izstas
izstas

Reputation: 5064

Nginx: Reverse proxying WebSocket Draft 76

I'm using nginx 1.4.0 and it deals perfectly fine with newer WebSocket versions, but Draft 76 is a problem. My backend (Netty-based Java application) doesn't seem to receive the handshake request, and in nginx's error log I have

[error] 7662#0: *3720 upstream timed out (110: Connection timed out) while reading response header from upstream

My configuration ($proxy_add_connection works the same way as described there)

include proxy_params;
proxy_pass http://127.0.0.1:8001/;
proxy_http_version 1.1;
proxy_set_header Connection $proxy_add_connection;
proxy_set_header Upgrade $http_upgrade;

If I connect directly to the backend, it works fine.

Is there anything I can do to fix it?

Upvotes: 1

Views: 966

Answers (1)

zaphoyd
zaphoyd

Reputation: 2740

The recent changes to Nginx to support WebSocket proxying don't support WebSockets per se, but rather allow it to recognize a request to upgrade the connection from HTTP to another protocol. When it gets such a request it now establishes a tunnel to the backend rather than dropping the connection as invalid. The RFC6455 WebSocket handshake is a standard HTTP protocol upgrade request and as such it works with this new capability.

The draft 76/00 WebSocket handshake was designed specifically to break intermediaries that did not explicitly support WebSockets. As all that Nginx is doing is proxying the upgraded TCP connection, it doesn't actually understand the WebSocket handshake or what protocol version of WebSocket is being used. As such it has no way to perform the non-HTTP adjustments that the draft 76/00 handshake require.

To support draft 76/00 versions of WebSocket Nginx would have to implement special draft 76/00 detection and handling logic. Given the complexity of adding non-HTTP logic and the unfinished quality and questionable security of draft 76/00 it is unlikely that proxy intermediaries will ever support it.

If your users absolutely depend on 2-3 year old versions of Chrome/Safari, Flash fallback or raw TCP load balancing is likely your best bet.

Upvotes: 3

Related Questions