def test_wrapper_support(): """Securecookie wrapper integration""" req = Request.from_values() resp = Response() c = SecureCookie.load_cookie(req, secret_key='foo') assert c.new c['foo'] = 42 assert c.secret_key == 'foo' c.save_cookie(resp) req = Request.from_values(headers={ 'Cookie': 'session="%s"' % parse_cookie(resp.headers['set-cookie'])['session'] }) c2 = SecureCookie.load_cookie(req, secret_key='foo') assert not c2.new assert c2 == c
def test_large_file(): """Test a largish file.""" data = "x" * (1024 * 600) req = Request.from_values(data={"foo": (StringIO(data), "test.txt")}, method="POST") # make sure we have a real file here, because we expect to be # on the disk. > 1024 * 500 assert isinstance(req.files["foo"].stream, file)
def test_nonstandard_line_endings(): """Test nonstandard line endings of multipart form data""" for nl in "\n", "\r", "\r\n": data = nl.join( ( "--foo", "Content-Disposition: form-data; name=foo", "", "this is just bar", "--foo", "Content-Disposition: form-data; name=bar", "", "blafasel", "--foo--", ) ) req = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="multipart/form-data; " "boundary=foo", method="POST", ) print req.form assert req.form["foo"] == "this is just bar" assert req.form["bar"] == "blafasel"
def _send_with_auth(values, secret_key, url): """Send dictionary of JSON serializable `values` as a POST body to `url` along with `auth_token` that's generated from `secret_key` and `values` scheduler.auth.create_token expects a JSON serializable payload, so we send a dictionary. On the receiving end of the POST request, the Flask view will have access to a werkzeug.datastructures.ImmutableMultiDict. The easiest and most surefire way to ensure that the payload sent to create_token will be consistent on both ends is to generate an ImmutableMultiDict using the werkzeug.Request. """ data = urllib.urlencode(values) # Simulate a Flask request because that is what will be unpacked when the # request is received on the other side request = Request.from_values( content_length=len(data), input_stream=StringIO(data), content_type='application/x-www-form-urlencoded', method='POST') # Add the auth_token, re-encode, and send values['auth_token'] = create_token(secret_key, dict(request.form)) data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) return json.loads(response.read())
def test_large_file(): """Test a largish file.""" data = 'x' * (1024 * 600) req = Request.from_values(data={'foo': (StringIO(data), 'test.txt')}, method='POST') # make sure we have a real file here, because we expect to be # on the disk. > 1024 * 500 assert isinstance(req.files['foo'].stream, file)
def test_multi_image_input_request(img_file): adapter = MultiImageInput(("imageX", "imageY")) multipart_data, headers = generate_multipart_body(img_file) request = Request.from_values( data=multipart_data, content_type=headers['Content-Type'], content_length=headers['Content-Length'], ) response = adapter.handle_request(request, predict) assert response.status_code == 200 assert response.data == b'[[10, 10, 3], [10, 10, 3]]'
def test_multipart_file_no_content_type(): """Chrome does not always provide a content type.""" data = ( '--foo\r\n' 'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n\r\n' 'file contents\r\n--foo--') data = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') assert data.files['test'].filename == 'test.txt' assert data.files['test'].read() == 'file contents'
def test_anno_image_input_batch_request_skip_bad(img_file, json_file): adapter = AnnotatedImageInput(is_batch_input=True) multipart_data, headers = generate_multipart_body(img_file, json_file) empty_request = SimpleRequest(headers=headers, data=None) request = SimpleRequest.from_flask_request( Request.from_values( data=multipart_data, content_type=headers['Content-Type'], content_length=headers['Content-Length'], )) image = ("image.jpg", open(img_file, "rb").read()) json = ("annotations.jso", open(json_file, "rb").read()) files = {"image.invalid": image, "annotations.invalid": json} bad_data, content_type = encode_multipart_formdata(files) bad_request = SimpleRequest.from_flask_request( Request.from_values( data=bad_data, content_type=content_type, content_length=len(bad_data), )) responses = adapter.handle_batch_request( [empty_request, request, bad_request], predict_image_and_json) assert len(responses) == 3 assert responses[0] is None assert responses[1].status == 200 and responses[ 1].data == '[[10, 10, 3], "kaith"]' assert responses[2] is None bad_responses = adapter.handle_batch_request([empty_request], predict_image_and_json) assert len(bad_responses) == 1 assert bad_responses[0] is None
def test_extra_newline_multipart(): """Test for multipart uploads with extra newlines""" # this test looks innocent but it was actually timeing out in # the Werkzeug 0.5 release version (#394) data = "\r\n\r\n--foo\r\n" 'Content-Disposition: form-data; name="foo"\r\n\r\n' "a string\r\n" "--foo--" data = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="multipart/form-data; boundary=foo", method="POST", ) assert not data.files assert data.form["foo"] == "a string"
def test_multipart_file_no_content_type(): """Chrome does not always provide a content type.""" data = ( '--foo\r\n' 'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n\r\n' 'file contents\r\n--foo--' ) data = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') assert data.files['test'].filename == 'test.txt' assert data.files['test'].read() == 'file contents'
def test_extra_newline_multipart(): """Test for multipart uploads with extra newlines""" # this test looks innocent but it was actually timeing out in # the Werkzeug 0.5 release version (#394) data = ('\r\n\r\n--foo\r\n' 'Content-Disposition: form-data; name="foo"\r\n\r\n' 'a string\r\n' '--foo--') data = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') assert not data.files assert data.form['foo'] == 'a string'
def test_multipart_file_no_content_type(): """Chrome does not always provide a content type.""" data = ( "--foo\r\n" 'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n\r\n' "file contents\r\n--foo--" ) data = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="multipart/form-data; boundary=foo", method="POST", ) assert data.files["test"].filename == "test.txt" assert data.files["test"].read() == "file contents"
def test_multi_image_batch_input(img_file): adapter = MultiImageInput(("imageX", "imageY"), is_batch_input=True) multipart_data, headers = generate_multipart_body(img_file) request = SimpleRequest.from_flask_request( Request.from_values( data=multipart_data, content_type=headers['Content-Type'], content_length=headers['Content-Length'], )) responses = adapter.handle_batch_request([request] * 5, predict) for response in responses: assert response.status == 200 assert response.data == '[[10, 10, 3], [10, 10, 3]]'
def test_bad_multi_image_batch_input(img_file): adapter = MultiImageInput(("imageX", "imageY"), is_batch_input=True) multipart_data, headers = generate_multipart_body(img_file) request = SimpleRequest.from_flask_request( Request.from_values( data=multipart_data, content_type=headers['Content-Type'], content_length=headers['Content-Length'], )) responses = adapter.handle_batch_request( [request] * 5 + [ SimpleRequest.from_flask_request( Request.from_values( data=multipart_data, content_type='application/octet-stream', content_length=headers['Content-Length'], )) ], predict, ) print(responses[-1]) assert isinstance(responses[-1], SimpleRequest)
def test_nonstandard_line_endings(): """Test nonstandard line endings of multipart form data""" for nl in '\n', '\r', '\r\n': data = nl.join(('--foo', 'Content-Disposition: form-data; name=foo', '', 'this is just bar', '--foo', 'Content-Disposition: form-data; name=bar', '', 'blafasel', '--foo--')) req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; ' 'boundary=foo', method='POST') print req.form assert req.form['foo'] == 'this is just bar' assert req.form['bar'] == 'blafasel'
def test_end_of_file_multipart(): """Test for multipart files ending unexpectedly""" # This test looks innocent but it was actually timeing out in # the Werkzeug 0.5 release version (#394) data = ( '--foo\r\n' 'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n' 'Content-Type: text/plain\r\n\r\n' 'file contents and no end') data = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') assert not data.files assert not data.form
def test_end_of_file_multipart(): """Test for multipart files ending unexpectedly""" # This test looks innocent but it was actually timeing out in # the Werkzeug 0.5 release version (#394) data = ( '--foo\r\n' 'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n' 'Content-Type: text/plain\r\n\r\n' 'file contents and no end' ) data = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') assert not data.files assert not data.form
def test_multipart_headers(): """Test access to multipart headers""" data = ('--foo\r\n' 'Content-Disposition: form-data; name="foo"; filename="foo.txt"\r\n' 'X-Custom-Header: blah\r\n' 'Content-Type: text/plain; charset=utf-8\r\n\r\n' 'file contents, just the contents\r\n' '--foo--') req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') foo = req.files['foo'] assert foo.content_type == 'text/plain' assert foo.headers['content-type'] == 'text/plain; charset=utf-8' assert foo.headers['x-custom-header'] == 'blah'
def test_anno_image_input_batch_request(img_file, json_file): adapter = AnnotatedImageInput(is_batch_input=True) multipart_data, headers = generate_multipart_body(img_file, json_file) request = SimpleRequest.from_flask_request( Request.from_values( data=multipart_data, content_type=headers['Content-Type'], content_length=headers['Content-Length'], )) responses = adapter.handle_batch_request([request] * 5, predict_image_and_json) for response in responses: assert response.status == 200 assert response.data == '[[10, 10, 3], "kaith"]'
def test_multipart_headers(): """Test access to multipart headers""" data = ( '--foo\r\n' 'Content-Disposition: form-data; name="foo"; filename="foo.txt"\r\n' 'X-Custom-Header: blah\r\n' 'Content-Type: text/plain; charset=utf-8\r\n\r\n' 'file contents, just the contents\r\n' '--foo--') req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') foo = req.files['foo'] assert foo.content_type == 'text/plain' assert foo.headers['content-type'] == 'text/plain; charset=utf-8' assert foo.headers['x-custom-header'] == 'blah'
def test_multipart_headers(): """Test access to multipart headers""" data = ( "--foo\r\n" 'Content-Disposition: form-data; name="foo"; filename="foo.txt"\r\n' "X-Custom-Header: blah\r\n" "Content-Type: text/plain; charset=utf-8\r\n\r\n" "file contents, just the contents\r\n" "--foo--" ) req = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="multipart/form-data; boundary=foo", method="POST", ) foo = req.files["foo"] assert foo.content_type == "text/plain" assert foo.headers["content-type"] == "text/plain; charset=utf-8" assert foo.headers["x-custom-header"] == "blah"
def test_wrapper_internals(): """Test internals of the wrappers""" from werkzeug import Request req = Request.from_values(data={'foo': 'bar'}, method='POST') req._load_form_data() assert req.form.to_dict() == {'foo': 'bar'} # second call does not break req._load_form_data() assert req.form.to_dict() == {'foo': 'bar'} # check reprs assert repr(req) == "<Request 'http://localhost/' [POST]>" resp = Response() assert repr(resp) == '<Response 0 bytes [200 OK]>' resp.data = 'Hello World!' assert repr(resp) == '<Response 12 bytes [200 OK]>' resp.response = iter(['Test']) assert repr(resp) == '<Response streamed [200 OK]>' # unicode data does not set content length response = Response([u'Hällo Wörld']) headers = response.get_wsgi_headers(create_environ()) assert 'Content-Length' not in headers response = Response(['Hällo Wörld']) headers = response.get_wsgi_headers(create_environ()) assert 'Content-Length' in headers # check for internal warnings print 'start' filterwarnings('error', category=Warning) response = Response() environ = create_environ() response.response = 'What the...?' assert_raises(Warning, lambda: list(response.iter_encoded())) assert_raises(Warning, lambda: list(response.get_app_iter(environ))) response.direct_passthrough = True assert_raises(Warning, lambda: list(response.iter_encoded())) assert_raises(Warning, lambda: list(response.get_app_iter(environ))) resetwarnings()
def test_nonstandard_line_endings(): """Test nonstandard line endings of multipart form data""" for nl in '\n', '\r', '\r\n': data = nl.join(( '--foo', 'Content-Disposition: form-data; name=foo', '', 'this is just bar', '--foo', 'Content-Disposition: form-data; name=bar', '', 'blafasel', '--foo--' )) req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; ' 'boundary=foo', method='POST') print req.form assert req.form['foo'] == 'this is just bar' assert req.form['bar'] == 'blafasel'
def handle_aws_lambda_event(self, event, func): """Handles a Lambda event, convert event dict into corresponding data format that user API function is expecting, and use API function result as response :param event: AWS lambda event data of the python `dict` type :param func: user API function """ content_type = event['headers']['Content-Type'] if "multipart/form-data" in content_type: files = {} request = Request.from_values(data=event['body'], content_type=content_type, headers=event['headers']) for name in request.files: file = request.files[name] files[name] = self.read_file(file.filename, file.stream) result = func((files, ))[0] return self.output_adapter.to_aws_lambda_event(result, event) else: raise BadInput( "Multi-image requests don't support the {} content type". format(content_type))
def handle_batch_request(self, requests: Iterable[SimpleRequest], func) -> Iterable[SimpleResponse]: inputs = [] slices = [] for i, req in enumerate(requests): content_type = next(header[1] for header in req.headers if header[0] == b"Content-Type") if b"multipart/form-data" not in content_type: slices.append(None) else: files = {} request = Request.from_values( data=req.data, content_type=content_type, headers=req.headers, ) for name in request.files: file = request.files[name] files[name] = self.read_file(file.filename, file.stream) inputs.append(files) slices.append(i) results = func(inputs) if inputs else [] return self.output_adapter.to_batch_response(results, slices, requests)
def test_limiting(): """Test the limiting features""" data = "foo=Hello+World&bar=baz" req = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="application/x-www-form-urlencoded", method="POST", ) req.max_content_length = 400 assert req.form["foo"] == "Hello World" req = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="application/x-www-form-urlencoded", method="POST", ) req.max_form_memory_size = 7 assert_raises(RequestEntityTooLarge, lambda: req.form["foo"]) req = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="application/x-www-form-urlencoded", method="POST", ) req.max_form_memory_size = 400 assert req.form["foo"] == "Hello World" data = ( "--foo\r\nContent-Disposition: form-field; name=foo\r\n\r\n" "Hello World\r\n" "--foo\r\nContent-Disposition: form-field; name=bar\r\n\r\n" "bar=baz\r\n--foo--" ) req = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="multipart/form-data; boundary=foo", method="POST", ) req.max_content_length = 4 assert_raises(RequestEntityTooLarge, lambda: req.form["foo"]) req = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="multipart/form-data; boundary=foo", method="POST", ) req.max_content_length = 400 assert req.form["foo"] == "Hello World" req = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="multipart/form-data; boundary=foo", method="POST", ) req.max_form_memory_size = 7 assert_raises(RequestEntityTooLarge, lambda: req.form["foo"]) req = Request.from_values( input_stream=StringIO(data), content_length=len(data), content_type="multipart/form-data; boundary=foo", method="POST", ) req.max_form_memory_size = 400 assert req.form["foo"] == "Hello World"
def test_limiting(): """Test the limiting features""" data = 'foo=Hello+World&bar=baz' req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='application/x-www-form-urlencoded', method='POST') req.max_content_length = 4 req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='application/x-www-form-urlencoded', method='POST') req.max_content_length = 400 assert req.form['foo'] == 'Hello World' req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='application/x-www-form-urlencoded', method='POST') req.max_form_memory_size = 7 assert_raises(RequestEntityTooLarge, lambda: req.form['foo']) req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='application/x-www-form-urlencoded', method='POST') req.max_form_memory_size = 400 assert req.form['foo'] == 'Hello World' data = ('--foo\r\nContent-Disposition: form-field; name=foo\r\n\r\n' 'Hello World\r\n' '--foo\r\nContent-Disposition: form-field; name=bar\r\n\r\n' 'bar=baz\r\n--foo--') req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') req.max_content_length = 4 assert_raises(RequestEntityTooLarge, lambda: req.form['foo']) req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') req.max_content_length = 400 assert req.form['foo'] == 'Hello World' req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') req.max_form_memory_size = 7 assert_raises(RequestEntityTooLarge, lambda: req.form['foo']) req = Request.from_values(input_stream=StringIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') req.max_form_memory_size = 400 assert req.form['foo'] == 'Hello World'
def test_easteregg(): """Make sure the easteregg runs""" req = Request.from_values('/?macgybarchakku') resp = Response.force_type(internal._easteregg(None), req) assert 'About Werkzeug' in resp.data assert 'the Swiss Army knife of Python web development' in resp.data