Skip to content

connmgr: add ability to send large outbound request headers#48368

Merged
jkarneges merged 2 commits into
mainfrom
jkarneges/send-large-header
Jun 16, 2026
Merged

connmgr: add ability to send large outbound request headers#48368
jkarneges merged 2 commits into
mainfrom
jkarneges/send-large-header

Conversation

@jkarneges

@jkarneges jkarneges commented Jun 16, 2026

Copy link
Copy Markdown
Member

Following #48365, this PR implements support for large outbound request headers.

Currently, http1::client::Request::prepare_header serializes its inputs (method, URI, headers) to a buffer and returns a RequestHeader instance. Then the async method RequestHeader::send writes the buffer to the socket. This PR reworks things such that prepare_header borrows its inputs without doing any serialization, keeping them in the RequestHeader instance, and then the send method writes the inputs directly to the socket, with resumption for partial writes.

The resulting API is essentially the same except callers have to ensure the inputs live until send completes, so some variables are moved around near call sites to achieve this.

Note: moving variables around in order to extend their lifetimes caused the async task sizes to increase beyond our latest thresholds. I'll see about optimizing the sizes afterwards, but if nothing can be done I think it's fine.

The underlying http1::protocol::ClientRequest::send_header function, like many of our low level I/O functions, is synchronous and operates on a Write implementation. In order to operate on an AsyncWrite implementation from within an async function, we use a pattern involving two convenience wrappers, StdWriteWrapper and AsyncOperation. StdWriteWrapper implements Write on anything that implements AsyncWrite. With it, an async socket object can be passed to send_header. AsyncOperation is then used to wrap the call and present it as a future that can be awaited.

Below is a manual test of ~20kb headers proxied from pushpin to nginx, using an 8kb block size in pushpin.

Before:

% curl -i -H "@largeheaders.txt" http://localhost:7999
HTTP/1.1 502 Bad Gateway
Content-Type: text/plain
Content-Length: 32

Error while proxying to origin.

Logs:

[DEBUG] 2026-06-16 10:44:11.549 [connmgr] [pushpin::connmgr::connection] client-conn 0-0-969f22eb-aa0c-41c7-ac78-17f58c90232c: process error: CoreHttp(RequestTooLarge(8192))

After:

% curl -i -H "@largeheaders.txt" http://localhost:7999
HTTP/1.1 200 OK
Server: nginx/1.29.8
Date: Tue, 16 Jun 2026 17:46:31 GMT
Content-Type: text/html
Last-Modified: Tue, 07 Apr 2026 11:41:31 GMT
ETag: "69d4ed6b-380"
Accept-Ranges: bytes
Content-Length: 896

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

@jkarneges jkarneges requested a review from a team June 16, 2026 18:24
@jkarneges jkarneges merged commit 08464e1 into main Jun 16, 2026
19 checks passed
@jkarneges jkarneges deleted the jkarneges/send-large-header branch June 16, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants