diff --git a/aiohttp/helpers.py b/aiohttp/helpers.py index 9fcb7f23832..9c64ee818e4 100644 --- a/aiohttp/helpers.py +++ b/aiohttp/helpers.py @@ -105,11 +105,12 @@ class FormData: """Helper class for multipart/form-data and application/x-www-form-urlencoded body generation.""" - def __init__(self, fields=()): + def __init__(self, fields=(), quote_fields=True): from . import multipart self._writer = multipart.MultipartWriter('form-data') self._fields = [] self._is_multipart = False + self._quote_fields = quote_fields if isinstance(fields, dict): fields = list(fields.items()) @@ -200,7 +201,9 @@ def _gen_form_data(self, *args, **kwargs): for dispparams, headers, value in self._fields: part = self._writer.append(value, headers) if dispparams: - part.set_content_disposition('form-data', **dispparams) + part.set_content_disposition( + 'form-data', quote_fields=self._quote_fields, **dispparams + ) # FIXME cgi.FieldStorage doesn't likes body parts with # Content-Length which were sent via chunked transfer encoding part.headers.pop(hdrs.CONTENT_LENGTH, None) diff --git a/aiohttp/multipart.py b/aiohttp/multipart.py index b11ee29de7c..16a7cafc905 100644 --- a/aiohttp/multipart.py +++ b/aiohttp/multipart.py @@ -883,7 +883,7 @@ def _apply_content_transfer_encoding(self, stream): raise RuntimeError('unknown content transfer encoding: {}' ''.format(encoding)) - def set_content_disposition(self, disptype, **params): + def set_content_disposition(self, disptype, quote_fields=True, **params): """Sets ``Content-Disposition`` header. :param str disptype: Disposition type: inline, attachment, form-data. @@ -900,7 +900,7 @@ def set_content_disposition(self, disptype, **params): if not key or not (TOKEN > set(key)): raise ValueError('bad content disposition parameter' ' {!r}={!r}'.format(key, val)) - qval = quote(val, '') + qval = quote(val, '') if quote_fields else val lparams.append((key, '"%s"' % qval)) if key == 'filename': lparams.append(('filename*', "utf-8''" + qval)) diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 949b7b5aa04..b916b9ff181 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -155,6 +155,20 @@ def test_invalid_formdata_content_transfer_encoding(): # ------------- access logger ------------------------- +def test_formdata_field_name_is_quoted(): + form = helpers.FormData() + form.add_field("emails[]", "xxx@x.co", content_type="multipart/form-data") + res = b"".join(form("ascii")) + assert b'name="emails%5B%5D"' in res + + +def test_formdata_field_name_is_not_quoted(): + form = helpers.FormData(quote_fields=False) + form.add_field("emails[]", "xxx@x.co", content_type="multipart/form-data") + res = b"".join(form("ascii")) + assert b'name="emails[]"' in res + + def test_access_logger_format(): log_format = '%T {%{SPAM}e} "%{ETag}o" %X {X} %%P %{FOO_TEST}e %{FOO1}e' mock_logger = mock.Mock()