Conversation
An NGINX that terminates TLS holds the whole event stream in its buffers with its default settings, so no push message reaches the browser at all. Atmosphere never sets X-Accel-Buffering, the header NGINX reads to turn buffering off for a single response, so Flow sets it on the push response itself. Checked against the scenarios in mcollovati/vaadin-reverse-proxy-tests: NGINX over HTTPS went from no push at all to a working stream, and Apache HTTPD over HTTP, AJP and HTTPS as well as NGINX over HTTP are unchanged.
Over HTTP/1.1 an open event stream occupies one of the six connections a browser allows per origin, so the sixth tab of the same application fails to load rather than only losing push. WebSocket is not affected.
Type of change
How to testA proxy is needed to see the difference, so this uses the scenario suite
For a check without a proxy, open Why TLS makes the differenceSame NGINX, same application, one variable at a time. The counter is ten
The last row is what this PR does, and it is the only one that does not ask NGINX logged the push request as Test coverage
Not covered by a unit test: that the header reaches the wire early enough to Reverse proxy resultsAll 44 scenarios of the suite, each driving Chromium over
The scenarios cover root and custom context paths, a custom servlet mapping, Worth noting for the AJP rows: those scenarios carry push over Two findings that are not fixed hereChanging the transport at runtime does not move an open connection. The Idle connections. Push survives a 75 s idle period on both proxies. On |
|
|
Could this be tested in flow-tests/vaadin-spring-tests/test-spring-boot-reverseproxy ? |
|
I'd avoid setting |



Follow-up to #24484
behavior deviation · flow-server · apps using the experimental
server-sent events push transport behind NGINX
Background — proxy response buffering. A reverse proxy normally
collects a response from the backend before passing it on, which is fine
for a response that ends but not for a stream that stays open. NGINX reads
X-Accel-Buffering: nofrom the backend and turns buffering off for thatone response.
With the server-sent events push transport, an application behind an NGINX
that terminates TLS never receives a push message and the view simply stops
updating. NGINX holds the whole stream in its buffers with its default
settings. Until now the only way out was a change to the proxy
configuration, which the application cannot make.
Risks:
header. NGINX consumes it, and other proxies ignore a header they do not
know.
session, no change to threading or to what is serialized.
Context. Atmosphere writes the content type and the cache headers for
an event stream itself but never sets
X-Accel-Buffering, and Flow added noheaders of its own on the push path, so nothing told NGINX to leave the
stream alone.
X-Accel-Buffering: noon server-sent events push responses, beforeAtmosphere writes anything, because the header cannot be added once the
response is committed.
so a proxy flushes it anyway, or are not HTTP responses at all.
X-Atmosphere-Transportquery parameterand falls back to the header of the same name, since the Flow client
sends it in the query string while an Atmosphere client may send a
header.
Transport.SERVER_SENT_EVENTSthat over HTTP/1.1 an openevent stream occupies one of the six connections a browser allows per
origin, so the sixth tab of the same application fails to load rather than
only losing push. HTTP/2 lifts the limit and WebSocket is not affected.
PushRequestHandlerTest, covering the transport in the queryparameter and in the header, and the transports that must be left alone.
Checked against the 44 reverse proxy scenarios in
https://github.com/mcollovati/vaadin-reverse-proxy-tests, driving a real
browser over all four transports. NGINX over HTTPS went from no push at all
to a stream that arrives tick by tick, and Apache HTTPD over HTTP, AJP and
HTTPS as well as NGINX over HTTP are unchanged. The per-scenario numbers are
in the first comment.