Skip to content

Commit

Permalink
Regression in parsing empty headers (#3218)
Browse files Browse the repository at this point in the history
  • Loading branch information
popravich authored and asvetlov committed Aug 28, 2018
1 parent 471c1f4 commit 470ccd0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES/3218.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix empty header parsing regression.
6 changes: 5 additions & 1 deletion aiohttp/_http_parser.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ cdef class HttpParser:

bytearray _raw_name
bytearray _raw_value
bint _has_value

object _protocol
object _loop
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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()
Expand Down
20 changes: 20 additions & 0 deletions tests/test_client_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 470ccd0

Please sign in to comment.