Problems with reverse proxied server sent events and compression #6293
Labels
bug 🐞
Something isn't working
discussion 💬
The right solution needs to be found
help wanted 🆘
Extra attention is needed
Affected version: 2.7.6, 2.8.0-beta.1
If the
encode
module is enabled and caddy is asked to reverse proxy a server sent event (SSE) endpoint, I noticed 2 problems:Problem 1:
If the upstream does not send a response body (just headers), which is perfectly valid by the way, caddy does not flush these headers to the client, so the SSE connection is not correctly established. #4247 seems to be very similar, and the reverse proxy module does the right thing, but because of #4314 (#4318) the encode module delays the flushing until the first bytes of response body are written. (oops my bad 😅). That means the SSE connection is only correctly established after the first write of the upstream (first event), which can be a while after the initial "handshake".
Possible solution:
Make an exception for the SSE Content-Type (
text/event-stream
) and don't wait for the first bytes, but just initialize the encoding ignoring theminimum_length
.Problem 2:
If the encode module actually decides to do compression on the SSE connection, the upstream flushing and flushing in the encode module (
FlushError
) afterward does not actually send the finished event message to the client.The reason for this is probably the window size of the compression algorithms. The bytes of the upstream are written to the encoder, but the Encoder has not actually written anything to the ResponseWriter (the thing the encoding module is flushing) and even if it has, the event message is likely incomplete because the compression frame was not full.
Possible solution:
Call
Flush()
on the encoder to make it finish its compression frame and write everything to the ResponseWriter which then can be flushed to the client.But I'm not sure about the above implementation.
Flush()
is called pretty frequently by caddy (especially withflush_interval -1
, which is the default) and this could make the compression less efficient when the compression frames are forced to finish before they actually filled up.curl
Calling curl (
-N
for streaming responses), see Debug Help below for info about the setup.No immediate Response because of Problem 1.
When the first event message from the upstream arrives:
Response headers (note the
Content-Encoding
) but no response body.Only if there is quite a lot of data coming from the upstream (commented out code on the small Go app below) a response arrives from caddy, but with the last event message incomplete.
Debugging help
Caddyfile (minimum length to force encoding)
Simple Go application for server sent events
The text was updated successfully, but these errors were encountered: