Fix event stream line parsing to handle CRLF and empty lines correctly (#89)

* Optimized code in `connectToEventStream` to use `.lines` computed value of `AsyncSequence` to produce a `AsyncLineSequence` instead of building a lines manually.

* - Reverter use of `lines` (it swallows newlines)
- Fiexed original issue I experienced with line 229 `while let newlineIndex = buffer.firstIndex(of: "\n") {` not handling "\r\n" properly
- Added unit test to test for "\r\n" scenario
- Simplified `end of event` test - `line` creation trims newline, added code trims carriage return. Only thing that should be left is an empty line
This commit is contained in:
Ayal Spitz 2025-04-27 09:50:08 -04:00 • committed by GitHub
commit f6e401aa97
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -226,12 +226,16 @@ public actor HTTPClientTransport: Actor, Transport {
buffer.append(char)
// Process complete lines
while let newlineIndex = buffer.firstIndex(of: "\n") {
let line = buffer[..<newlineIndex]
while let newlineIndex = buffer.utf8.firstIndex(where: { $0 == 10 }) {
var line = buffer[..<newlineIndex]
if line.hasSuffix("\r") {
line = line.dropLast()
}
buffer = String(buffer[buffer.index(after: newlineIndex)...])
// Empty line marks the end of an event
if line.isEmpty || line == "\r" || line == "\n" || line == "\r\n" {
if line.isEmpty {
if !eventData.isEmpty {
// Process the event
if eventType == "id" {
@ -256,6 +260,10 @@ public actor HTTPClientTransport: Actor, Transport {
continue
}
if line.hasSuffix("\r") {
line = line.dropLast()
}
// Lines starting with ":" are comments
if line.hasPrefix(":") { continue }