849
|
1 <!--
|
|
2 Copyright (C) Nginx, Inc.
|
|
3 -->
|
|
4
|
|
5 <!DOCTYPE article SYSTEM "../../../../dtd/article.dtd">
|
|
6
|
|
7 <article name="Проксирование WebSocket"
|
|
8 link="/ru/docs/http/websocket.html"
|
|
9 lang="ru"
|
|
10 rev="1">
|
|
11
|
|
12
|
|
13 <section>
|
|
14
|
|
15 <para>
|
|
16 Для превращения соединения между клиентом и сервером из HTTP/1.1 в WebSocket
|
|
17 используется доступный в HTTP/1.1 механизм
|
|
18 <link url="http://tools.ietf.org/html/rfc2616#section-14.42">смены
|
|
19 протокола</link>.
|
|
20 </para>
|
|
21
|
|
22 <para>
|
|
23 Но есть сложность: поскольку <header>Upgrade</header> является
|
|
24 <link url="http://tools.ietf.org/html/rfc2616#section-13.5.1">hop-by-hop</link>
|
|
25 заголовком, то он не передаётся от клиента к проксируемому серверу.
|
|
26 При прямом проксировании клиенты могут использовать метод
|
|
27 <literal>CONNECT</literal>, чтобы обойти эту проблему.
|
|
28 Однако при обратном проксировании такой подход не работает,
|
|
29 так как клиент ничего о проксирующем сервере не знает,
|
|
30 и требуется специальная обработка на проксирующем сервере.
|
|
31 </para>
|
|
32
|
|
33 <para>
|
|
34 Начиная с версии 1.3.13,
|
|
35 в nginx предусмотрен особый режим работы,
|
|
36 который позволяет установить туннель между клиентом и проксируемым
|
|
37 сервером, если проксируемый сервер вернул ответ с кодом
|
|
38 <http-status code="101" text="Switching Protocols"/>,
|
|
39 и клиент попросил сменить протокол с помощью заголовка
|
|
40 <header>Upgrade</header> в запросе.
|
|
41 </para>
|
|
42
|
|
43 <para>
|
|
44 Как уже отмечалось выше, hop-by-hop заголовки, включая <header>Upgrade</header>
|
|
45 и <header>Connection</header>, не передаются от клиента к проксируемому
|
|
46 серверу, поэтому, для того чтобы проксируемый сервер узнал о
|
|
47 намерении клиента сменить протокол на WebSocket, эти заголовки следует
|
|
48 передать явно:
|
|
49 <programlisting>
|
|
50 location /chat/ {
|
|
51 proxy_pass http://backend;
|
|
52 proxy_http_version 1.1;
|
|
53 proxy_set_header Upgrade $http_upgrade;
|
|
54 proxy_set_header Connection "upgrade";
|
|
55 }
|
|
56 </programlisting>
|
|
57 Более сложный пример,
|
|
58 в котором значение поля <header>Connection</header>
|
|
59 в заголовке запроса к проксируемому серверу зависит от наличия поля
|
|
60 <header>Upgrade</header> в заголовке запроса клиента:
|
|
61 <programlisting>
|
|
62 http {
|
|
63 map $http_upgrade $connection_upgrade {
|
|
64 default upgrade;
|
|
65 '' close;
|
|
66 }
|
|
67
|
|
68 server {
|
|
69 ...
|
|
70
|
|
71 location /chat/ {
|
|
72 proxy_pass http://backend;
|
|
73 proxy_http_version 1.1;
|
|
74 proxy_set_header Upgrade $http_upgrade;
|
|
75 proxy_set_header Connection $connection_upgrade;
|
|
76 }
|
|
77 }
|
|
78 </programlisting>
|
|
79 </para>
|
|
80
|
|
81 </section>
|
|
82
|
|
83 </article>
|