=encoding utf-8


=head1 Name


websocket - WebSocket proxying


=head1



To turn a connection between a client and server from HTTPE<sol>1.1 into WebSocket,
the L<protocol
switch|https://tools.ietf.org/html/rfc2616#section-14.42> mechanism available in HTTPE<sol>1.1 is used.





There is one subtlety however: since the C<Upgrade> is a
L<hop-by-hop|https://tools.ietf.org/html/rfc2616#section-13.5.1>
header, it is not passed from a client to proxied server.
With forward proxying, clients may use the C<CONNECT>
method to circumvent this issue.
This does not work with reverse proxying however,
since clients are not aware of any proxy servers,
and special processing on a proxy server is required.





Since version 1.3.13,
nginx implements special mode of operation
that allows setting up a tunnel between a client and proxied
server if the proxied server returned a response with the code
C<101> (C<Switching Protocols>),
and the client asked for a protocol switch via the C<Upgrade>
header in a request.





As noted above, hop-by-hop headers including C<Upgrade>
and C<Connection> are not passed from a client to proxied
server, therefore in order for the proxied server to know about the client’s
intention to switch a protocol to WebSocket, these headers have to be
passed explicitly:

    
    location /chat/ {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }


A more sophisticated example
in which a value of the C<Connection> header field
in a request to the proxied server depends on the presence of
the C<Upgrade> field in the client request header:

    
    http {
        map $http_upgrade $connection_upgrade {
            default upgrade;
            ''      close;
        }
    
        server {
            ...
    
            location /chat/ {
                proxy_pass http://backend;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
            }
        }







By default, the connection will be closed
if the proxied server does not transmit any data within 60 seconds.
This timeout can be increased with the
L<ngx_http_proxy_module> directive.
Alternatively, the proxied server can be configured
to periodically send WebSocket ping frames to reset the timeout
and check if the connection is still alive.




