varnish (plus) http/2 and websockets, server sent events

Tom Anheyer | BerlinOnline Tom.Anheyer at berlinonline.de
Tue Jun 24 13:34:39 UTC 2025


Hello Guillaume,

You are right - it should work and :drumroll: it works!

I've enabled nearly all debug settings and see:

    327685 VCL_call       b BACKEND_RESPONSE
    327685 TTL            b VCL -1 3600 0 1750771561 uncacheable
    327685 TTL            b VCL -1 3600 300 1750771561 uncacheable
    327685 VCL_Log        b server_sent_events_vcl_backend_response
    327685 VCL_return     b pass
    327685 VCL_call       b VHA_INTERNAL
    327685 VCL_return     b ok
    327685 Timestamp      b Process: 1750771560.572744 0.837391 0.000332
    327685 BerespHeader   b Content-Encoding: gzip
    327685 BerespHeader   b Vary: Accept-Encoding
    327685 Storage        b mse s0
    327685 Fetch_Body     b 2 chunked stream
    327685 VCL_call       b BACKEND_RESPONSE
    327685 TTL            b VCL -1 3600 0 1750771561 uncacheable
    327685 TTL            b VCL -1 3600 300 1750771561 uncacheable
    327685 VCL_Log        b server_sent_events_vcl_backend_response
    327685 VCL_return     b pass
    327685 VCL_call       b VHA_INTERNAL
    327685 VCL_return     b ok
    327685 Timestamp      b Process: 1750771560.572744 0.837391 0.000332
    327685 BerespHeader   b Content-Encoding: gzip
    327685 BerespHeader   b Vary: Accept-Encoding
    327685 Storage        b mse s0
    327685 Fetch_Body     b 2 chunked stream

