Streaming Response Support
Status: Implemented
Overview
Add support for streaming HTTP responses (chunked transfer-encoding and SSE) through the tunnel, so that long-lived or chunked responses are delivered incrementally to the client instead of being buffered entirely in memory.
Protocol
Three new WebSocket frame types (agent -> edge):
http_response_start-- begins a streaming response with status code and headers (no body).http_response_chunk-- a base64-encoded chunk of the response body.http_response_end-- signals the response is complete.
The existing http_response frame (full buffered body) remains supported for backward compatibility.
Components
wsproto (cli/internal/wsproto/proto.go)
New constants and structs:
TypeHTTPResponseStart,TypeHTTPResponseChunk,TypeHTTPResponseEndHTTPResponseStartstruct (Type, RequestID, Status, Headers)HTTPResponseChunkstruct (Type, RequestID, DataB64)HTTPResponseEndstruct (Type, RequestID)
Edge server (cli/internal/edge/edge.go)
streamWritertype holds a reference to the clienthttp.ResponseWriterand adonechannel.- Session gets a
streamingmap (map[string]*streamWriter) alongside the existingpendingmap. readAgentLoophandles the three new frame types: writes headers onhttp_response_start, writes decoded chunks onhttp_response_chunk, and closes the done channel onhttp_response_end.handlePublicHTTPregisters both a pending channel and a stream writer for each request. If the agent uses streaming (closes the channel instead of sending a full response), it waits on the stream writer done channel.- Full backward compatibility: agents that send
http_responsework exactly as before.
PHP CLI EdgeAgent (jetty-client/src/EdgeAgent.php)
- Detects streaming responses via
Transfer-Encoding: chunkedorContent-Type: text/event-streamheaders from the upstream. - Uses
CURLOPT_HEADERFUNCTIONandCURLOPT_WRITEFUNCTIONcallbacks to stream data. - For streaming: sends
http_response_startwith headers, thenhttp_response_chunkfor each chunk of data from the upstream, thenhttp_response_end. - For normal responses: sends the existing
http_responseframe (backward compatible). - Returns a
streamedflag so the caller knows whether the response was already sent over the WebSocket.
Send feedback
Found an issue or have a suggestion? Let us know.