Skip to content

Commit 7eb2022

Browse files
DHuyAuHuy Au
and
Huy Au
authored
Accept http headers up to 100kB (encode#647)
Increase the default allowable http header size to 100kB similar to curl. Raised in discussion encode/httpx#2520 Co-authored-by: Huy Au <[email protected]>
1 parent f49d37e commit 7eb2022

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

httpcore/_async/http11.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class HTTPConnectionState(enum.IntEnum):
4343

4444
class AsyncHTTP11Connection(AsyncConnectionInterface):
4545
READ_NUM_BYTES = 64 * 1024
46+
MAX_INCOMPLETE_EVENT_SIZE = 100 * 1024
4647

4748
def __init__(
4849
self,
@@ -57,7 +58,10 @@ def __init__(
5758
self._state = HTTPConnectionState.NEW
5859
self._state_lock = AsyncLock()
5960
self._request_count = 0
60-
self._h11_state = h11.Connection(our_role=h11.CLIENT)
61+
self._h11_state = h11.Connection(
62+
our_role=h11.CLIENT,
63+
max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE,
64+
)
6165

6266
async def handle_async_request(self, request: Request) -> Response:
6367
if not self.can_handle_request(request.url.origin):

httpcore/_sync/http11.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class HTTPConnectionState(enum.IntEnum):
4343

4444
class HTTP11Connection(ConnectionInterface):
4545
READ_NUM_BYTES = 64 * 1024
46+
MAX_INCOMPLETE_EVENT_SIZE = 100 * 1024
4647

4748
def __init__(
4849
self,
@@ -57,7 +58,10 @@ def __init__(
5758
self._state = HTTPConnectionState.NEW
5859
self._state_lock = Lock()
5960
self._request_count = 0
60-
self._h11_state = h11.Connection(our_role=h11.CLIENT)
61+
self._h11_state = h11.Connection(
62+
our_role=h11.CLIENT,
63+
max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE,
64+
)
6165

6266
def handle_request(self, request: Request) -> Response:
6367
if not self.can_handle_request(request.url.origin):

tests/_async/test_http11.py

+24
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,27 @@ async def test_http11_early_hints():
310310
)
311311
assert response.status == 200
312312
assert response.content == b"<html>Hello, world! ...</html>"
313+
314+
315+
@pytest.mark.anyio
316+
async def test_http11_header_sub_100kb():
317+
"""
318+
A connection should be able to handle a http header size up to 100kB.
319+
"""
320+
origin = Origin(b"https", b"example.com", 443)
321+
stream = AsyncMockStream(
322+
[
323+
b"HTTP/1.1 200 OK\r\n", # 17
324+
b"Content-Type: plain/text\r\n", # 43
325+
b"Cookie: " + b"x" * (100 * 1024 - 72) + b"\r\n", # 102381
326+
b"Content-Length: 0\r\n", # 102400
327+
b"\r\n",
328+
b"",
329+
]
330+
)
331+
async with AsyncHTTP11Connection(
332+
origin=origin, stream=stream, keepalive_expiry=5.0
333+
) as conn:
334+
response = await conn.request("GET", "https://example.com/")
335+
assert response.status == 200
336+
assert response.content == b""

tests/_sync/test_http11.py

+24
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,27 @@ def test_http11_early_hints():
310310
)
311311
assert response.status == 200
312312
assert response.content == b"<html>Hello, world! ...</html>"
313+
314+
315+
316+
def test_http11_header_sub_100kb():
317+
"""
318+
A connection should be able to handle a http header size up to 100kB.
319+
"""
320+
origin = Origin(b"https", b"example.com", 443)
321+
stream = MockStream(
322+
[
323+
b"HTTP/1.1 200 OK\r\n", # 17
324+
b"Content-Type: plain/text\r\n", # 43
325+
b"Cookie: " + b"x" * (100 * 1024 - 72) + b"\r\n", # 102381
326+
b"Content-Length: 0\r\n", # 102400
327+
b"\r\n",
328+
b"",
329+
]
330+
)
331+
with HTTP11Connection(
332+
origin=origin, stream=stream, keepalive_expiry=5.0
333+
) as conn:
334+
response = conn.request("GET", "https://example.com/")
335+
assert response.status == 200
336+
assert response.content == b""

0 commit comments

Comments
 (0)