summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-04-21 20:48:46 -0400
committerChris McDonough <chrism@plope.com>2011-04-21 20:48:46 -0400
commitb64268655a5cb17d31ad2c95b3d6a962d881f77a (patch)
treea3a3d8d449dab74fca53e79d0e1bcec4bc802d8f
parent76071718a63dc86be4bb53713fadbdc618c719ad (diff)
downloadpyramid-b64268655a5cb17d31ad2c95b3d6a962d881f77a.tar.gz
pyramid-b64268655a5cb17d31ad2c95b3d6a962d881f77a.tar.bz2
pyramid-b64268655a5cb17d31ad2c95b3d6a962d881f77a.zip
share call_app_with_subpath_as_path_info between static view and wsgiapp2
-rw-r--r--pyramid/request.py69
-rw-r--r--pyramid/static.py7
-rw-r--r--pyramid/tests/test_integration.py4
-rw-r--r--pyramid/tests/test_static.py5
-rw-r--r--pyramid/tests/test_wsgi.py43
-rw-r--r--pyramid/wsgi.py5
6 files changed, 61 insertions, 72 deletions
diff --git a/pyramid/request.py b/pyramid/request.py
index 1aceccdba..e53a70023 100644
--- a/pyramid/request.py
+++ b/pyramid/request.py
@@ -394,10 +394,11 @@ def add_global_response_headers(request, headerlist):
response.headerlist.append((k, v))
request.add_response_callback(add_headers)
-def subpath_as_path_info(request, default_script_name='',default_path_info='/'):
- # Copy the request. Use the request's subpath (if it exists) as the new
- # request's PATH_INFO. Set the request copy's SCRIPT_NAME to the prefix
- # before the subpath.
+def call_app_subpath_as_path_info(request, app):
+ # Copy the request. Use the source request's subpath (if it exists) as
+ # the new request's PATH_INFO. Set the request copy's SCRIPT_NAME to the
+ # prefix before the subpath. Call the application with the new request
+ # and return a response.
#
# Postconditions:
# - SCRIPT_NAME and PATH_INFO are empty or start with /
@@ -408,32 +409,40 @@ def subpath_as_path_info(request, default_script_name='',default_path_info='/'):
script_name = request.environ.get('SCRIPT_NAME', '')
path_info = request.environ.get('PATH_INFO', '/')
- new_script_name = default_script_name
- new_path_info = default_path_info
+ new_script_name = ''
subpath = list(getattr(request, 'subpath', ()))
- if subpath:
- # compute new_path_info
- new_path_info = '/' + '/'.join([quote_path_segment(x) for x in subpath])
- if path_info.endswith('/'):
- # readd trailing slash stripped by subpath (traversal)
- # conversion
- new_path_info += '/'
-
- # compute new_script_name
- tmp = []
- workback = (script_name + path_info).split('/')
- while workback:
- el = workback.pop()
- if el:
- tmp.insert(0, el.decode('utf-8'))
- if tmp == subpath:
- new_script_name = '/'.join(workback)
- break
-
- request = request.copy()
- request.environ['SCRIPT_NAME'] = new_script_name
- request.environ['PATH_INFO'] = new_path_info
-
- return request
+ # compute new_path_info
+ new_path_info = '/' + '/'.join([quote_path_segment(x) for x in subpath])
+
+ if new_path_info != '/':
+ if path_info != '/':
+ if path_info.endswith('/'):
+ # readd trailing slash stripped by subpath (traversal)
+ # conversion
+ new_path_info += '/'
+
+ # compute new_script_name
+ tmp = []
+ workback = (script_name + path_info).split('/')
+
+ # strip trailing slash from workback to avoid appending undue slash
+ # to script_name
+ if workback and (workback[-1] == ''):
+ workback = workback[:-1]
+
+ while workback:
+ if tmp == subpath:
+ break
+ el = workback.pop()
+ if el:
+ tmp.insert(0, el.decode('utf-8'))
+
+ new_script_name = '/'.join(workback)
+
+ request_copy = request.copy()
+ request_copy.environ['SCRIPT_NAME'] = new_script_name
+ request_copy.environ['PATH_INFO'] = new_path_info
+
+ return request_copy.get_response(app)
diff --git a/pyramid/static.py b/pyramid/static.py
index c80952129..22e6e9256 100644
--- a/pyramid/static.py
+++ b/pyramid/static.py
@@ -13,7 +13,7 @@ from zope.interface import implements
from pyramid.asset import resolve_asset_spec
from pyramid.interfaces import IStaticURLInfo
from pyramid.path import caller_package
-from pyramid.request import subpath_as_path_info
+from pyramid.request import call_app_subpath_as_path_info
from pyramid.url import route_url
class PackageURLParser(StaticURLParser):
@@ -209,7 +209,4 @@ class static_view(object):
self.app = app
def __call__(self, context, request):
- script_name = request.environ.get('SCRIPT_NAME', '')
- path_info = request.environ.get('PATH_INFO', '/')
- request_copy = subpath_as_path_info(request, script_name, path_info)
- return request_copy.get_response(self.app)
+ return call_app_subpath_as_path_info(request, self.app)
diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py
index 1f9484279..e3a1a8003 100644
--- a/pyramid/tests/test_integration.py
+++ b/pyramid/tests/test_integration.py
@@ -104,7 +104,7 @@ class TestStaticApp(unittest.TestCase):
from webob import Request
context = DummyContext()
from StringIO import StringIO
- request = Request({'PATH_INFO':'',
+ request = Request({'PATH_INFO':'/static',
'SCRIPT_NAME':'/script_name',
'SERVER_NAME':'localhost',
'SERVER_PORT':'80',
@@ -112,7 +112,7 @@ class TestStaticApp(unittest.TestCase):
'wsgi.version':(1,0),
'wsgi.url_scheme':'http',
'wsgi.input':StringIO()})
- request.subpath = ['static']
+ request.subpath = ('static',)
result = staticapp(context, request)
self.assertEqual(result.status, '301 Moved Permanently')
self.assertEqual(result.location,
diff --git a/pyramid/tests/test_static.py b/pyramid/tests/test_static.py
index b9d464bf1..0095b29d3 100644
--- a/pyramid/tests/test_static.py
+++ b/pyramid/tests/test_static.py
@@ -268,8 +268,9 @@ class Test_static_view(unittest.TestCase):
SCRIPT_NAME='/script_name')
view(context, request)
self.assertEqual(request.copied, True)
- self.assertEqual(request.environ['PATH_INFO'], '/path_info')
- self.assertEqual(request.environ['SCRIPT_NAME'], '/script_name')
+ self.assertEqual(request.environ['PATH_INFO'], '/')
+ self.assertEqual(request.environ['SCRIPT_NAME'],
+ '/script_name/path_info')
def test_with_subpath_path_info_ends_with_slash(self):
view = self._makeOne('fixtures', package_name='another')
diff --git a/pyramid/tests/test_wsgi.py b/pyramid/tests/test_wsgi.py
index 067c86127..06bcf1cb2 100644
--- a/pyramid/tests/test_wsgi.py
+++ b/pyramid/tests/test_wsgi.py
@@ -20,11 +20,9 @@ class WSGIApp2Tests(unittest.TestCase):
def test_decorator_with_subpath_and_view_name(self):
context = DummyContext()
request = DummyRequest()
- request.traversed = ['a', 'b']
- request.virtual_root_path = ['a']
- request.subpath = ['subpath']
- request.view_name = 'view_name'
- request.environ = {'SCRIPT_NAME':'/foo'}
+ request.subpath = ('subpath',)
+ request.environ = {'SCRIPT_NAME':'/foo',
+ 'PATH_INFO':'/b/view_name/subpath'}
decorator = self._callFUT(dummyapp)
response = decorator(context, request)
self.assertEqual(response, dummyapp)
@@ -34,11 +32,8 @@ class WSGIApp2Tests(unittest.TestCase):
def test_decorator_with_subpath_no_view_name(self):
context = DummyContext()
request = DummyRequest()
- request.traversed = ['a', 'b']
- request.virtual_root_path = ['a']
- request.subpath = ['subpath']
- request.view_name = ''
- request.environ = {'SCRIPT_NAME':'/foo'}
+ request.subpath = ('subpath',)
+ request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/b/subpath'}
decorator = self._callFUT(dummyapp)
response = decorator(context, request)
self.assertEqual(response, dummyapp)
@@ -48,11 +43,8 @@ class WSGIApp2Tests(unittest.TestCase):
def test_decorator_no_subpath_with_view_name(self):
context = DummyContext()
request = DummyRequest()
- request.traversed = ['a', 'b']
- request.virtual_root_path = ['a']
- request.subpath = []
- request.view_name = 'view_name'
- request.environ = {'SCRIPT_NAME':'/foo'}
+ request.subpath = ()
+ request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/b/view_name'}
decorator = self._callFUT(dummyapp)
response = decorator(context, request)
self.assertEqual(response, dummyapp)
@@ -62,11 +54,8 @@ class WSGIApp2Tests(unittest.TestCase):
def test_decorator_traversed_empty_with_view_name(self):
context = DummyContext()
request = DummyRequest()
- request.traversed = []
- request.virtual_root_path = []
- request.subpath = []
- request.view_name = 'view_name'
- request.environ = {'SCRIPT_NAME':'/foo'}
+ request.subpath = ()
+ request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/view_name'}
decorator = self._callFUT(dummyapp)
response = decorator(context, request)
self.assertEqual(response, dummyapp)
@@ -76,11 +65,8 @@ class WSGIApp2Tests(unittest.TestCase):
def test_decorator_traversed_empty_no_view_name(self):
context = DummyContext()
request = DummyRequest()
- request.traversed = []
- request.virtual_root_path = []
- request.subpath = []
- request.view_name = ''
- request.environ = {'SCRIPT_NAME':'/foo'}
+ request.subpath = ()
+ request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/'}
decorator = self._callFUT(dummyapp)
response = decorator(context, request)
self.assertEqual(response, dummyapp)
@@ -90,11 +76,8 @@ class WSGIApp2Tests(unittest.TestCase):
def test_decorator_traversed_empty_no_view_name_no_script_name(self):
context = DummyContext()
request = DummyRequest()
- request.traversed = []
- request.virtual_root_path = []
- request.subpath = []
- request.view_name = ''
- request.environ = {'SCRIPT_NAME':''}
+ request.subpath = ()
+ request.environ = {'SCRIPT_NAME':'', 'PATH_INFO':'/'}
decorator = self._callFUT(dummyapp)
response = decorator(context, request)
self.assertEqual(response, dummyapp)
diff --git a/pyramid/wsgi.py b/pyramid/wsgi.py
index ef8863cfa..71045bb54 100644
--- a/pyramid/wsgi.py
+++ b/pyramid/wsgi.py
@@ -1,5 +1,5 @@
from pyramid.compat import wraps
-from pyramid.request import subpath_as_path_info
+from pyramid.request import call_app_subpath_as_path_info
def wsgiapp(wrapped):
""" Decorator to turn a WSGI application into a :app:`Pyramid`
@@ -62,7 +62,6 @@ def wsgiapp2(wrapped):
up before the application is invoked. """
def decorator(context, request):
- request_copy = subpath_as_path_info(request)
- return request_copy.get_response(wrapped)
+ return call_app_subpath_as_path_info(request, wrapped)
return wraps(wrapped)(decorator)