tower-rs / tower-http

HTTP specific Tower utilities.
680 stars 159 forks source link

CompressionLayer causes event streams to buffer, breaking them #420

Closed ekzhang closed 6 months ago

ekzhang commented 11 months ago

Bug Report

When using Server-Sent Events (SSE), a streaming body is sent in real time with type text/event-stream. This is a standard MIME type for many websites, such as notification feeds, or streaming chat completion APIs.

However, if you apply the default CompressionLayer on a site with SSE, it will cause all of the server-sent events to buffer until reaching a given size, before they are able to reach the HTTP client.

I straced a server running hyper over HTTP/1.1, with an event stream outputting messages every 1 second, and it does still write chunks of data to the socket every second. However, the web browser (as well as curl --no-buffer --compressed) is not able to decode the messages individually.

I also confirmed this behavior with other streaming middleware implementations, such as FastAPI's GZipMiddleware. It seems that compression encoding generally doesn't work nicely with text/event-stream.

Version

0.4.4

Platform

Linux ip-172-31-47-18 5.15.0-1045-aws #50~20.04.1-Ubuntu SMP Wed Sep 6 17:29:11 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

Crates

compression module with compression-gzip feature

Description

I wanted to ask if it's possible to include

NotForContentType::const_new("text/event-stream")

in the DefaultPredicate for tower_http::compression::CompressionLayer. This would reduce the chance of an issue like this happening for application developers, who commonly use SSE for live event feeds.

Thank you so much for your work on this library.

BenJeau commented 7 months ago

Addressed as part of https://github.com/tower-rs/tower-http/pull/465

jplatte commented 6 months ago

And shippped in 0.5.3.