Varnishd is waiting for compressable bytes and stops the stream. I've added `set
beresp.do_gzip = false;` and it works. Current config looks like:

sub server_sent_events_vcl_recv {
    set req.backend_hint = server_sent_events.backend();
    unset req.http.Accept-Encoding;
    return(pass);
}

sub server_sent_events_vcl_backend_fetch {
    if (bereq.backend == server_sent_events.backend()) {
        std.log("server_sent_events_vcl_backend_fetch");
        set bereq.first_byte_timeout = 30s;
        set bereq.between_bytes_timeout = 30s;
    }
}

sub server_sent_events_vcl_backend_response {
    if (bereq.backend == server_sent_events.backend()) {
        if (beresp.http.content-type == "text/event-stream") {
            std.log("server_sent_events_vcl_backend_response");
            set beresp.do_esi = false;
            set beresp.do_gzip = false;
            set beresp.do_stream = true;
            return (pass);
        }
    }
}


Thank you
tom

Am Dienstag, dem 24.06.2025 um 09:46 +0200 schrieb Guillaume Quintard:
> Hi Tom,
> I have a hard time believing this doesn't work with pass, but let's check.
> Would you be able to run `varnishlig -g raw` as the transaction is going on ?
> (You don't want extra traffic otherwise things will be hard to follow)
> 
> -- 
> Guillaume Quintard
> 
> On Mon, Jun 23, 2025, 08:31 Tom Anheyer | BerlinOnline
> <Tom.Anheyer at berlinonline.de> wrote:
> > Good morning,
> > 
> > OK, one more. Server-Sent-Events are streaming GET requests. I've tried
> > 
> > sub vcl_recv {
> > 	…
> > 	return(pass);
> > }
> > 
> > sub vcl_backend_fetch {
> > 	set bereq.first_byte_timeout = 30s;
> > 	set bereq.between_bytes_timeout = 30s;
> > }
> > 
> > sub vcl_backend_response {
> > 	set beresp.do_esi = false;
> > 	set beresp.do_stream = true;
> > }
> > 
> > 
> > without success. The request is forwarded to the SSE server but comes never
> > back and does not show up in varnishlog. Is there any chance to get this
> > work without `pipe`? 
> > 
> > thanks in advance 
> > tom
> > 
> > Am Freitag, dem 20.06.2025 um 15:05 +0200 schrieb Guillaume Quintard:
> > > Always a pleasure! Let us know if you have any further questions!
> > > 
> > > -- 
> > > Guillaume Quintard
> > > 
> > > On Fri, Jun 20, 2025, 13:30 Tom Anheyer | BerlinOnline
> > > <Tom.Anheyer at berlinonline.de> wrote:
> > > > 
> > > > Hi Guillaume,
> > > > 
> > > > thank you for your very quick (as always) and clear answer.
> > > > 
> > > > tom
> > > > 
> > > > Am Freitag, dem 20.06.2025 um 11:37 +0200 schrieb Guillaume Quintard:
> > > > > Hi Tom,
> > > > > This is a base behavior, so Varnish Enterprise inherits it, but it's
> > > > present
> > > > > in Varnish Cache too.
> > > > > Piping involves foregoing HTTP parsing and just passing all the
> > > > connection
> > > > > bytes back and forth. It's possible on HTTP 1.x since there's only at
> > > > most one
> > > > > request per connection, but this breaks with HTTP2 multiplexing, so
> > > > Varnish
> > > > > does the best thing it can and uses a pass instead.
> > > > > Interestingly, H/2 didn't plan an upgrade path to websockets (or to
> > > > anything
> > > > > else, really) for a relatively sane reason: H/2 requires TLS and TLS
> > > > has ALPN
> > > > > that allows you to go to websockets directly, without the upgrade hop.
> > > > > So, to my (maybe outdated) knowledge of H/2, upgrading to websockets
> > > > isn't
> > > > > possible.
> > > > > Please let me know if I'm not being clear.
> > > > > -- 
> > > > > Guillaume Quintard
> > > > > 
> > > > > On Fri, Jun 20, 2025, 11:15 Tom Anheyer | BerlinOnline
> > > > > <Tom.Anheyer at berlinonline.de> wrote:
> > > > > > Hello,
> > > > > > 
> > > > > > I don't know if this is specific to varnish plus:
> > > > > > 
> > > > > > 
> > > > > > If I enable pipe-mode for server sent events in vcl_recv this way:
> > > > > > 
> > > > > > if (…) {
> > > > > >     set req.http.connection = "close";
> > > > > >     return(pipe);
> > > > > > }
> > > > > > 
> > > > > > the log shows:
> > > > > > 
> > > > > > -   VCL_return     pipe
> > > > > > -   VCL_call       HASH
> > > > > > -   VCL_return     lookup
> > > > > > -   VCL_Error      vcl_recv{} returns pipe/connect for HTTP/2
> > > > request. 
> > > > > > Doing pass.
> > > > > > -   VCL_call       PASS
> > > > > > 
> > > > > > 
> > > > > > Is it possible to use server sent events, websockets with http/2
> > > > requests?
> > > > > > 
> > > > > > 
> > > > > > I've opened a varnish software ticket but I thin [1]k that's public
> > > > interest.
> > > > > > 
> > > > > > tom  
> > > > > > 
> > > > 
> > 
> > 

-- 
Tom Anheyer
Senior Developer

BerlinOnline GmbH
Stefan-Heym-Platz 1
10367 Berlin
Germany

Tel.: +49-30-5771180-62
Fax: +49 30 5771180-95
E-Mail: tom.anheyer at berlinonline.de

berlin.de | berlinonline.net

Amtsgericht Berlin-Charlottenburg, HRB 266384
Sitz der Gesellschaft: Berlin, Deutschland
USt.-IdNr.: DE219483549

Geschäftsführung: Andreas Mängel, Katrin Dorgeist
Vorsitzender des Aufsichtsrats: Nicolas Zimmer



[1] pened a varnish software ticket but I thin
    https://www.google.com/maps/search/pened+a+varnish+software+ticket+but+I+thin?entry=gmail&source=g
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.varnish-cache.org/lists/pipermail/varnish-misc/attachments/20250624/30d3608d/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <https://www.varnish-cache.org/lists/pipermail/varnish-misc/attachments/20250624/30d3608d/attachment-0001.bin>


More information about the varnish-misc mailing list