# HG changeset patch # User Homutov Vladimir # Date 1362036028 -14400 # Node ID 0ed4c093c026669be2f4babe69f3f6bd9d946eec # Parent 7a270b2e6ee3e8535b4e7deaa30459c0b195f948 WebSocket proxying howto. diff --git a/xml/en/GNUmakefile b/xml/en/GNUmakefile --- 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 \ diff --git a/xml/en/docs/http/ngx_http_proxy_module.xml b/xml/en/docs/http/ngx_http_proxy_module.xml --- a/xml/en/docs/http/ngx_http_proxy_module.xml +++ b/xml/en/docs/http/ngx_http_proxy_module.xml @@ -10,7 +10,7 @@ + rev="9">
@@ -1019,6 +1019,11 @@ and if not found is determined using a . + +WebSocket proxying requires special +configuration and is supported since version 1.3.13. + + diff --git a/xml/en/docs/http/websocket.xml b/xml/en/docs/http/websocket.xml new file mode 100644 --- /dev/null +++ b/xml/en/docs/http/websocket.xml @@ -0,0 +1,82 @@ + + + + +
+ + +
+ + +To turn a connection between a client and server from HTTP/1.1 into WebSocket, +the protocol +switch mechanism available in HTTP/1.1 is used. + + + +There is one subtlety however: since the
Upgrade
is a +hop-by-hop +header, it is not passed from a client to proxied server. +With forward proxying, clients may use the 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 to set up a tunnel between a client and proxied +server if the proxied server returned a response with the code +, +and the client asked for a protocol switch via the
Upgrade
+header in a request. +
+ + +As noted above, hop-by-hop headers including
Upgrade
+and
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
Connection
header field +in a request to the proxied server depends on the presence of +the
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; + } + } + +
+ +
+ +
diff --git a/xml/en/docs/index.xml b/xml/en/docs/index.xml --- a/xml/en/docs/index.xml +++ b/xml/en/docs/index.xml @@ -8,7 +8,7 @@
@@ -73,6 +73,10 @@ + + + + diff --git a/xml/ru/GNUmakefile b/xml/ru/GNUmakefile --- 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 \ diff --git a/xml/ru/docs/http/ngx_http_proxy_module.xml b/xml/ru/docs/http/ngx_http_proxy_module.xml --- a/xml/ru/docs/http/ngx_http_proxy_module.xml +++ b/xml/ru/docs/http/ngx_http_proxy_module.xml @@ -10,7 +10,7 @@ + rev="9">
@@ -1017,6 +1017,11 @@ proxy_pass $request; ’а. + +Проксирование WebSocket требует особой +настройки и поддерживается начиная с версии 1.3.13. + + diff --git a/xml/ru/docs/http/websocket.xml b/xml/ru/docs/http/websocket.xml new file mode 100644 --- /dev/null +++ b/xml/ru/docs/http/websocket.xml @@ -0,0 +1,83 @@ + + + + +
+ + +
+ + +Для превращения соединения между клиентом и сервером из HTTP/1.1 в WebSocket +используется доступный в HTTP/1.1 механизм +смены +протокола. + + + +Но есть сложность: поскольку
Upgrade
является +hop-by-hop +заголовком, то он не передаётся от клиента к проксируемому серверу. +При прямом проксировании клиенты могут использовать метод +CONNECT, чтобы обойти эту проблему. +Однако при обратном проксировании такой подход не работает, +так как клиент ничего о проксирующем сервере не знает, +и требуется специальная обработка на проксирующем сервере. +
+ + +Начиная с версии 1.3.13, +в nginx предусмотрен особый режим работы, +который позволяет установить туннель между клиентом и проксируемым +сервером, если проксируемый сервер вернул ответ с кодом +, +и клиент попросил сменить протокол с помощью заголовка +
Upgrade
в запросе. +
+ + +Как уже отмечалось выше, hop-by-hop заголовки, включая
Upgrade
Connection
, не передаются от клиента к проксируемому +серверу, поэтому, для того чтобы проксируемый сервер узнал о +намерении клиента сменить протокол на WebSocket, эти заголовки следует +передать явно: + +location /chat/ { + proxy_pass http://backend; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; +} + +Более сложный пример, +в котором значение поля
Connection
+в заголовке запроса к проксируемому серверу зависит от наличия поля +
Upgrade
в заголовке запроса клиента: + +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; + } + } + +
+ +
+ +
diff --git a/xml/ru/docs/index.xml b/xml/ru/docs/index.xml --- a/xml/ru/docs/index.xml +++ b/xml/ru/docs/index.xml @@ -8,7 +8,7 @@
@@ -71,6 +71,21 @@
+
+ + + + + + + + + + + +
+ +