Hello all!
I've installed the latest version 1.3.13 (supposedly supporing
websocket) and was trying to push websocket connections through nginx to
tomcat while leaving all other (static) content to nginx. To do this,
I've added the following "location" for tomcat:
location /examples/websocket {
proxy_pass http://127.0.0.1:8080/examples/websocket;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
I know that tomcat itself accepts some test websocket connection just
fine. Also, getting static pages from tomcat through nginx works well
too. However, proxying websocket doesn't seem to work.
So I've stopped tomcat and used netcat to see what gets through. Here it
goes:
Direct request (firefox -> tomcat):
GET /examples/websocket/echoStream HTTP/1.1
Host: 192.168.0.91:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20100101
Firefox/17.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive, Upgrade
Sec-WebSocket-Version: 13
Origin: http://192.168.0.91:8080
Sec-WebSocket-Key: ZffbHEsoryDw1gcX51lt8g==
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Request passed though nginx (firefox -> nginx -> tomcat):
GET /examples/websocket/echoStream HTTP/1.0
Host: 192.168.0.91
X-Real-IP: 192.168.0.98
Connection: close
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20100101
Firefox/17.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http://192.168.0.91
Sec-WebSocket-Key: 9YkdANPMSHDxb8axUbeKwQ==
Pragma: no-cache
Cache-Control: no-cache
One can clearly see that there is a problem. At least, "HTTP/1.1" is
lost, "Connection: keep-alive, Upgrade" is lost, and "Upgrade:
websocket" is lost. Generally, it does not look like websocket is
supported at all (Essentially, apache does this same damage to websocket
connections).
Honestly I'm not much familiar with nginx, just had to dismiss apache
because apparently they refused to even consider support for websocket.
So before trying to dig deep into sources I thoght I should ask here. Is
it possible to get websocket through nginx really? Maybe I need to
configure something additionally?
Thank you.
Nikolai
on 2013-02-21 15:15
on 2013-02-21 15:31
On Thursday 21 February 2013 18:35:14 Nikolai Zhubr wrote: > proxy_set_header Host $host; > Direct request (firefox -> tomcat): > Origin: http://192.168.0.91:8080 > Connection: close > > configure something additionally? > Yes, it's possible with 1.3.13. And yes, you need some additional configuration. Example: location /examples/websocket { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } Docs: http://nginx.org/r/proxy_http_version http://nginx.org/r/proxy_set_header wbr, Valentin V. Bartenev -- http://nginx.com/support.html http://nginx.org/en/donation.html
on 2013-02-21 16:36
21.02.2013 18:30, Valentin V. Bartenev wrote:
[...]
> }
Ah, this indeed helped! Now it works. Thank you very much.
Apparently such configuration implies that different kinds of
connections (standard and websocket) can not be mixed in one "location"
section? (As far as I understood it, magic headers do not get through
directly, but essentially get reintroduced by these configuration
settings?)
Thank you.
Nikolai
on 2013-02-21 17:04
On Thursday 21 February 2013 19:55:45 Nikolai Zhubr wrote: > > proxy_http_version 1.1; > directly, but essentially get reintroduced by these configuration > settings?) > Not quite so. Actually, they can be mixed. That's why the $http_upgrade variable used. If there's no such header in request, then the variable is empty and the header won't be set. You can also set the Connection header to different values depending on existence of the Upagrade header in a request. Example: http { map $http_upgrade $conn_header { default upgrade; '' close; } server { ... location { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $conn_header; } } http://nginx.org/r/map wbr, Valentin V. Bartenev -- http://nginx.com/support.html http://nginx.org/en/donation.html
on 2013-02-21 22:53
21.02.2013 20:03, Valentin V. Bartenev wrote: [...] >> Apparently such configuration implies that different kinds of >> connections (standard and websocket) can not be mixed in one "location" >> section? (As far as I understood it, magic headers do not get through >> directly, but essentially get reintroduced by these configuration >> settings?) >> > > Not quite so. Actually, they can be mixed. That's why the $http_upgrade variable > used. If there's no such header in request, then the variable is empty and the > header won't be set. You are right. Now I see. I've even actually made some tests to be completely sure and they all worked correctly. Thank you for precise explanation and usefull examples! Nikolai
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.