From 3e12a2cc00aee82beee510658670ecc3c34711b7 Mon Sep 17 00:00:00 2001 From: Alexey Popravka <alexey.popravka@horsedevel.com> Date: Mon, 27 Aug 2018 13:36:25 +0300 Subject: [PATCH 1/4] Add a empty header value parsing test (failing test) --- tests/test_client_functional.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index 05588453d30..33d27b401a5 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -495,6 +495,26 @@ async def handler(request): resp.close() +async def test_empty_header_values(aiohttp_client): + async def handler(request): + resp = web.Response() + resp.headers['X-Empty'] = '' + return resp + + app = web.Application() + app.router.add_route('GET', '/', handler) + client = await aiohttp_client(app) + resp = await client.get('/') + assert resp.status == 200 + raw_headers = tuple((bytes(h), bytes(v)) for h, v in resp.raw_headers) + assert raw_headers == ((b'X-Empty', b''), + (b'Content-Length', b'0'), + (b'Content-Type', b'application/octet-stream'), + (b'Date', mock.ANY), + (b'Server', mock.ANY)) + resp.close() + + async def test_204_with_gzipped_content_encoding(aiohttp_client): async def handler(request): resp = web.StreamResponse(status=204) From 3bd52060350fcdf74402e9a499825ef62e259daf Mon Sep 17 00:00:00 2001 From: Alexey Popravka <alexey.popravka@horsedevel.com> Date: Mon, 27 Aug 2018 15:51:12 +0300 Subject: [PATCH 2/4] fix empty header value parsing --- CHANGES/3218.bugfix | 1 + aiohttp/_http_parser.pyx | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 CHANGES/3218.bugfix diff --git a/CHANGES/3218.bugfix b/CHANGES/3218.bugfix new file mode 100644 index 00000000000..990e082fbc0 --- /dev/null +++ b/CHANGES/3218.bugfix @@ -0,0 +1 @@ +Fix empty header parsing regression. diff --git a/aiohttp/_http_parser.pyx b/aiohttp/_http_parser.pyx index b0a214c1c16..817b4827e5e 100644 --- a/aiohttp/_http_parser.pyx +++ b/aiohttp/_http_parser.pyx @@ -260,6 +260,7 @@ cdef class HttpParser: bytearray _raw_name bytearray _raw_value + bint _has_value object _protocol object _loop @@ -327,6 +328,7 @@ cdef class HttpParser: self._raw_name = bytearray() self._raw_value = bytearray() + self._has_value = False self._max_line_size = max_line_size self._max_headers = max_headers @@ -364,12 +366,13 @@ cdef class HttpParser: PyByteArray_Resize(self._raw_name, 0) PyByteArray_Resize(self._raw_value, 0) + self._has_value = False self._raw_headers.append((raw_name, raw_value)) cdef _on_header_field(self, char* at, size_t length): cdef Py_ssize_t size cdef char *buf - if self._raw_value: + if self._has_value: self._process_header() size = PyByteArray_Size(self._raw_name) @@ -385,6 +388,7 @@ cdef class HttpParser: PyByteArray_Resize(self._raw_value, size + length) buf = PyByteArray_AsString(self._raw_value) memcpy(buf + size, at, length) + self._has_value = True cdef _on_headers_complete(self): self._process_header() From 0f1520b699f158b6f269dd248e433082a187a38e Mon Sep 17 00:00:00 2001 From: Alexey Popravka <alexey.popravka@horsedevel.com> Date: Mon, 27 Aug 2018 16:22:31 +0300 Subject: [PATCH 3/4] add one more related issue to CHANGES --- CHANGES/3219.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGES/3219.bugfix diff --git a/CHANGES/3219.bugfix b/CHANGES/3219.bugfix new file mode 100644 index 00000000000..990e082fbc0 --- /dev/null +++ b/CHANGES/3219.bugfix @@ -0,0 +1 @@ +Fix empty header parsing regression. From 3c98df8a5e084499aaaa46944fc3ba903bf86e82 Mon Sep 17 00:00:00 2001 From: Alexey Popravka <alexey.popravka@horsedevel.com> Date: Tue, 28 Aug 2018 12:53:47 +0300 Subject: [PATCH 4/4] drop duplicate news fragment --- CHANGES/3219.bugfix | 1 - 1 file changed, 1 deletion(-) delete mode 100644 CHANGES/3219.bugfix diff --git a/CHANGES/3219.bugfix b/CHANGES/3219.bugfix deleted file mode 100644 index 990e082fbc0..00000000000 --- a/CHANGES/3219.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix empty header parsing regression.