feat: add InitSSE(), SSEStream() and fix deprecated CloseNotifier in …#4662
feat: add InitSSE(), SSEStream() and fix deprecated CloseNotifier in …#4662shahariaz wants to merge 3 commits into
Conversation
67f5d24 to
4b37248
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4662 +/- ##
==========================================
- Coverage 99.21% 98.83% -0.38%
==========================================
Files 42 48 +6
Lines 3182 3181 -1
==========================================
- Hits 3157 3144 -13
- Misses 17 27 +10
- Partials 8 10 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
4b37248 to
8f66229
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds first-class helpers for Server-Sent Events (SSE) on gin.Context and updates Context.Stream() to use Request.Context().Done() instead of the deprecated http.CloseNotifier.
Changes:
- Add
(*Context).InitSSE()to set SSE headers and start the response. - Add
(*Context).SSEStream(step func(*Context) bool) boolto run an SSE loop with automatic flush and disconnect detection. - Update docs and tests; migrate
Stream()disconnect detection offCloseNotify().
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| docs/doc.md | Documents InitSSE() / SSEStream() usage patterns and return semantics. |
| context.go | Adds InitSSE() and SSEStream(); replaces Stream()’s CloseNotify() usage with request context cancellation. |
| context_test.go | Adds tests for InitSSE() / SSEStream() and updates Stream() tests to use request context cancellation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func (c *Context) InitSSE() { | ||
| c.Writer.Header().Set("Content-Type", sse.ContentType) | ||
| c.Writer.Header().Set("Cache-Control", "no-cache") | ||
| c.Writer.Header().Set("Connection", "keep-alive") | ||
| c.Writer.WriteHeaderNow() | ||
| } |
| func (c *Context) SSEStream(step func(c *Context) bool) bool { | ||
| c.InitSSE() | ||
| ctx := c.Request.Context() | ||
| for { | ||
| select { | ||
| case <-ctx.Done(): | ||
| return true | ||
| default: | ||
| if !step(c) { | ||
| return false | ||
| } | ||
| c.Writer.Flush() | ||
| } | ||
| } | ||
| } |
| func (c *Context) Stream(step func(w io.Writer) bool) bool { | ||
| w := c.Writer | ||
| clientGone := w.CloseNotify() | ||
| clientGone := c.Request.Context().Done() | ||
| for { |
| assert.Equal(t, sse.ContentType, w.Header().Get("Content-Type")) | ||
| assert.Equal(t, "no-cache", w.Header().Get("Cache-Control")) | ||
| assert.Equal(t, "keep-alive", w.Header().Get("Connection")) | ||
| assert.Equal(t, http.StatusOK, w.Code) | ||
| } |
… paths - ginS: add TestLoadHTMLGlob, TestLoadHTMLFiles, TestLoadHTMLFS covering the three HTML template loader wrappers (73.1% -> 100%) - ginS: add TestRunError, TestRunTLSError, TestRunUnixError, TestRunFdError covering all four server-start wrappers via fast-failing error paths - binding: add TestPlainBindingBody covering plainBinding.BindBody (string, []byte, unsupported type, and nil receiver branches) - render: add TestRedirectWriteContentType covering the Redirect no-op method Overall project coverage: 98.5% -> 98.9% Patch coverage: 100%
Summary
Adds two new SSE helper methods and fixes a deprecated API in
Stream().Changes
c.InitSSE()(new)Sets the required SSE response headers (
Content-Type: text/event-stream,Cache-Control: no-cache,Connection: keep-alive) and immediately flushesthem to the client. Eliminates copy-paste boilerplate from every SSE handler.
c.SSEStream(step func(*Context) bool) bool(new)Calls
InitSSE()then loops — callingstepand flushing after each call —until the client disconnects (
Request.Context().Done()) orstepreturnsfalse. Returnstrueon disconnect,falseon normal end. Symmetric withthe existing
Stream().c.Stream()fixReplaces the deprecated
http.CloseNotifier/w.CloseNotify()withc.Request.Context().Done().http.CloseNotifierhas been deprecated sinceGo 1.11;
Request.Context()is the stdlib-recommended replacement.Tests
TestContextInitSSE— verifies headers are set and flushedTestContextSSEStreamNormalEnd— verifies event loop terminates when stepreturns false
TestContextSSEStreamClientDisconnect— verifies loop exits on contextcancellation
TestContextStream— fixed: added missingc.RequestinitializationTestContextStreamWithClientGone— fixed: uses context cancellation insteadof the removed
CloseNotify()Breaking Changes
None.
Stream()behaviour is identical; it now uses context cancellationinstead of the deprecated
CloseNotify().