소스 검색

Ignore a leading UTF-8 BOM in an SSE stream

The SSE spec strips one BOM at the start of the stream, but
SSEClient kept it as part of the first field name, so the
first event was silently dropped.
yhirose 2 일 전
부모
커밋
fee592c2c2
2개의 변경된 파일과 17개의 추가작업 그리고 0개의 파일을 삭제
  1. 7 0
      httplib.h
  2. 10 0
      test/test.cc

+ 7 - 0
httplib.h

@@ -4993,6 +4993,7 @@ inline void SSEClient::run_event_loop() {
     SSEMessage current_msg;
     auto has_data = false;
     auto has_id = false;
+    auto first_line = true;
 
     while (running_.load() && result.next()) {
       buffer.append(result.data(), result.size());
@@ -5010,6 +5011,12 @@ inline void SSEClient::run_event_loop() {
         // one without a colon, sees the same line
         if (!line.empty() && line.back() == '\r') { line.pop_back(); }
 
+        // A UTF-8 BOM at the start of the stream is ignored per the SSE spec
+        if (first_line) {
+          first_line = false;
+          if (line.compare(0, 3, "\xEF\xBB\xBF") == 0) { line.erase(0, 3); }
+        }
+
         // Parse the line and check if event is complete
         auto event_complete = parse_sse_line(
             line, current_msg, reconnect_interval_ms_, has_data, has_id);

+ 10 - 0
test/test.cc

@@ -22793,6 +22793,16 @@ TEST_F(SSEParsingTest, FieldNameOnlyWithCarriageReturn) {
   EXPECT_EQ(msgs[0].data, "");
 }
 
+TEST_F(SSEParsingTest, LeadingByteOrderMarkIgnored) {
+  // Only a BOM at the start of the stream is ignored
+  auto msgs = parse("\xEF\xBB\xBF"
+                    "data: first\n\n"
+                    "\xEF\xBB\xBF"
+                    "data: second\n\n");
+  ASSERT_EQ(msgs.size(), 1u);
+  EXPECT_EQ(msgs[0].data, "first");
+}
+
 TEST_F(SSEParsingTest, UnknownFieldsIgnored) {
   auto msgs = parse("unknown: value\ndata: hello\n\n");
   ASSERT_EQ(msgs.size(), 1u);