feat(sse): first-class Server-Sent Events API on HttpResponse (#3)#91
Merged
Conversation
Add text/event-stream helpers — sseStart(), sseEvent($data, $event, $id, $retry), sseComment() and sseRetry() — layered on the existing send() streaming pipeline, so the same handler streams over HTTP/1.1, HTTP/2 and HTTP/3 (the client picks the protocol via ALPN/Upgrade). sseStart() sets the canonical headers (Content-Type: text/event-stream, Cache-Control: no-cache, no-transform, X-Accel-Buffering: no) and marks the response non-compressible. Framing follows WHATWG §9.2: multiline data is split per line, single-line fields reject CR/LF (injection) and id rejects NUL. All input validation runs before the stream commits, so a rejected call leaves the response buffered. Implemented in a dedicated TU (src/http_sse.c). phpt coverage for H1/H2/H3 end-to-end framing plus the validation surface; example in examples/sse-server.php.
Contributor
CoverageTotal lines: 75.71% → 76.04% (+0.33 pp)
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3.
First-class Server-Sent Events (
text/event-stream) as thin WHATWG §9.2framing helpers over the existing
send()streaming pipeline — SSE is not aseparate protocol, so the same handler streams over HTTP/1.1, HTTP/2 and
HTTP/3 (the client picks the protocol via ALPN / Upgrade).
API (
HttpResponse)sseStart(): staticsseEvent(?string $data, ?string $event, ?string $id, ?int $retry): staticsseComment(string $text = ""): static:heartbeat to hold the connection through proxy idle timeouts.sseRetry(int $milliseconds): staticretry:reconnect-delay directive.sseStart()setsContent-Type: text/event-stream,Cache-Control: no-cache, no-transform,X-Accel-Buffering: noand marks the response non-compressible(a buffering gzip stream would defeat real-time delivery).
Correctness
datais split into onedata:line perLF/CR/CRLF; conventional field order
id, event, retry, data; recordterminated by a blank line.
event,id) reject CR/LF,idrejects NUL,
retryrejects negatives — all before the stream commits, soa rejected call leaves the response buffered.
stream_ops->append_chunk,which suspends the handler under H2/H3 flow control; a dead stream surfaces as
499, matchingsend().Implementation
src/http_sse.c(wired into config.m4 / config.w32 / CMakeLists.txt).Tests
h1/022— chunked framing + headers +Transfer-Encoding: chunked+ streaming-lock + telemetryh1/023— full input-validation surface (buffered route)h2/025— h2c DATA-frame stream (headers survive HPACK)h3/041— QUIC stream viah3client(body byte-exact, status, header count, h3 stats)Full server suite 214/214 locally (1 pre-existing XFAIL warn, unrelated).