fix: support CRLF SSE frame parsing (#223)

This commit is contained in:
Alan
2026-04-09 21:52:28 +08:00
committed by GitHub
parent 87230cf3bf
commit bb07836231
2 changed files with 65 additions and 6 deletions

View File

@@ -63,11 +63,15 @@ export function parseSSEFrames(buffer: string): {
const frames: SSEFrame[] = []
let pos = 0
// SSE frames are delimited by double newlines
let idx: number
while ((idx = buffer.indexOf('\n\n', pos)) !== -1) {
const rawFrame = buffer.slice(pos, idx)
pos = idx + 2
// SSE frames are delimited by an empty line. Support LF and CRLF streams.
const frameDelimiter = /\r?\n\r?\n/g
frameDelimiter.lastIndex = pos
let delimiterMatch: RegExpExecArray | null
while ((delimiterMatch = frameDelimiter.exec(buffer)) !== null) {
const frameEnd = delimiterMatch.index
const rawFrame = buffer.slice(pos, frameEnd)
pos = frameEnd + delimiterMatch[0].length
// Skip empty frames
if (!rawFrame.trim()) continue
@@ -75,7 +79,13 @@ export function parseSSEFrames(buffer: string): {
const frame: SSEFrame = {}
let isComment = false
for (const line of rawFrame.split('\n')) {
for (const rawLine of rawFrame.split('\n')) {
// Normalize CRLF lines in mixed-line-ending streams.
const line =
rawLine[rawLine.length - 1] === '\r'
? rawLine.slice(0, -1)
: rawLine
if (line.startsWith(':')) {
// SSE comment (e.g., `:keepalive`)
isComment = true