I'm currently trying to have a hack.chat on my personal server working.
Long story short, it consists of two servers. The first is a simple httpd server serving javascript and CSS. The second one, the chat system, is a node.js server which the javascript connects to using websocket. And here comes the problems.
I want it all to use port 80, with a different domain name on a single IP, using a separate server block in Nginx.
I followed the Nginx websocket doc but this is not working. When the websocket tries to connect, it always gets a 200 return code whereas, if I understood well, it should get 101 (switching protocol).
My Nginx version is 1.8.0 and my server is running on gentoo with linux 4.0.5
Here is a dump of the relevant nginx conf files :
nginx.conf:
user nginx nginx;
worker_processes 1;
error_log /var/log/nginx/error_log info;
events {
worker_connections 1024;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main
'$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
client_header_timeout 10m;
client_body_timeout 10m;
send_timeout 10m;
connection_pool_size 256;
client_header_buffer_size 1k;
large_client_header_buffers 4 2k;
request_pool_size 4k;
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
output_buffers 1 32k;
postpone_output 1460;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 75 20;
ignore_invalid_headers on;
include /etc/nginx/sites-enabled/*;
}
sites-enabled/chat :
map $http_upgrade $connection_upgrade{
default upgrade;
'' close;
}
server{
listen 0.0.0.0:80;
server_name chat.axellink.fr;
location / {
proxy_pass http://127.0.0.1:6060;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
access_log /var/log/nginx/chat_access;
error_log /var/log/nginx/chat_error debug;
}
When I take a look at the access_log, it effectively shows the 200 response and there is no error in the error_log. Unfortunately, the node.js server does not give me any log (or I don't know how to view it).
Thank you in advance for any response.
EDIT
Thx to mc0e, I managed to have the hack.chat server respond 101. By comparing what actually happens between nginx and node.js with what happens on a direct connection, I saw that on direct an header Upgrade: websocket is set but nginx does not. So I corrected my sites-enabled/chat to :
server{
listen 0.0.0.0:80;
server_name chat.axellink.fr;
location / {
proxy_pass http://127.0.0.1:6060;
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
}
access_log /var/log/nginx/chat_access;
error_log /var/log/nginx/chat_error debug;
}
I also removed the map block as it used to set the Connection header to close instead of Upgrade.
Still doesn't work though. hack.chat gives back a 101 with Connection: Upgrade and Upgrade : websocket but somehow nginx gives back a 101 with Connection: keep-alive (as what I see in firefox) :/
EDIT
Did a ngrep on nginx communications, it does send the packet hack.chat gives back to him and firefox is complaining about cross-origin. I'll try to avoid cross origin.
LAST EDIT
Ok now that I'm home I did a test and it worked like a charm. Pretty sur that my last issue was because of my work proxy, let's hope it's cache or else everything would have been useless.
Here is the last of my conf that avoids cross origin :
server{
listen 0.0.0.0:80;
server_name chat.axellink.fr;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:8081;
}
location /chat/ {
proxy_pass http://127.0.0.1:6060;
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
}
access_log /var/log/nginx/chat_access;
error_log /var/log/nginx/chat_error debug;
}