view xml/en/docs/http/websocket.xml @ 3011:55d49eb065ac

Fixed example in the js_periodic directive.
author Yaroslav Zhuravlev <yar@nginx.com>
date Thu, 14 Sep 2023 16:38:00 +0100
parents 4add6ae1296f
children
line wrap: on
line source

<!--
  Copyright (C) Nginx, Inc.
  -->

<!DOCTYPE article SYSTEM "../../../../dtd/article.dtd">

<article name="WebSocket proxying"
         link="/en/docs/http/websocket.html"
         lang="en"
         rev="4">


<section>

<para>
To turn a connection between a client and server from HTTP/1.1 into WebSocket,
the <link url="https://datatracker.ietf.org/doc/html/rfc2616#section-14.42">protocol
switch</link> mechanism available in HTTP/1.1 is used.
</para>

<para>
There is one subtlety however: since the <header>Upgrade</header> is a
<link url="https://datatracker.ietf.org/doc/html/rfc2616#section-13.5.1">hop-by-hop</link>
header, it is not passed from a client to proxied server.
With forward proxying, clients may use the <literal>CONNECT</literal>
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.
</para>

<para>
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
<http-status code="101" text="Switching Protocols"/>,
and the client asked for a protocol switch via the <header>Upgrade</header>
header in a request.
</para>

<para>
As noted above, hop-by-hop headers including <header>Upgrade</header>
and <header>Connection</header> 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:
<programlisting>
location /chat/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}
</programlisting>
A more sophisticated example
in which a value of the <header>Connection</header> header field
in a request to the proxied server depends on the presence of
the <header>Upgrade</header> field in the client request header:
<programlisting>
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;
        }
    }
</programlisting>
</para>

<para>
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
<link doc="ngx_http_proxy_module.xml" id="proxy_read_timeout"/> 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.
</para>

</section>

</article>