Skip to content

Commit 1f868f4

Browse files
CSchriswritescode-dev
authored andcommitted
Fix SSE duplicate Transfer-Encoding headers
Replace Hono's streamSSE with manual stream implementation to avoid sending duplicate Transfer-Encoding: chunked headers which cause nginx/Cloudflare to reject responses with 502 errors. Manually formats SSE messages with proper event/data structure and sets Content-Type: text/event-stream headers.
1 parent 5d5c4d1 commit 1f868f4

File tree

1 file changed

+11
-21
lines changed

1 file changed

+11
-21
lines changed

backend/src/routes/sse.ts

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ export function createSSERoutes() {
88
const app = new Hono()
99

1010
app.get('/stream', async (c) => {
11-
c.header('Cache-Control', 'no-cache, no-store, no-transform')
12-
c.header('Connection', 'keep-alive')
13-
c.header('X-Accel-Buffering', 'no')
14-
1511
const directoriesParam = c.req.query('directories')
1612
const directories = directoriesParam ? directoriesParam.split(',').filter(Boolean) : []
1713
const clientId = `client_${Date.now()}_${Math.random().toString(36).slice(2)}`
@@ -90,34 +86,28 @@ export function createSSERoutes() {
9086
})
9187

9288
app.get('/test-stream', async (c) => {
93-
c.header('Content-Type', 'text/event-stream')
94-
c.header('Cache-Control', 'no-cache, no-store, no-transform')
95-
c.header('Connection', 'keep-alive')
96-
c.header('X-Accel-Buffering', 'no')
89+
return stream(c, async (writer) => {
90+
const writeSSE = (event: string, data: string) => {
91+
const lines = []
92+
if (event) lines.push(`event: ${event}`)
93+
lines.push(`data: ${data}`)
94+
lines.push('')
95+
lines.push('')
96+
writer.write(new TextEncoder().encode(lines.join('\n')))
97+
}
9798

98-
return streamSSE(c, async (stream) => {
99-
await stream.writeSSE({
100-
event: 'test',
101-
data: JSON.stringify({ message: 'SSE working', timestamp: Date.now() })
102-
})
99+
writeSSE('test', JSON.stringify({ message: 'SSE working', timestamp: Date.now() }))
103100

104101
let count = 0
105102
const interval = setInterval(async () => {
106103
count++
107104
try {
108-
await stream.writeSSE({
109-
event: 'ping',
110-
data: JSON.stringify({ count, timestamp: Date.now() })
111-
})
105+
writeSSE('ping', JSON.stringify({ count, timestamp: Date.now() }))
112106
} catch {
113107
clearInterval(interval)
114108
}
115109
}, 1000)
116110

117-
stream.onAbort(() => {
118-
clearInterval(interval)
119-
})
120-
121111
await new Promise(() => {})
122112
})
123113
})

0 commit comments

Comments
 (0)