Mercurial > hg > nginx-site
changeset 849:0ed4c093c026
WebSocket proxying howto.
author | Homutov Vladimir <vl@nginx.com> |
---|---|
date | Thu, 28 Feb 2013 11:20:28 +0400 |
parents | 7a270b2e6ee3 |
children | 1026f41db4f9 |
files | xml/en/GNUmakefile xml/en/docs/http/ngx_http_proxy_module.xml xml/en/docs/http/websocket.xml xml/en/docs/index.xml xml/ru/GNUmakefile xml/ru/docs/http/ngx_http_proxy_module.xml xml/ru/docs/http/websocket.xml xml/ru/docs/index.xml |
diffstat | 8 files changed, 200 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/xml/en/GNUmakefile +++ b/xml/en/GNUmakefile @@ -12,6 +12,7 @@ DOCS = \ http/configuring_https_servers \ debugging_log \ http/converting_rewrite_rules \ + http/websocket \ howto_build_on_win32 \ freebsd_tuning \ howto_setup_development_environment_on_ec2 \
--- a/xml/en/docs/http/ngx_http_proxy_module.xml +++ b/xml/en/docs/http/ngx_http_proxy_module.xml @@ -10,7 +10,7 @@ <module name="Module ngx_http_proxy_module" link="/en/docs/http/ngx_http_proxy_module.html" lang="en" - rev="8"> + rev="9"> <section id="summary"> @@ -1019,6 +1019,11 @@ and if not found is determined using a <link doc="ngx_http_core_module.xml" id="resolver"/>. </para> +<para> +<link doc="websocket.xml">WebSocket</link> proxying requires special +configuration and is supported since version 1.3.13. +</para> + </directive>
new file mode 100644 --- /dev/null +++ b/xml/en/docs/http/websocket.xml @@ -0,0 +1,82 @@ +<!-- + Copyright (C) Nginx, Inc. + --> + +<!DOCTYPE article SYSTEM "../../../../dtd/article.dtd"> + +<article name="WebSocket proxying" + link="/en/docs/http/websocket.html" + lang="en" + rev="1"> + + +<section> + +<para> +To turn a connection between a client and server from HTTP/1.1 into WebSocket, +the <link url="http://tools.ietf.org/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="http://tools.ietf.org/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 to set 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> + +</section> + +</article>
--- a/xml/en/docs/index.xml +++ b/xml/en/docs/index.xml @@ -8,7 +8,7 @@ <article name="nginx documentation" link="/en/docs/" lang="en" - rev="3" + rev="4" toc="no"> @@ -73,6 +73,10 @@ </listitem> <listitem> +<link doc="http/websocket.xml"/> +</listitem> + +<listitem> <link doc="howto_build_on_win32.xml"/> </listitem>
--- a/xml/ru/GNUmakefile +++ b/xml/ru/GNUmakefile @@ -13,6 +13,7 @@ DOCS = \ http/server_names \ http/configuring_https_servers \ debugging_log \ + http/websocket \ FAQ = \ sys_errlist \
--- a/xml/ru/docs/http/ngx_http_proxy_module.xml +++ b/xml/ru/docs/http/ngx_http_proxy_module.xml @@ -10,7 +10,7 @@ <module name="Модуль ngx_http_proxy_module" link="/ru/docs/http/ngx_http_proxy_module.html" lang="ru" - rev="8"> + rev="9"> <section id="summary"> @@ -1017,6 +1017,11 @@ proxy_pass $request; <link doc="ngx_http_core_module.xml" id="resolver"/>’а. </para> +<para> +Проксирование <link doc="websocket.xml">WebSocket</link> требует особой +настройки и поддерживается начиная с версии 1.3.13. +</para> + </directive>
new file mode 100644 --- /dev/null +++ b/xml/ru/docs/http/websocket.xml @@ -0,0 +1,83 @@ +<!-- + Copyright (C) Nginx, Inc. + --> + +<!DOCTYPE article SYSTEM "../../../../dtd/article.dtd"> + +<article name="Проксирование WebSocket" + link="/ru/docs/http/websocket.html" + lang="ru" + rev="1"> + + +<section> + +<para> +Для превращения соединения между клиентом и сервером из HTTP/1.1 в WebSocket +используется доступный в HTTP/1.1 механизм +<link url="http://tools.ietf.org/html/rfc2616#section-14.42">смены +протокола</link>. +</para> + +<para> +Но есть сложность: поскольку <header>Upgrade</header> является +<link url="http://tools.ietf.org/html/rfc2616#section-13.5.1">hop-by-hop</link> +заголовком, то он не передаётся от клиента к проксируемому серверу. +При прямом проксировании клиенты могут использовать метод +<literal>CONNECT</literal>, чтобы обойти эту проблему. +Однако при обратном проксировании такой подход не работает, +так как клиент ничего о проксирующем сервере не знает, +и требуется специальная обработка на проксирующем сервере. +</para> + +<para> +Начиная с версии 1.3.13, +в nginx предусмотрен особый режим работы, +который позволяет установить туннель между клиентом и проксируемым +сервером, если проксируемый сервер вернул ответ с кодом +<http-status code="101" text="Switching Protocols"/>, +и клиент попросил сменить протокол с помощью заголовка +<header>Upgrade</header> в запросе. +</para> + +<para> +Как уже отмечалось выше, hop-by-hop заголовки, включая <header>Upgrade</header> +и <header>Connection</header>, не передаются от клиента к проксируемому +серверу, поэтому, для того чтобы проксируемый сервер узнал о +намерении клиента сменить протокол на WebSocket, эти заголовки следует +передать явно: +<programlisting> +location /chat/ { + proxy_pass http://backend; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; +} +</programlisting> +Более сложный пример, +в котором значение поля <header>Connection</header> +в заголовке запроса к проксируемому серверу зависит от наличия поля +<header>Upgrade</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> + +</section> + +</article>
--- a/xml/ru/docs/index.xml +++ b/xml/ru/docs/index.xml @@ -8,7 +8,7 @@ <article name="nginx: документация" link="/ru/docs/" lang="ru" - rev="3" + rev="4" toc="no"> @@ -71,6 +71,21 @@ </section> +<section id="howto" name="How-To"> + +<para> +<list type="bullet"> + +<listitem> +<link doc="http/websocket.xml"/> +</listitem> + +</list> +</para> + +</section> + + <section name="Справочник по модулям"> <para>