You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by je...@apache.org on 2015/12/03 15:27:40 UTC

allura git commit: @with[out]_trailing_slash now handles URLs with query strings too

Repository: allura
Updated Branches:
  refs/heads/master f4a9f4223 -> 1c38b6ffe


@with[out]_trailing_slash now handles URLs with query strings too


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/1c38b6ff
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/1c38b6ff
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/1c38b6ff

Branch: refs/heads/master
Commit: 1c38b6ffe55f4dc3533af6041c36f5794855373c
Parents: f4a9f42
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Dec 2 16:29:39 2015 -0500
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Dec 2 16:30:16 2015 -0500

----------------------------------------------------------------------
 Allura/allura/lib/patches.py        | 20 ++++----
 Allura/allura/tests/test_patches.py | 78 ++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/1c38b6ff/Allura/allura/lib/patches.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/patches.py b/Allura/allura/lib/patches.py
index 2c363ea..67ba105 100644
--- a/Allura/allura/lib/patches.py
+++ b/Allura/allura/lib/patches.py
@@ -70,21 +70,25 @@ def apply():
     @h.monkeypatch(tg, tg.decorators)
     @decorator
     def without_trailing_slash(func, *args, **kwargs):
-        '''Monkey-patched to use 301 redirects for SEO'''
+        '''Monkey-patched to use 301 redirects for SEO, and handle query strings'''
         response_type = getattr(request, 'response_type', None)
-        if (request.method == 'GET' and request.path.endswith('/')
-                and not response_type and len(request.params) == 0):
-            raise webob.exc.HTTPMovedPermanently(location=request.url[:-1])
+        if (request.method == 'GET' and request.path.endswith('/') and not response_type):
+            location = request.path_url[:-1]
+            if request.query_string:
+                location += '?' + request.query_string
+            raise webob.exc.HTTPMovedPermanently(location=location)
         return func(*args, **kwargs)
 
     @h.monkeypatch(tg, tg.decorators)
     @decorator
     def with_trailing_slash(func, *args, **kwargs):
-        '''Monkey-patched to use 301 redirects for SEO'''
+        '''Monkey-patched to use 301 redirects for SEO, and handle query strings'''
         response_type = getattr(request, 'response_type', None)
-        if (request.method == 'GET' and not(request.path.endswith('/'))
-                and not response_type and len(request.params) == 0):
-            raise webob.exc.HTTPMovedPermanently(location=request.url + '/')
+        if (request.method == 'GET' and not request.path.endswith('/') and not response_type):
+            location = request.path_url + '/'
+            if request.query_string:
+                location += '?' + request.query_string
+            raise webob.exc.HTTPMovedPermanently(location=location)
         return func(*args, **kwargs)
 
     # http://blog.watchfire.com/wfblog/2011/10/json-based-xss-exploitation.html

http://git-wip-us.apache.org/repos/asf/allura/blob/1c38b6ff/Allura/allura/tests/test_patches.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_patches.py b/Allura/allura/tests/test_patches.py
new file mode 100644
index 0000000..a1fc9bc
--- /dev/null
+++ b/Allura/allura/tests/test_patches.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+
+#       Licensed to the Apache Software Foundation (ASF) under one
+#       or more contributor license agreements.  See the NOTICE file
+#       distributed with this work for additional information
+#       regarding copyright ownership.  The ASF licenses this file
+#       to you under the Apache License, Version 2.0 (the
+#       "License"); you may not use this file except in compliance
+#       with the License.  You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#       Unless required by applicable law or agreed to in writing,
+#       software distributed under the License is distributed on an
+#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#       KIND, either express or implied.  See the License for the
+#       specific language governing permissions and limitations
+#       under the License.
+
+import webob
+from mock import patch
+from nose.tools import (
+    assert_equal,
+    assert_raises,
+)
+import tg
+
+from allura.lib import patches
+
+
+def empty_func():
+    pass
+
+
+@patch.object(patches, 'request', webob.Request.blank('/foo/bar'))
+def test_with_trailing_slash():
+    patches.apply()
+    with assert_raises(webob.exc.HTTPMovedPermanently) as raised:
+        tg.decorators.with_trailing_slash(empty_func)()
+    assert_equal(raised.exception.location, 'http://localhost/foo/bar/')
+
+
+@patch.object(patches, 'request', webob.Request.blank('/foo/bar/?a=b'))
+def test_with_trailing_slash_ok():
+    patches.apply()
+    # no exception raised
+    tg.decorators.with_trailing_slash(empty_func)()
+
+
+@patch.object(patches, 'request', webob.Request.blank('/foo/bar?foo=bar&baz=bam'))
+def test_with_trailing_slash_qs():
+    patches.apply()
+    with assert_raises(webob.exc.HTTPMovedPermanently) as raised:
+        tg.decorators.with_trailing_slash(empty_func)()
+    assert_equal(raised.exception.location, 'http://localhost/foo/bar/?foo=bar&baz=bam')
+
+
+@patch.object(patches, 'request', webob.Request.blank('/foo/bar/'))
+def test_without_trailing_slash():
+    patches.apply()
+    with assert_raises(webob.exc.HTTPMovedPermanently) as raised:
+        tg.decorators.without_trailing_slash(empty_func)()
+    assert_equal(raised.exception.location, 'http://localhost/foo/bar')
+
+
+@patch.object(patches, 'request', webob.Request.blank('/foo/bar?a=b'))
+def test_without_trailing_slash_ok():
+    patches.apply()
+    # no exception raised
+    tg.decorators.without_trailing_slash(empty_func)()
+
+
+@patch.object(patches, 'request', webob.Request.blank('/foo/bar/?foo=bar&baz=bam'))
+def test_without_trailing_slash_qs():
+    patches.apply()
+    with assert_raises(webob.exc.HTTPMovedPermanently) as raised:
+        tg.decorators.without_trailing_slash(empty_func)()
+    assert_equal(raised.exception.location, 'http://localhost/foo/bar?foo=bar&baz=bam')