Skip to content

feat(client/plugin): stream HTTP client plugin responses#795

Open
Nicofuma wants to merge 1 commit into
luraproject:masterfrom
Nicofuma:prototype/streaming-client-plugin-executor
Open

feat(client/plugin): stream HTTP client plugin responses#795
Nicofuma wants to merge 1 commit into
luraproject:masterfrom
Nicofuma:prototype/streaming-client-plugin-executor

Conversation

@Nicofuma

Copy link
Copy Markdown

The client plugin executor buffered the entire plugin response with httptest.NewRecorder and only returned once ServeHTTP completed, which makes streaming responses (Server-Sent Events, chunked passthrough, large downloads) impossible: the proxy, and therefore the client, received nothing until the plugin handler returned, i.e. until the upstream stream closed.

Run the handler in a goroutine writing into an io.Pipe and return the response as soon as the status line and headers are known, with the pipe's read end as the body. Bytes now flow to the caller as the handler produces them.

The pipe is unbuffered, so the executor watches the request context and closes the read end on cancellation, ensuring the handler goroutine unwinds even when a consumer drops the response. Flush commits the headers like net/http, a panicking handler surfaces as a 502, and the error-status handler bounds how much of a streaming error body it reads.

@Nicofuma Nicofuma force-pushed the prototype/streaming-client-plugin-executor branch 2 times, most recently from efa18f7 to e2311f2 Compare June 19, 2026 13:35
The client plugin executor buffered the entire plugin response with
httptest.NewRecorder and only returned once ServeHTTP completed, which
makes streaming responses (Server-Sent Events, chunked passthrough,
large downloads) impossible: the proxy, and therefore the client,
received nothing until the plugin handler returned, i.e. until the
upstream stream closed.

Run the handler in a goroutine writing into an io.Pipe and return the
response as soon as the status line and headers are known, with the
pipe's read end as the body. Bytes now flow to the caller as the handler
produces them.

The pipe is unbuffered, so the executor watches the request context and
closes the read end on cancellation, ensuring the handler goroutine
unwinds even when a consumer drops the response. Flush commits the
headers like net/http, a panicking handler surfaces as a 502, and the
error-status handler bounds how much of a streaming error body it reads.

Signed-off-by: Tristan Darricau <tristan.darricau@jobteaser.com>
@Nicofuma Nicofuma force-pushed the prototype/streaming-client-plugin-executor branch from e2311f2 to fb8b998 Compare June 19, 2026 13:37
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.

1 participant