from io import open import os import falcon from falcon_multipart.middleware import MultipartMiddleware import pytest application = falcon.API(middleware=MultipartMiddleware()) @pytest.fixture def app(): return application def test_parse_form_as_params(client): class Resource: def on_post(self, req, resp, **kwargs): assert req.get_param('simple') == 'ok' assert req.get_param('afile').file.read() == b'filecontent' assert req.get_param('afile').filename == 'afile.txt' resp.body = 'parsed' resp.content_type = 'text/plain' application.add_route('/route', Resource()) resp = client.post('/route', data={'simple': 'ok'}, files={'afile': ('filecontent', 'afile.txt')}) assert resp.status == falcon.HTTP_OK assert resp.body == 'parsed' def test_with_binary_file(client): here = os.path.dirname(os.path.realpath(__file__)) filepath = os.path.join(here, 'image.jpg') image = open(filepath, 'rb') class Resource: def on_post(self, req, resp, **kwargs): resp.data = req.get_param('afile').file.read() resp.content_type = 'image/jpg' application.add_route('/route', Resource()) resp = client.post('/route', data={'simple': 'ok'}, files={'afile': image}) assert resp.status == falcon.HTTP_OK image.seek(0) assert resp.body == image.read() def test_parse_multiple_values(client): class Resource: def on_post(self, req, resp, **kwargs): assert req.get_param_as_list('multi') == ['1', '2'] resp.body = 'parsed' resp.content_type = 'text/plain' application.add_route('/route', Resource()) resp = client.post('/route', data={'multi': ['1', '2']}, files={'afile': ('filecontent', 'afile.txt')}) assert resp.status == falcon.HTTP_OK assert resp.body == 'parsed' def test_parse_non_ascii_filename_in_headers(client): class Resource: def on_post(self, req, resp, **kwargs): assert req.get_param('afile').file.read() == b'name,code\nnom,2\n' assert req.get_param('afile').filename == 'Na%C3%AFve%20file.txt' resp.body = 'parsed' resp.content_type = 'text/plain' application.add_route('/route', Resource()) # Simulate browser sending non ascii filename. body = ('--boundary\r\nContent-Disposition: ' 'form-data; name="afile"; filename*=utf-8\'\'Na%C3%AFve%20file.txt' '\r\nContent-Type: text/csv\r\n\r\nname,code\nnom,2\n\r\n' '--boundary--\r\n') headers = {'Content-Type': 'multipart/form-data; boundary=boundary'} resp = client.post('/route', body=body, headers=headers) assert resp.status == falcon.HTTP_OK assert resp.body == 'parsed'