summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-04-20 15:07:19 -0400
committerChris McDonough <chrism@plope.com>2011-04-20 15:07:19 -0400
commitbcb3312f9faf032bd197a3650d82bad1bf633f4c (patch)
tree2aefc898ffe283385a620d2a84fef555623cf27f
parentbea9f5b1b99fc27ee2a79512d098d688aea9d113 (diff)
downloadpyramid-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.py42
-rw-r--r--pyramid/static.py46
-rw-r--r--pyramid/wsgi.py29
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)
+