diff options
| author | Chris McDonough <chrism@plope.com> | 2011-04-20 15:07:19 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-04-20 15:07:19 -0400 |
| commit | bcb3312f9faf032bd197a3650d82bad1bf633f4c (patch) | |
| tree | 2aefc898ffe283385a620d2a84fef555623cf27f | |
| parent | bea9f5b1b99fc27ee2a79512d098d688aea9d113 (diff) | |
| download | pyramid-bcb3312f9faf032bd197a3650d82bad1bf633f4c.tar.gz pyramid-bcb3312f9faf032bd197a3650d82bad1bf633f4c.tar.bz2 pyramid-bcb3312f9faf032bd197a3650d82bad1bf633f4c.zip | |
fix scriptname and path_info computation in wsgiapp2 decorator; share code between static and wsgiapp2 decorator
| -rw-r--r-- | pyramid/request.py | 42 | ||||
| -rw-r--r-- | pyramid/static.py | 46 | ||||
| -rw-r--r-- | pyramid/wsgi.py | 29 |
3 files changed, 55 insertions, 62 deletions
diff --git a/pyramid/request.py b/pyramid/request.py index 9d2b9344b..050828d01 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -393,3 +393,45 @@ def add_global_response_headers(request, headerlist): response.headerlist.append((k, v)) request.add_response_callback(add_headers) +def copy_request_with_subpath_as_path_info(request, default_script_name='', + default_path_info='/'): + # Make a copy of the request and use the request's subpath (if it exists) + # as the request copy's PATH_INFO. Set the request copy's SCRIPT_NAME to + # the prefix before the subpath. + # + # Postconditions: + # - SCRIPT_NAME and PATH_INFO are empty or start with / + # - At least one of SCRIPT_NAME or PATH_INFO are set. + # - SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should + # be '/'). + + script_name = request.environ.get('SCRIPT_NAME', '') + path_info = request.environ.get('PATH_INFO', '/') + + subpath = getattr(request, 'subpath', ()) + + if subpath: + # compute new_path_info + default_path_info = '/' + '/'.join(subpath) + if path_info.endswith('/'): + # readd trailing slash stripped by subpath (traversal) + # conversion + default_path_info += '/' + + # compute new_script_name + tmp = [] + workback = (script_name + path_info).split('/') + while workback: + el = workback.pop() + if el: + tmp.insert(0, el) + if tmp == subpath: + default_script_name = '/'.join(workback) + break + + request_copy = request.copy() + + request_copy.environ['SCRIPT_NAME'] = default_script_name + request_copy.environ['PATH_INFO'] = default_path_info + + return request_copy diff --git a/pyramid/static.py b/pyramid/static.py index 223652768..903316deb 100644 --- a/pyramid/static.py +++ b/pyramid/static.py @@ -13,6 +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 copy_request_with_subpath_as_path_info from pyramid.url import route_url class PackageURLParser(StaticURLParser): @@ -208,44 +209,11 @@ class static_view(object): self.app = app def __call__(self, context, request): - # Point PATH_INFO to the static file/dir path; point SCRIPT_NAME - # to the prefix before it. - - # Postconditions: - # - SCRIPT_NAME and PATH_INFO are empty or start with / - # - At least one of SCRIPT_NAME or PATH_INFO are set. - # - SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should - # be '/'). - - request_copy = request.copy() - script_name = request_copy.environ.get('SCRIPT_NAME', '') - path_info = request_copy.environ.get('PATH_INFO', '/') - - new_script_name = script_name - new_path_info = path_info - - subpath = list(request.subpath) - - if subpath: - # compute new_path_info - new_path_info = '/' + '/'.join(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) - if tmp == subpath: - new_script_name = '/'.join(workback) - break - - request_copy.environ['SCRIPT_NAME'] = new_script_name - request_copy.environ['PATH_INFO'] = new_path_info + script_name = request.environ.get('SCRIPT_NAME', '') + path_info = request.environ.get('PATH_INFO', '/') + + request_copy = copy_request_with_subpath_as_path_info(request, + script_name, + path_info) return request_copy.get_response(self.app) diff --git a/pyramid/wsgi.py b/pyramid/wsgi.py index e988a000e..959f84bbc 100644 --- a/pyramid/wsgi.py +++ b/pyramid/wsgi.py @@ -1,5 +1,5 @@ from pyramid.compat import wraps -from pyramid.traversal import quote_path_segment +from pyramid.request import copy_request_with_subpath_as_path_info def wsgiapp(wrapped): """ Decorator to turn a WSGI application into a :app:`Pyramid` @@ -62,25 +62,8 @@ def wsgiapp2(wrapped): up before the application is invoked. """ def decorator(context, request): - traversed = request.traversed - vroot_path = request.virtual_root_path - if not vroot_path: - vroot_path = () - view_name = request.view_name - subpath = request.subpath - if not subpath: - subpath = () - script_tuple = traversed[len(vroot_path):] - script_list = [ quote_path_segment(name) for name in script_tuple ] - if view_name: - script_list.append(quote_path_segment(view_name)) - script_name = '/' + '/'.join(script_list) - path_list = [ quote_path_segment(name) for name in subpath ] - path_info = '/' + '/'.join(path_list) - request.environ['PATH_INFO'] = path_info - script_name = request.environ['SCRIPT_NAME'] + script_name - if script_name.endswith('/'): - script_name = script_name[:-1] - request.environ['SCRIPT_NAME'] = script_name - return request.get_response(wrapped) - return wraps(wrapped)(decorator) # grokkability + request_copy = copy_request_with_subpath_as_path_info(request) + return request_copy.get_response(wrapped) + + return wraps(wrapped)(decorator) + |
