849
|
1 <!--
|
|
2 Copyright (C) Nginx, Inc.
|
|
3 -->
|
|
4
|
|
5 <!DOCTYPE article SYSTEM "../../../../dtd/article.dtd">
|
|
6
|
|
7 <article name="WebSocket proxying"
|
|
8 link="/en/docs/http/websocket.html"
|
|
9 lang="en"
|
|
10 rev="1">
|
|
11
|
|
12
|
|
13 <section>
|
|
14
|
|
15 <para>
|
|
16 To turn a connection between a client and server from HTTP/1.1 into WebSocket,
|
|
17 the <link url="http://tools.ietf.org/html/rfc2616#section-14.42">protocol
|
|
18 switch</link> mechanism available in HTTP/1.1 is used.
|
|
19 </para>
|
|
20
|
|
21 <para>
|
|
22 There is one subtlety however: since the <header>Upgrade</header> is a
|
|
23 <link url="http://tools.ietf.org/html/rfc2616#section-13.5.1">hop-by-hop</link>
|
|
24 header, it is not passed from a client to proxied server.
|
|
25 With forward proxying, clients may use the <literal>CONNECT</literal>
|
|
26 method to circumvent this issue.
|
|
27 This does not work with reverse proxying however,
|
|
28 since clients are not aware of any proxy servers,
|
|
29 and special processing on a proxy server is required.
|
|
30 </para>
|
|
31
|
|
32 <para>
|
|
33 Since version 1.3.13,
|
|
34 nginx implements special mode of operation
|
966
|
35 that allows setting up a tunnel between a client and proxied
|
849
|
36 server if the proxied server returned a response with the code
|
|
37 <http-status code="101" text="Switching Protocols"/>,
|
|
38 and the client asked for a protocol switch via the <header>Upgrade</header>
|
|
39 header in a request.
|
|
40 </para>
|
|
41
|
|
42 <para>
|
|
43 As noted above, hop-by-hop headers including <header>Upgrade</header>
|
|
44 and <header>Connection</header> are not passed from a client to proxied
|
|
45 server, therefore in order for the proxied server to know about the client’s
|
|
46 intention to switch a protocol to WebSocket, these headers have to be
|
|
47 passed explicitly:
|
|
48 <programlisting>
|
|
49 location /chat/ {
|
|
50 proxy_pass http://backend;
|
|
51 proxy_http_version 1.1;
|
|
52 proxy_set_header Upgrade $http_upgrade;
|
|
53 proxy_set_header Connection "upgrade";
|
|
54 }
|
|
55 </programlisting>
|
|
56 A more sophisticated example
|
|
57 in which a value of the <header>Connection</header> header field
|
|
58 in a request to the proxied server depends on the presence of
|
|
59 the <header>Upgrade</header> field in the client request header:
|
|
60 <programlisting>
|
|
61 http {
|
|
62 map $http_upgrade $connection_upgrade {
|
|
63 default upgrade;
|
|
64 '' close;
|
|
65 }
|
|
66
|
|
67 server {
|
|
68 ...
|
|
69
|
|
70 location /chat/ {
|
|
71 proxy_pass http://backend;
|
|
72 proxy_http_version 1.1;
|
|
73 proxy_set_header Upgrade $http_upgrade;
|
|
74 proxy_set_header Connection $connection_upgrade;
|
|
75 }
|
|
76 }
|
|
77 </programlisting>
|
|
78 </para>
|
|
79
|
|
80 </section>
|
|
81
|
|
82 </article>
|