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>