Skip to content

feat: add InitSSE(), SSEStream() and fix deprecated CloseNotifier in …#4662

Open
shahariaz wants to merge 3 commits into
gin-gonic:masterfrom
shahariaz:feat/sse-helpers-and-stream-fix
Open

feat: add InitSSE(), SSEStream() and fix deprecated CloseNotifier in …#4662
shahariaz wants to merge 3 commits into
gin-gonic:masterfrom
shahariaz:feat/sse-helpers-and-stream-fix

Conversation

@shahariaz
Copy link
Copy Markdown

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 flushes
them to the client. Eliminates copy-paste boilerplate from every SSE handler.

c.SSEStream(step func(*Context) bool) bool (new)
Calls InitSSE() then loops — calling step and flushing after each call —
until the client disconnects (Request.Context().Done()) or step returns
false. Returns true on disconnect, false on normal end. Symmetric with
the existing Stream().

c.Stream() fix
Replaces the deprecated http.CloseNotifier / w.CloseNotify() with
c.Request.Context().Done(). http.CloseNotifier has been deprecated since
Go 1.11; Request.Context() is the stdlib-recommended replacement.

Tests

  • TestContextInitSSE — verifies headers are set and flushed
  • TestContextSSEStreamNormalEnd — verifies event loop terminates when step
    returns false
  • TestContextSSEStreamClientDisconnect — verifies loop exits on context
    cancellation
  • TestContextStream — fixed: added missing c.Request initialization
  • TestContextStreamWithClientGone — fixed: uses context cancellation instead
    of the removed CloseNotify()

Breaking Changes

None. Stream() behaviour is identical; it now uses context cancellation
instead of the deprecated CloseNotify().

@shahariaz shahariaz force-pushed the feat/sse-helpers-and-stream-fix branch from 67f5d24 to 4b37248 Compare May 22, 2026 19:12
@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.83%. Comparing base (3dc1cd6) to head (2c42206).
⚠️ Report is 281 commits behind head on master.

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     
Flag Coverage Δ
?
--ldflags="-checklinkname=0" -tags sonic 98.82% <100.00%> (?)
-tags go_json 98.76% <100.00%> (?)
-tags nomsgpack 98.82% <100.00%> (?)
go-1.18 ?
go-1.19 ?
go-1.20 ?
go-1.21 ?
go-1.25 98.83% <100.00%> (?)
go-1.26 98.83% <100.00%> (?)
macos-latest 98.83% <100.00%> (-0.38%) ⬇️
ubuntu-latest 98.83% <100.00%> (-0.38%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@shahariaz shahariaz force-pushed the feat/sse-helpers-and-stream-fix branch from 4b37248 to 8f66229 Compare May 22, 2026 19:19
@appleboy appleboy requested a review from Copilot June 2, 2026 13:52
@appleboy appleboy added this to the v1.13 milestone Jun 2, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) bool to run an SSE loop with automatic flush and disconnect detection.
  • Update docs and tests; migrate Stream() disconnect detection off CloseNotify().

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.

Comment thread context.go
Comment on lines +1333 to +1338
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()
}
Comment thread context.go
Comment on lines +1378 to +1392
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()
}
}
}
Comment thread context.go
Comment on lines 1396 to 1399
func (c *Context) Stream(step func(w io.Writer) bool) bool {
w := c.Writer
clientGone := w.CloseNotify()
clientGone := c.Request.Context().Done()
for {
Comment thread context_test.go
Comment on lines +1451 to +1455
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)
}
shahariaz added 2 commits June 2, 2026 21:03
… 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%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants