fix pre_auth request funcs to handle quoted paths

Change-Id: I739e3f600cedab5c7174a5b1f0ff2ec6003fc453
This commit is contained in:
David Goetz
2012-05-07 13:46:41 -07:00
parent 5dcc9083a7
commit a539ac56f0
2 changed files with 30 additions and 9 deletions

View File

@@ -27,6 +27,7 @@ from eventlet import greenio, GreenPool, sleep, wsgi, listen
from paste.deploy import loadapp, appconfig from paste.deploy import loadapp, appconfig
from eventlet.green import socket, ssl from eventlet.green import socket, ssl
from webob import Request from webob import Request
from urllib import unquote
from swift.common.utils import get_logger, drop_privileges, \ from swift.common.utils import get_logger, drop_privileges, \
validate_configuration, capture_stdio, NullLogger validate_configuration, capture_stdio, NullLogger
@@ -264,7 +265,10 @@ def make_pre_authed_request(env, method=None, path=None, body=None,
:param method: HTTP method of new request; default is from :param method: HTTP method of new request; default is from
the original env. the original env.
:param path: HTTP path of new request; default is from the :param path: HTTP path of new request; default is from the
original env. original env. path should be compatible with what you
would send to Request.blank. path should be quoted and it
can include a query string. for example:
'/a%20space?unicode_str%E8%AA%9E=y%20es'
:param body: HTTP body of new request; empty by default. :param body: HTTP body of new request; empty by default.
:param headers: Extra HTTP headers of new request; None by :param headers: Extra HTTP headers of new request; None by
default. default.
@@ -276,17 +280,21 @@ def make_pre_authed_request(env, method=None, path=None, body=None,
have no HTTP_USER_AGENT. have no HTTP_USER_AGENT.
:returns: Fresh webob.Request object. :returns: Fresh webob.Request object.
""" """
newenv = make_pre_authed_env(env, method, path, agent) query_string = None
if path and '?' in path:
path, query_string = path.split('?', 1)
newenv = make_pre_authed_env(env, method, path=unquote(path), agent=agent,
query_string=query_string)
if not headers: if not headers:
headers = {} headers = {}
if body: if body:
return Request.blank(path, environ=newenv, body=body, return Request.blank(path, environ=newenv, body=body, headers=headers)
headers=headers)
else: else:
return Request.blank(path, environ=newenv, headers=headers) return Request.blank(path, environ=newenv, headers=headers)
def make_pre_authed_env(env, method=None, path=None, agent='Swift'): def make_pre_authed_env(env, method=None, path=None, agent='Swift',
query_string=None):
""" """
Returns a new fresh WSGI environment with escalated privileges to Returns a new fresh WSGI environment with escalated privileges to
do backend checks, listings, etc. that the remote user wouldn't do backend checks, listings, etc. that the remote user wouldn't
@@ -295,7 +303,14 @@ def make_pre_authed_env(env, method=None, path=None, agent='Swift'):
:param env: The WSGI environment to base the new environment on. :param env: The WSGI environment to base the new environment on.
:param method: The new REQUEST_METHOD or None to use the :param method: The new REQUEST_METHOD or None to use the
original. original.
:param path: The new PATH_INFO or None to use the original. :param path: The new path_info or none to use the original. path
should NOT be quoted. When building a url, a Webob
Request (in accordance with wsgi spec) will quote
env['PATH_INFO']. url += quote(environ['PATH_INFO'])
:param query_string: The new query_string or none to use the original.
When building a url, a Webob Request will append
the query string directly to the url.
url += '?' + env['QUERY_STRING']
:param agent: The HTTP user agent to use; default 'Swift'. You :param agent: The HTTP user agent to use; default 'Swift'. You
can put %(orig)s in the agent to have it replaced can put %(orig)s in the agent to have it replaced
with the original env's HTTP_USER_AGENT, such as with the original env's HTTP_USER_AGENT, such as
@@ -314,10 +329,9 @@ def make_pre_authed_env(env, method=None, path=None, agent='Swift'):
if method: if method:
newenv['REQUEST_METHOD'] = method newenv['REQUEST_METHOD'] = method
if path: if path:
if '?' in path:
path, query_string = path.split('?', 1)
newenv['QUERY_STRING'] = query_string
newenv['PATH_INFO'] = path newenv['PATH_INFO'] = path
if query_string:
newenv['QUERY_STRING'] = query_string
if agent: if agent:
newenv['HTTP_USER_AGENT'] = ( newenv['HTTP_USER_AGENT'] = (
agent % {'orig': env.get('HTTP_USER_AGENT', '')}).strip() agent % {'orig': env.get('HTTP_USER_AGENT', '')}).strip()

View File

@@ -26,6 +26,7 @@ from getpass import getuser
from shutil import rmtree from shutil import rmtree
from StringIO import StringIO from StringIO import StringIO
from collections import defaultdict from collections import defaultdict
from urllib import quote
from eventlet import sleep from eventlet import sleep
from webob import Request from webob import Request
@@ -188,5 +189,11 @@ class TestWSGI(unittest.TestCase):
'PUT', '/', headers={}) 'PUT', '/', headers={})
Request.blank = was_blank Request.blank = was_blank
def test_pre_auth_req_with_quoted_path(self):
r = wsgi.make_pre_authed_request(
{'HTTP_X_TRANS_ID': '1234'}, 'PUT', path=quote('/a space'),
body='tester', headers={})
self.assertEquals(r.path, quote('/a space'))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()