Для превращения соединения между клиентом и сервером из HTTP/1.1 в WebSocket
используется доступный в HTTP/1.1 механизм
смены
протокола.
Но есть сложность: поскольку “Upgrade” является
hop-by-hop
заголовком, то он не передаётся от клиента к проксируемому серверу.
При прямом проксировании клиенты могут использовать метод
CONNECT , чтобы обойти эту проблему.
Однако при обратном проксировании такой подход не работает,
так как клиент ничего о проксирующем сервере не знает,
и требуется специальная обработка на проксирующем сервере.
Начиная с версии 1.3.13,
в nginx предусмотрен особый режим работы,
который позволяет установить туннель между клиентом и проксируемым
сервером, если проксируемый сервер вернул ответ с кодом
101 (Switching Protocols),
и клиент попросил сменить протокол с помощью заголовка
“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;
}
}
|