hono
hono copied to clipboard
SSEStreamingApi.writeSSE does not handle \r correctly
What version of Hono are you using?
4.7.4
What runtime/platform is your app running on? (with version if possible)
Node v22.4.1
What steps can reproduce the bug?
- Return the following SSE stream from a GET endpoint:
async function testStream(c: Context) {
return streamSSE(c, async (stream) => {
await stream.writeSSE({
data: `Left\r\rdata: Right`,
event: 'time-update',
})
})
}
app.get('/test', testStream)
- Listen on the client via
EventSourceand log the messages:
const evtSource = new EventSource("http://localhost:8080/test")
evtSource.onmessage = ((e) => {
console.log('Message:', e)
})
evtSource.addEventListener('time-update', (e) => {
console.log('Time-Update:', e)
})
What is the expected behavior?
It should log:
Time-Update: Left\r\rdata: Right
What do you see instead?
Time-Update: Left
Message: Right
Additional information
If \r is replaced with \n, things work correctly.
E.g
await stream.writeSSE({
data: `Left\n\ndata: Right`,
event: 'time-update',
})
logs:
Time-Update: Left
data: Right
The following code listens to an event via a stream reader:
const res = await fetch('http://localhost:8080/test')
if (!res.body) {
return
}
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader()
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log(value);
}
await reader.closed
Using it to listen to Left\n\ndata: Right logs:
event: time-update
data: Left
data:
data: data: Right
So it seems that hono adds the data: prefix for every line ending with \n to prevent double \n from ending an event. It doesn't do the same with \r:
Left\r\rdata: Right logs:
event: time-update
data: Leftdata: Right
Lines can end with \r according to the SSE spec https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
Hi @sor4chi @watany-dev
I'll work on it if I have time, but can you handle this if you can?