tokio-rs / axum

Ergonomic and modular web framework built with Tokio, Tower, and Hyper

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

transfer-encoding: chunked being added to SSE responses, which are not chunked

cbiffle opened this issue · comments

  • I have looked for existing issues (including closed) about this

Bug Report

Version

├── axum v0.7.4
│   ├── axum-core v0.4.3
├── axum-extra v0.9.2
│   ├── axum v0.7.4 (*)
│   ├── axum-core v0.4.3 (*)

Platform

Linux.

Description

Something (I suspect hyper) is adding a transfer-encoding: chunked header to responses generated using Axum's Sse type. As far as I can tell, the SSE responses are not being generated with chunked encoding, but rather raw SSE-style newline-delimited blocks. (chunked would normally imply a chunk size followed by a \r\n-delimited block, as far as I recall.)

Chromium tolerates this. Firefox mostly tolerates it, but it appears to break the display of event streams in the devtools, from what I can tell. This is how I noticed it.

You can verify this using the sse example:

$ cargo run -p example-sse

and then from another terminal,

$ curl --trace-ascii - http://localhost:3000/sse
== Info: Host localhost:3000 was resolved.
== Info: IPv6: ::1
== Info: IPv4: 127.0.0.1
== Info:   Trying [::1]:3000...
== Info: connect to ::1 port 3000 from ::1 port 33356 failed: Connection refused
== Info:   Trying 127.0.0.1:3000...
== Info: Connected to localhost (127.0.0.1) port 3000
=> Send header, 80 bytes (0x50)
0000: GET /sse HTTP/1.1
0013: Host: localhost:3000
0029: User-Agent: curl/8.5.0
0041: Accept: */*
004e: 
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 33 bytes (0x21)
0000: content-type: text/event-stream
<= Recv header, 25 bytes (0x19)
0000: cache-control: no-cache
<= Recv header, 28 bytes (0x1c)
0000: transfer-encoding: chunked     <----- HEADER
<= Recv header, 37 bytes (0x25)
0000: date: Thu, 15 Feb 2024 21:58:35 GMT
<= Recv header, 2 bytes (0x2)
0000: 
<= Recv data, 11 bytes (0xb)
0000: data: hi!..        <----- NOT CHUNKED
data: hi!

The data there is definitely raw rather than chunked.

I'm filing this here because I'm not totally sure how the components interact -- is there e.g. a trait impl for Sse in Axum that I could adjust to stop this, or would I need to climb down into hyper? Happy to help but I'd need to be pointed at a starting point.

Sorry if I've missed something, thanks in advance.

same