Skip to content

Commit

Permalink
Accept http headers up to 100kB (#647)
Browse files Browse the repository at this point in the history
Increase the default allowable http header size to 100kB similar to curl.

Raised in discussion encode/httpx#2520

Co-authored-by: Huy Au <hau@invast.com.au>
  • Loading branch information
DHuyAu and Huy Au authored Jan 5, 2023
1 parent f49d37e commit 7eb2022
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 2 deletions.
6 changes: 5 additions & 1 deletion httpcore/_async/http11.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class HTTPConnectionState(enum.IntEnum):

class AsyncHTTP11Connection(AsyncConnectionInterface):
READ_NUM_BYTES = 64 * 1024
MAX_INCOMPLETE_EVENT_SIZE = 100 * 1024

def __init__(
self,
Expand All @@ -57,7 +58,10 @@ def __init__(
self._state = HTTPConnectionState.NEW
self._state_lock = AsyncLock()
self._request_count = 0
self._h11_state = h11.Connection(our_role=h11.CLIENT)
self._h11_state = h11.Connection(
our_role=h11.CLIENT,
max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE,
)

async def handle_async_request(self, request: Request) -> Response:
if not self.can_handle_request(request.url.origin):
Expand Down
6 changes: 5 additions & 1 deletion httpcore/_sync/http11.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class HTTPConnectionState(enum.IntEnum):

class HTTP11Connection(ConnectionInterface):
READ_NUM_BYTES = 64 * 1024
MAX_INCOMPLETE_EVENT_SIZE = 100 * 1024

def __init__(
self,
Expand All @@ -57,7 +58,10 @@ def __init__(
self._state = HTTPConnectionState.NEW
self._state_lock = Lock()
self._request_count = 0
self._h11_state = h11.Connection(our_role=h11.CLIENT)
self._h11_state = h11.Connection(
our_role=h11.CLIENT,
max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE,
)

def handle_request(self, request: Request) -> Response:
if not self.can_handle_request(request.url.origin):
Expand Down
24 changes: 24 additions & 0 deletions tests/_async/test_http11.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,27 @@ async def test_http11_early_hints():
)
assert response.status == 200
assert response.content == b"<html>Hello, world! ...</html>"


@pytest.mark.anyio
async def test_http11_header_sub_100kb():
"""
A connection should be able to handle a http header size up to 100kB.
"""
origin = Origin(b"https", b"example.com", 443)
stream = AsyncMockStream(
[
b"HTTP/1.1 200 OK\r\n", # 17
b"Content-Type: plain/text\r\n", # 43
b"Cookie: " + b"x" * (100 * 1024 - 72) + b"\r\n", # 102381
b"Content-Length: 0\r\n", # 102400
b"\r\n",
b"",
]
)
async with AsyncHTTP11Connection(
origin=origin, stream=stream, keepalive_expiry=5.0
) as conn:
response = await conn.request("GET", "https://example.com/")
assert response.status == 200
assert response.content == b""
24 changes: 24 additions & 0 deletions tests/_sync/test_http11.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,27 @@ def test_http11_early_hints():
)
assert response.status == 200
assert response.content == b"<html>Hello, world! ...</html>"



def test_http11_header_sub_100kb():
"""
A connection should be able to handle a http header size up to 100kB.
"""
origin = Origin(b"https", b"example.com", 443)
stream = MockStream(
[
b"HTTP/1.1 200 OK\r\n", # 17
b"Content-Type: plain/text\r\n", # 43
b"Cookie: " + b"x" * (100 * 1024 - 72) + b"\r\n", # 102381
b"Content-Length: 0\r\n", # 102400
b"\r\n",
b"",
]
)
with HTTP11Connection(
origin=origin, stream=stream, keepalive_expiry=5.0
) as conn:
response = conn.request("GET", "https://example.com/")
assert response.status == 200
assert response.content == b""

0 comments on commit 7eb2022

Please sign in to comment.