Immich behind HTTP/2 reverse proxy supporting extended CONNECT fails to connect WebSocket in web UI at least in Firefox #31158
Closed
Domini
started this conversation in
Feature Request
Replies: 2 comments 5 replies
|
Moving to FR for now, as mentioned it’s not clear where/if there is an actual bug here and this is more of a data gathering stage. For now I would say Immich does not support this newer websocket setup. |
0 replies
|
It seems to me like the interaction/problem here is entirely between the browser and reverse proxy, and Immich isn't really involved in any way that we could do something about? |
5 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I have searched the existing issues, both open and closed, to make sure this is not a duplicate report.
The bug
There are two ways of WebSocket connection
Upgrade: websocketCONNECTfor HTTP/2Upgrade: websocketis explicitly disallowed for HTTP/2One can check if their reverse proxy supports extended
CONNECTfor HTTP/2 using e.g.nghttp -nv https://hostname | grep -F SETTINGS_ENABLE_CONNECT_PROTOCOLDifferent browsers work with reverse proxies supporting extended
CONNECTfor HTTP/2 differently. I haven't checked all of them, but so far the newest version ofUpgrade: websocketeven if the server supports extendedCONNECTand even if other, non-WebSocket connections to this server use HTTP/2 or HTTP/3 (I assume because Chrome has not yet implemented the support for extendedCONNECT, but I might be wrong)about:configsettingnetwork.http.http2.websockets- if disabled it leads to the same behaviour as ChromeCONNECT- the same behaviour as ChromeCONNECT- Firefox uses HTTP/2 for WebSocket connection but instead of using CONNECT method it sendsUpgrade: websocketheader which is explicitly against the RFC 8441.On one hand this kind of happens because of a race condition - the request data (including headers) can be sent to HTTP/2 connection before you get its
SETTINGSframe, so Firefox kind of does not know whether the server supports extendedCONNECTbefore it sendsUpgrade: websocket. On the other hand, when server supports HTTP/2 but does not support extendedCONNECT, Firefox somehow understands it needs to use HTTP/1.1 for WebSocket, so for some reason race condition no longer leads to an error. Also when it connects using HTTP/2, it knows thatUpgrade: websocketis against the standard in any case, but still sends it. So there is wrong behaviour for sure, the question is how it should be fixed. And no matter what, after failing once it should understand that the next time it should either reconnect via HTTP/1.1 if it wants to continue usingUpgrade: websocket, or use extendedCONNECTif it wants to continue using HTTP/2 - there is no race condition on the following attempt.As far as my investigation went, Immich uses socket.io, which uses browser native
websockets/wsimplementation, though I might be wrong. I'm not sure which layer should be responsible for fixing the error. As far as I understand the linked chain above, the error happens because the WebSocket implementation is not at all aware that HTTP/2 requires different WebSocket method as none of the layers have implemented HTTP/2 extendedCONNECTyet.Here comes the fuzzy part of the issue. My Immich is behind
envoyreverse proxy which is very strict in following the standards - it responds with400 Bad Requestwithout even proxying the request to Immich. All the WebSocket connections from Immich fail. (For anyone encountering the same issue, temporary workaround is to disable extendedCONNECT(http2_protocol_options.allow_connect=false) at least for the/api/socket.io/prefix - Firefox will start using HTTP/1.1 for Immich WebSocket connections and continue using HTTP/2 for the rest.)I understand that
envoyis not a supported configuration for Immich (there is no example forenvoyin the docs), but setting up another reverse proxy just to check whether the behaviour is the same is too much work.Also, as far as I understand,
nginxhas just recently implemented extendedCONNECT(not yet merged), so the problem might appear soon out of nowhere as the fleet ofnginxs is auto-updated even if there is no problem now. As far as I understand, at the momentnginxwill simply respond withSETTINGS_ENABLE_CONNECT_PROTOCOL=0and everything will work - not because browser works better withnginx, but rather becausenginxdoes not support the technology that leads to the wrong behaviour.I don't know about Apache and Caddy.
If you have an
nginx, Apache, Caddy or other reverse proxy HTTP/2-enabled configuration, could you check whatnghttp -nv https://hostname | grep -F SETTINGS_ENABLE_CONNECT_PROTOCOLsays, and if it'sSETTINGS_ENABLE_CONNECT_PROTOCOL=1whether Immich web UI WebSockets work in Firefox.The OS that Immich Server is running on
Fedora CoreOS stable latest (based on Fedora 44 so pretty bleeding edge)
Firefox 154.0 on macOS Sequoia 15.7.9
Version of Immich Server
v3.1.0
Version of Immich Mobile App
Platform with the issue
Device make and model
No response
Your docker-compose.yml content
Your .env content
Reproduction steps
CONNECTRelevant log output
Additional information
This might not be immediately fixable issue, but I think it's worth having it open to track the issue if encountered by others or in different configurations.
All reactions