From e632139b5eef0b071f43f5ac6891f4a54f5a4d91 Mon Sep 17 00:00:00 2001 From: ttyS3 Date: Fri, 4 Aug 2023 11:17:35 +0800 Subject: [PATCH 1/2] chore(sse): add space between field and value for compatibility according to https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation using `field: value` style is OK. > Collect the characters on the line after the first U+003A COLON character (:), and let value be that string. If value starts with a U+0020 SPACE character, remove it from value. other client side tools may detect the `data` field rely on the space, like this one https://github.com/openai/openai-python/blob/b82a3f7e4c462a8a10fa445193301a3cefef9a4a/openai/api_requestor.py#L106 and this one: https://github.com/sashabaranov/go-openai/blob/71a24931dbc5b7029901ff963dc4d0d2509aa7ed/stream_reader.go#L14 --- axum/src/response/sse.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/axum/src/response/sse.rs b/axum/src/response/sse.rs index 679e03d1bf..ad3d38a191 100644 --- a/axum/src/response/sse.rs +++ b/axum/src/response/sse.rs @@ -171,9 +171,9 @@ pub struct Event { } impl Event { - /// Set the event's data data field(s) (`data:`) + /// Set the event's data data field(s) (`data: `) /// - /// Newlines in `data` will automatically be broken across `data:` fields. + /// Newlines in `data` will automatically be broken across `data: ` fields. /// /// This corresponds to [`MessageEvent`'s data field]. /// @@ -202,7 +202,7 @@ impl Event { self } - /// Set the event's data field to a value serialized as unformatted JSON (`data:`). + /// Set the event's data field to a value serialized as unformatted JSON (`data: `). /// /// This corresponds to [`MessageEvent`'s data field]. /// @@ -220,7 +220,7 @@ impl Event { panic!("Called `EventBuilder::json_data` multiple times"); } - self.buffer.extend_from_slice(b"data:"); + self.buffer.extend_from_slice(b"data: "); serde_json::to_writer((&mut self.buffer).writer(), &data).map_err(axum_core::Error::new)?; self.buffer.put_u8(b'\n'); @@ -358,10 +358,7 @@ impl Event { ); self.buffer.extend_from_slice(name.as_bytes()); self.buffer.put_u8(b':'); - // Prevent values that start with spaces having that space stripped - if value.starts_with(b" ") { - self.buffer.put_u8(b' '); - } + self.buffer.put_u8(b' '); self.buffer.extend_from_slice(value); self.buffer.put_u8(b'\n'); } @@ -538,7 +535,7 @@ mod tests { #[test] fn leading_space_is_not_stripped() { let no_leading_space = Event::default().data("\tfoobar"); - assert_eq!(&*no_leading_space.finalize(), b"data:\tfoobar\n\n"); + assert_eq!(&*no_leading_space.finalize(), b"data: \tfoobar\n\n"); let leading_space = Event::default().data(" foobar"); assert_eq!(&*leading_space.finalize(), b"data: foobar\n\n"); From 14bdd74e453d464d3250a8641dac0841b0916c46 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Sat, 16 Sep 2023 21:35:49 +0200 Subject: [PATCH 2/2] changelog --- axum/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md index 6f3d9e6b63..4cb60f6717 100644 --- a/axum/CHANGELOG.md +++ b/axum/CHANGELOG.md @@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **change:** axum's MSRV is now 1.63 ([#2021]) - **added:** Implement `Handler` for `T: IntoResponse` ([#2140]) - **added:** Implement `IntoResponse` for `(R,) where R: IntoResponse` ([#2143]) +- **changed:** For SSE, add space between field and value for compatibility ([#2149]) [#2021]: https://github.com/tokio-rs/axum/pull/2021 [#2014]: https://github.com/tokio-rs/axum/pull/2014 @@ -82,6 +83,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#2096]: https://github.com/tokio-rs/axum/pull/2096 [#2140]: https://github.com/tokio-rs/axum/pull/2140 [#2143]: https://github.com/tokio-rs/axum/pull/2143 +[#2149]: https://github.com/tokio-rs/axum/pull/2149 # 0.6.17 (25. April, 2023)