Skip to content

Commit

Permalink
Patchback/backports/3.9/ecd9c72697ca1529e7cae4693775612987a2a6d2/pr 6…
Browse files Browse the repository at this point in the history
…559 (#7264)

<!-- Thank you for your contribution! -->

## What do these changes do?
This an attempt at a backport following these guidelines -
#6559 (comment) .
Note, haven't done a backport so no clue if I'm completely missing
something or it was as simple as resolving the merge conflicts when
cherry-picking that work in.

See
#6559 (comment)

---------

Co-authored-by: jorop <jorop@users.noreply.github.com>
Co-authored-by: Sam Bull <aa6bs0@sambull.org>
  • Loading branch information
3 people committed Apr 29, 2023
1 parent 2b3db3a commit 94aa627
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES/2304.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support setting response header parameters max_line_size and max_field_size.
20 changes: 20 additions & 0 deletions aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ class ClientSession:
"_ws_response_class",
"_trace_configs",
"_read_bufsize",
"_max_line_size",
"_max_field_size",
]
)

Expand Down Expand Up @@ -223,6 +225,8 @@ def __init__(
requote_redirect_url: bool = True,
trace_configs: Optional[List[TraceConfig]] = None,
read_bufsize: int = 2**16,
max_line_size: int = 8190,
max_field_size: int = 8190,
) -> None:
if loop is None:
if connector is not None:
Expand Down Expand Up @@ -296,6 +300,8 @@ def __init__(
self._trust_env = trust_env
self._requote_redirect_url = requote_redirect_url
self._read_bufsize = read_bufsize
self._max_line_size = max_line_size
self._max_field_size = max_field_size

# Convert to list of tuples
if headers:
Expand Down Expand Up @@ -393,6 +399,8 @@ async def _request(
trace_request_ctx: Optional[SimpleNamespace] = None,
read_bufsize: Optional[int] = None,
auto_decompress: Optional[bool] = None,
max_line_size: Optional[int] = None,
max_field_size: Optional[int] = None,
) -> ClientResponse:

# NOTE: timeout clamps existing connect and read timeouts. We cannot
Expand Down Expand Up @@ -458,6 +466,12 @@ async def _request(
if auto_decompress is None:
auto_decompress = self._auto_decompress

if max_line_size is None:
max_line_size = self._max_line_size

if max_field_size is None:
max_field_size = self._max_field_size

traces = [
Trace(
self,
Expand Down Expand Up @@ -564,6 +578,8 @@ async def _request(
read_timeout=real_timeout.sock_read,
read_bufsize=read_bufsize,
timeout_ceil_threshold=self._connector._timeout_ceil_threshold,
max_line_size=max_line_size,
max_field_size=max_field_size,
)

try:
Expand Down Expand Up @@ -1247,6 +1263,8 @@ def request(
connector: Optional[BaseConnector] = None,
read_bufsize: Optional[int] = None,
loop: Optional[asyncio.AbstractEventLoop] = None,
max_line_size: int = 8190,
max_field_size: int = 8190,
) -> _SessionRequestContextManager:
"""Constructs and sends a request.
Expand Down Expand Up @@ -1318,6 +1336,8 @@ def request(
proxy=proxy,
proxy_auth=proxy_auth,
read_bufsize=read_bufsize,
max_line_size=max_line_size,
max_field_size=max_field_size,
),
session,
)
4 changes: 4 additions & 0 deletions aiohttp/client_proto.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ def set_response_params(
read_timeout: Optional[float] = None,
read_bufsize: int = 2**16,
timeout_ceil_threshold: float = 5,
max_line_size: int = 8190,
max_field_size: int = 8190,
) -> None:
self._skip_payload = skip_payload

Expand All @@ -162,6 +164,8 @@ def set_response_params(
response_with_body=not skip_payload,
read_until_eof=read_until_eof,
auto_decompress=auto_decompress,
max_line_size=max_line_size,
max_field_size=max_field_size,
)

if self._tail:
Expand Down
102 changes: 102 additions & 0 deletions tests/test_client_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -3077,3 +3077,105 @@ async def handler(request):
assert resp.status == 200
assert await resp.text() == "ok"
assert resp.headers["Content-Type"] == "text/plain; charset=utf-8"


async def test_max_field_size_session_default(aiohttp_client) -> None:
async def handler(request):
return web.Response(headers={"Custom": "x" * 8190})

app = web.Application()
app.add_routes([web.get("/", handler)])

client = await aiohttp_client(app)

async with await client.get("/") as resp:
assert resp.headers["Custom"] == "x" * 8190


async def test_max_field_size_session_default_fail(aiohttp_client) -> None:
async def handler(request):
return web.Response(headers={"Custom": "x" * 8191})

app = web.Application()
app.add_routes([web.get("/", handler)])

client = await aiohttp_client(app)
with pytest.raises(aiohttp.ClientResponseError):
await client.get("/")


async def test_max_field_size_session_explicit(aiohttp_client) -> None:
async def handler(request):
return web.Response(headers={"Custom": "x" * 8191})

app = web.Application()
app.add_routes([web.get("/", handler)])

client = await aiohttp_client(app, max_field_size=8191)

async with await client.get("/") as resp:
assert resp.headers["Custom"] == "x" * 8191


async def test_max_field_size_request_explicit(aiohttp_client) -> None:
async def handler(request):
return web.Response(headers={"Custom": "x" * 8191})

app = web.Application()
app.add_routes([web.get("/", handler)])

client = await aiohttp_client(app)

async with await client.get("/", max_field_size=8191) as resp:
assert resp.headers["Custom"] == "x" * 8191


async def test_max_line_size_session_default(aiohttp_client) -> None:
async def handler(request):
return web.Response(status=200, reason="x" * 8190)

app = web.Application()
app.add_routes([web.get("/", handler)])

client = await aiohttp_client(app)

async with await client.get("/") as resp:
assert resp.reason == "x" * 8190


async def test_max_line_size_session_default_fail(aiohttp_client) -> None:
async def handler(request):
return web.Response(status=200, reason="x" * 8192)

app = web.Application()
app.add_routes([web.get("/", handler)])

client = await aiohttp_client(app)
with pytest.raises(aiohttp.ClientResponseError):
await client.get("/")


async def test_max_line_size_session_explicit(aiohttp_client) -> None:
async def handler(request):
return web.Response(status=200, reason="x" * 8191)

app = web.Application()
app.add_routes([web.get("/", handler)])

client = await aiohttp_client(app, max_line_size=8191)

async with await client.get("/") as resp:
assert resp.reason == "x" * 8191


async def test_max_line_size_request_explicit(aiohttp_client) -> None:
async def handler(request):
return web.Response(status=200, reason="x" * 8191)

app = web.Application()
app.add_routes([web.get("/", handler)])

client = await aiohttp_client(app)

async with await client.get("/", max_line_size=8191) as resp:
assert resp.reason == "x" * 8191

0 comments on commit 94aa627

Please sign in to comment.