kunchenguid--no-mistakes
26f897c1ec
release / release-please (push) Failing after 1m49s
docs / build (push) Failing after 6m34s
release / build-and-upload (arm64, linux) (push) Has been cancelled
release / build-and-upload (arm64, windows) (push) Has been cancelled
release / build-darwin (amd64, darwin) (push) Has been cancelled
release / checksums (push) Has been cancelled
release / finalize (push) Has been cancelled
release / build-darwin (arm64, darwin) (push) Has been cancelled
release / build-and-upload (amd64, linux) (push) Has been cancelled
release / build-and-upload (amd64, windows) (push) Has been cancelled
docs / deploy (push) Has been cancelled
61 行
1.4 KiB
Go
61 行
1.4 KiB
Go
package agent
|
|
|
|
import (
|
|
"bufio"
|
|
"io"
|
|
"strings"
|
|
)
|
|
|
|
// sseEvent represents a parsed Server-Sent Event.
|
|
type sseEvent struct {
|
|
Name string // event: field (empty if not specified)
|
|
Data string // concatenated data: fields
|
|
}
|
|
|
|
// parseSSE reads SSE events from a reader and sends them to the handler.
|
|
// It handles multi-line data fields and both \n\n and \r\n\r\n separators.
|
|
// Stops when the reader is exhausted or the handler returns false.
|
|
func parseSSE(r io.Reader, handler func(sseEvent) bool) error {
|
|
scanner := bufio.NewScanner(r)
|
|
scanner.Buffer(make([]byte, 0, 64*1024), 256*1024*1024)
|
|
var name string
|
|
var dataLines []string
|
|
|
|
flush := func() bool {
|
|
if len(dataLines) == 0 && name == "" {
|
|
return true
|
|
}
|
|
data := strings.Join(dataLines, "\n")
|
|
cont := handler(sseEvent{Name: name, Data: data})
|
|
name = ""
|
|
dataLines = nil
|
|
return cont
|
|
}
|
|
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
// Trim trailing \r for \r\n line endings
|
|
line = strings.TrimRight(line, "\r")
|
|
|
|
if line == "" {
|
|
// Empty line = event boundary
|
|
if !flush() {
|
|
return nil
|
|
}
|
|
continue
|
|
}
|
|
|
|
if strings.HasPrefix(line, "event:") {
|
|
name = strings.TrimPrefix(line[6:], " ")
|
|
} else if strings.HasPrefix(line, "data:") {
|
|
dataLines = append(dataLines, strings.TrimPrefix(line[5:], " "))
|
|
}
|
|
// Ignore other fields (id:, retry:, comments)
|
|
}
|
|
|
|
// Flush any trailing event without final newline
|
|
flush()
|
|
|
|
return scanner.Err()
|
|
}
|