form post over XMLHttpRequest (cors) broken
Change-Id: Ia55e0d3974a96e11d49ab3cb26b6dcd7129b5cc8
This commit is contained in:
parent
7ccde73974
commit
56c902c8de
@ -49,11 +49,12 @@ different users' uploads, such as::
|
||||
Note the form method must be POST and the enctype must be set as
|
||||
"multipart/form-data".
|
||||
|
||||
The redirect attribute is the URL to redirect the browser to after
|
||||
the upload completes. The URL will have status and message query
|
||||
parameters added to it, indicating the HTTP status code for the
|
||||
upload (2xx is success) and a possible message for further
|
||||
information if there was an error (such as "max_file_size exceeded").
|
||||
The redirect attribute is the URL to redirect the browser to after the upload
|
||||
completes. This is an optional parameter. If you are uploading the form via an
|
||||
XMLHttpRequest the redirect should not be included. The URL will have status
|
||||
and message query parameters added to it, indicating the HTTP status code for
|
||||
the upload (2xx is success) and a possible message for further information if
|
||||
there was an error (such as "max_file_size exceeded").
|
||||
|
||||
The max_file_size attribute must be included and indicates the
|
||||
largest single file upload that can be done, in bytes.
|
||||
@ -73,7 +74,7 @@ sample code for computing the signature::
|
||||
from hashlib import sha1
|
||||
from time import time
|
||||
path = '/v1/account/container/object_prefix'
|
||||
redirect = 'https://myserver.com/some-page'
|
||||
redirect = 'https://srv.com/some-page' # set to '' if redirect not in form
|
||||
max_file_size = 104857600
|
||||
max_file_count = 10
|
||||
expires = int(time() + 600)
|
||||
@ -350,6 +351,7 @@ class FormPost(object):
|
||||
keys = self._get_keys(env)
|
||||
status = message = ''
|
||||
attributes = {}
|
||||
subheaders = []
|
||||
file_count = 0
|
||||
for fp in _iter_requests(env['wsgi.input'], boundary):
|
||||
hdrs = rfc822.Message(fp, 0)
|
||||
@ -368,8 +370,8 @@ class FormPost(object):
|
||||
if 'content-type' not in attributes and 'content-type' in hdrs:
|
||||
attributes['content-type'] = \
|
||||
hdrs['Content-Type'] or 'application/octet-stream'
|
||||
status, message = self._perform_subrequest(env, attributes, fp,
|
||||
keys)
|
||||
status, subheaders, message = \
|
||||
self._perform_subrequest(env, attributes, fp, keys)
|
||||
if status[:1] != '2':
|
||||
break
|
||||
else:
|
||||
@ -388,13 +390,17 @@ class FormPost(object):
|
||||
if not status:
|
||||
status = '400 Bad Request'
|
||||
message = 'no files to process'
|
||||
|
||||
headers = [(k, v) for k, v in subheaders
|
||||
if k.lower().startswith('access-control')]
|
||||
|
||||
redirect = attributes.get('redirect')
|
||||
if not redirect:
|
||||
body = status
|
||||
if message:
|
||||
body = status + '\r\nFormPost: ' + message.title()
|
||||
headers = [('Content-Type', 'text/plain'),
|
||||
('Content-Length', len(body))]
|
||||
headers.extend([('Content-Type', 'text/plain'),
|
||||
('Content-Length', len(body))])
|
||||
return status, headers, body
|
||||
status = status.split(' ', 1)[0]
|
||||
if '?' in redirect:
|
||||
@ -404,7 +410,8 @@ class FormPost(object):
|
||||
redirect += 'status=%s&message=%s' % (quote(status), quote(message))
|
||||
body = '<html><body><p><a href="%s">' \
|
||||
'Click to continue...</a></p></body></html>' % redirect
|
||||
headers = [('Location', redirect), ('Content-Length', str(len(body)))]
|
||||
headers.extend(
|
||||
[('Location', redirect), ('Content-Length', str(len(body)))])
|
||||
return '303 See Other', headers, body
|
||||
|
||||
def _perform_subrequest(self, orig_env, attributes, fp, keys):
|
||||
@ -416,7 +423,7 @@ class FormPost(object):
|
||||
:param attributes: dict of the attributes of the form so far.
|
||||
:param fp: The file-like object containing the request body.
|
||||
:param keys: The account keys to validate the signature with.
|
||||
:returns: (status_line, message)
|
||||
:returns: (status_line, headers_list, message)
|
||||
"""
|
||||
if not keys:
|
||||
raise FormUnauthorized('invalid signature')
|
||||
@ -461,16 +468,18 @@ class FormPost(object):
|
||||
raise FormUnauthorized('invalid signature')
|
||||
|
||||
substatus = [None]
|
||||
subheaders = [None]
|
||||
|
||||
def _start_response(status, headers, exc_info=None):
|
||||
substatus[0] = status
|
||||
subheaders[0] = headers
|
||||
|
||||
i = iter(self.app(subenv, _start_response))
|
||||
try:
|
||||
i.next()
|
||||
except StopIteration:
|
||||
pass
|
||||
return substatus[0], ''
|
||||
return substatus[0], subheaders[0], ''
|
||||
|
||||
def _get_keys(self, env):
|
||||
"""
|
||||
|
@ -485,7 +485,7 @@ def make_pre_authed_env(env, method=None, path=None, agent='Swift',
|
||||
newenv = {}
|
||||
for name in ('eventlet.posthooks', 'HTTP_USER_AGENT', 'HTTP_HOST',
|
||||
'PATH_INFO', 'QUERY_STRING', 'REMOTE_USER', 'REQUEST_METHOD',
|
||||
'SCRIPT_NAME', 'SERVER_NAME', 'SERVER_PORT',
|
||||
'SCRIPT_NAME', 'SERVER_NAME', 'SERVER_PORT', 'HTTP_ORIGIN',
|
||||
'SERVER_PROTOCOL', 'swift.cache', 'swift.source',
|
||||
'swift.trans_id'):
|
||||
if name in env:
|
||||
|
@ -1223,6 +1223,33 @@ class TestFormPost(unittest.TestCase):
|
||||
self.assertEquals(self.app.requests[0].headers['User-Agent'],
|
||||
'FormPost')
|
||||
|
||||
def test_formpost_with_origin(self):
|
||||
key = 'abc'
|
||||
sig, env, body = self._make_sig_env_body(
|
||||
'/v1/AUTH_test/container', 'http://redirect', 1024, 10,
|
||||
int(time() + 86400), key, user_agent=False)
|
||||
env['wsgi.input'] = StringIO('\r\n'.join(body))
|
||||
env['swift.account/AUTH_test'] = self._fake_cache_env(
|
||||
'AUTH_test', [key])
|
||||
env['HTTP_ORIGIN'] = 'http://localhost:5000'
|
||||
self.app = FakeApp(iter([('201 Created', {}, ''),
|
||||
('201 Created',
|
||||
{'Access-Control-Allow-Origin':
|
||||
'http://localhost:5000'}, '')]))
|
||||
self.auth = tempauth.filter_factory({})(self.app)
|
||||
self.formpost = formpost.filter_factory({})(self.auth)
|
||||
|
||||
headers = {}
|
||||
|
||||
def start_response(s, h, e=None):
|
||||
for k, v in h:
|
||||
headers[k] = v
|
||||
pass
|
||||
|
||||
body = ''.join(self.formpost(env, start_response))
|
||||
self.assertEquals(headers['Access-Control-Allow-Origin'],
|
||||
'http://localhost:5000')
|
||||
|
||||
def test_formpost_with_multiple_keys(self):
|
||||
key = 'ernie'
|
||||
sig, env, body = self._make_sig_env_body(
|
||||
|
Loading…
Reference in New Issue
Block a user