Docker + Nginx: Websocket returns 404 not found - node.js

I'm struggling on implementing a websocket connection between a SSL Server and the client.
Architecture:
Proxy: Nginx
Host: Docker (Swarm)
Webserver: Node.js (express)
Client (Postman, later vue.js)
Nginx settings (app.conf):
server {
listen 443;
listen [::]:443;
client_max_body_size 100M;
server_name search.app search.app.host.ads;
location / {
proxy_pass http://search-service:3020; # docker container
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
search-server (server.js)
async function startServer() {
// variable definition
server = express();
// set http server
let httpServer = http.createServer(server);
// init loaders -> websocket is defined here
loaders(server, httpServer);
}
search-service (websocket.js) (how is the websocket created?)
let wsSearch = new websocket.Server({ server: httpServer, path: "/socket/websocketSearch" });
The websocket is working properly on localhost using this url
ws://localhost:3020/socket/websocketSearch
After deploying on production site, the url will be
wss://search.app.host.ads/socket/websocketSearch
Trying to connect to production websocket using Postman returns following error:
Error: Unexpected server response: 404
Handshake Details
Request URL: https://search.app.host.ads/socket/websocketSearch
Request Method: GET
Status Code: 404 Not Found
Request Headers
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: gzRuxZ2QYTOladlXSenjmw==
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: search.app.host.ads
Response Headers
Server: nginx/1.19.4
Date: Tue, 03 Aug 2021 13:07:45 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 161
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'none'
X-Content-Type-Options: "nosniff"
Which package do I use to implement websocket?
WS Version 7.5.3
I've followed several instructions like Nginx or related StackOverflow issues. However, I didn't manage to connect to my websocket.
Do you have any idea, where is my fault?
Thanks in advance.
If any further information is needed, I try to provide it.
Best regards

Related

How to return empty response with Varnish?

When a request come on a Varnish server, I would like to return an empty response or simply close the connection, if the requested server name is not known.
For example from nginx (the backend side of Varnish) I did that:
server {
listen 80 default_server;
listen [::]:80 default_server;
return 444;
}
server {
listen 80;
listen [::]:80;
server_name my.example.org
}
So, when an user/robot come on this nginx server with an address IP or an unknown host, it got: The connection was reset.
How do I?
With this configuration on nginx side and nothing more on Varnish side, if I try to access to the Varnish server with his public IP, I have: Error 503 Backend fetch failed - Backend fetch failed - Guru Meditation.
Perhaps there is a possibility on Varnish side, when response from backend (nginx) is 444, to simply close the connexion.
varnishlog says:
- BereqMethod GET
- BereqURL /
- BereqProtocol HTTP/1.1
...
- BereqHeader X-Varnish: 1540833
- VCL_call BACKEND_FETCH
- VCL_return fetch
- BackendOpen 33 default X.X.X.X 80 X.X.X.X 34862
...
- FetchError HTC eof (-1)
- BackendClose 33 default
...
- BerespProtocol HTTP/1.1
- BerespStatus 503
- BerespReason Backend fetch failed
- BerespHeader Date: Fri, 10 Feb 2023 10:10:48 GMT
- BerespHeader Server: Varnish
- VCL_call BACKEND_ERROR
I want to "process" this error.
If Varnish is hosted on the same machine as your Nginx server, Varnish should be listening on port 80 and Nginx on port 8080.
Once Varnish can reach Nginx, the Backend fetch failed issue will go away.
In Varnish you don't need to configure anything special, whatever Nginx returns, Varnish will handle. However, if you want to handle this in Varnish before Nginx is reached, you could use the following VCL code:
sub vcl_recv {
if(req.http.Host != "my.example.org") {
return(synth(403));
}
}
This assumes that my.example.org is the right Host header. This also assumes that returning a synthetic 403 Forbidden is an acceptable return value.

Remove or Replace Server Header in Swoole WebSocket Response

I have created a Swoole WebSocket server using the example given on the official OpenSwoole website:
https://openswoole.com/docs/modules/swoole-websocket-server#quick-start-example
The response header returned by the server to the client contains the Server: OpenSwoole 4.11.1 entry.
Connection: Upgrade
Sec-WebSocket-Accept: mABCD0joUS/Z/yPYqrqfa3+I2sT=
Sec-WebSocket-Version: 13
Server: OpenSwoole 4.11.1
Upgrade: websocket
Could we remove this server header line completely or replace it with a fake name like Server: XYZ?

Apache + Socket.io result in error establishing websocket connection on Mac

I have node.js with socket.io module in it and the tutorial chat example runs perfectly on localhost:3000.
I also have Apache server where I put all my php files for the project. Server works fine on localhost:8080.
Part of the project is communicating a message upon pushing send button on a form in a page that is created by compose.php script on Apache server. When pushing send a websocket connection has to be established (if not yet) and a test emit is sent. Just like the tutorial chat example. But that never happens.
When examining the problem on Chrome Console/Network errors are:
Console:
WebSocket connection to 'ws://localhost:8080/socket.io/?EIO=3&transport=websocket&sid=dhRg2iHG7dJqL3JEAAF4' failed: Error during WebSocket handshake: Unexpected response code: 302
Network:
First:
Request URL: ws://localhost:8080/socket.io/?EIO=3&transport=websocket&sid=BFoFZNDQamsdNurlAAIr
Request Method: GET
Status Code: 302 Found
Content-Length: 273
Content-Type: text/html; charset=iso-8859-1
Date: Sat, 29 Sep 2018 11:43:07 GMT
Location: ws://localhost:3000/socket.io/?EIO=3&transport=websocket&sid=BFoFZNDQamsdNurlAAIr
Server: Apache/2.4.33 (Unix) OpenSSL/1.0.2o PHP/7.2.6 mod_perl/2.0.8-dev Perl/v5.16.3
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,ru;q=0.8,ja;q=0.7,uk;q=0.6
Cache-Control: no-cache
Connection: Upgrade
Cookie: PHPSESSID=aaa8a06d8e58534d5ebbe62919085074; io=BFoFZNDQamsdNurlAAIr
Host: localhost:8080
Origin: http://localhost:8080
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: WqB/VJfA2Fx/+0BrcHPnBA==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
EIO: 3
transport: websocket
sid: BFoFZNDQamsdNurlAAIr
Then:
Request URL: http://localhost:3000/socket.io/?EIO=3&transport=polling&t=MOb913S&sid=BFoFZNDQamsdNurlAAIr
Request Method: GET
Status Code: 500 Internal Server Error
Remote Address: [::1]:3000
Referrer Policy: no-referrer-when-downgrade
Connection: keep-alive
Date: Sat, 29 Sep 2018 11:43:32 GMT
Transfer-Encoding: chunked
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,ru;q=0.8,ja;q=0.7,uk;q=0.6
Connection: keep-alive
Content-type: text/plain;charset=UTF-8
Cookie: PHPSESSID=aaa8a06d8e58534d5ebbe62919085074; io=BFoFZNDQamsdNurlAAIr
Host: localhost:3000
Origin: http://localhost:8080
Referer: http://localhost:8080/compose.php?crate_id=53
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
EIO: 3
transport: polling
t: MOb913S
sid: BFoFZNDQamsdNurlAAIr
My rewrite rule setup in .htaccess is this:
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule ^/?socket.io ws://localhost:3000/socket.io/
RewriteRule ^/?socket.io http://localhost:3000/socket.io/
I almost certain the problem is in the way I redirect socket.io calls from localhost:8080 to localhost:3000. I am just that bad at networks to completely not understand that. I have tried different configurations, including proxy and reverse proxy settings in httpd.conf such as:
<IfModule proxy_module>
ProxyRequests Off
ProxyPass /socket.io http://localhost:3000/socket.io/
ProxyPassReverse /socket.io http://localhost:3000/socket.io/
</IfModule>
I've been trying to fix this for 2 weeks now, it's driving me crazy. How can I get the socket.io on localhost:3000 to emit info upon request from a page originated from localhost:8080/compose.php ?
As most things I fail to do in life, solution was quite simple.
When running socket = io(); in a .js file, that is being served by Apache server, the socket object is set uri which is uri of the Apache server, in my case localhost:8080.
By adding this line
socket.io.uri = "http://localhost:3000/";
the problem is solved. The connection fails to be established right away, but will be established at reconnect attempt.

Tcp request failed with status 400 in Elastic Beanstalk Node Server with Nginx Proxy Server?

> 14.195.188.230 - - [18/Mar/2017:16:43:11 +0000] "(004026579154BP05000004026579154111213V0000.0000N00000.0000E000.0000000000.0010000000L0000021C)" 400 173 "-" "-" "-"
This is the error message that i received
HTTP/1.1 400 Bad Request
Server: nginx/1.10.1
Date: Sun, 19 Mar 2017 02:19:35 GMT
Content-Type: text/html
Content-Length: 173
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.10.1</center>
</body>
</html>
This is the log that i can see in my nginx access log, I need this data in my node server.
(004026579154BP05000004026579154111213V0000.0000N00000.0000E000.0000000000.0010000000L0000021C)
1) I am using elastic Beanstalk, i don't know how can i pass the above value to my node server module? If its possible to get that value as http or https request inside my node express module.
2) If i have to run a net server, than in which port should i listen for tcp, and how nginx will know about that port, for http server port, i use process.env.port

Too Many Redirects on OpenShift after push

I have a node.js application running on openshift. After testing my code on a local environment I pushed it up to my instance on openshift. After doing so, I went to check those changes on the public site and my browser reported that I was getting too many redirects. I tried to look at my haproxy status and even that was getting too many redirects.
I have done some investigation and here is what I've found:
I checked my nodejs logs and my node server started successfully (no errors)
I've ssh'd into my machine and ran curl -vvv $OPENSHIFT_NODEJS_IP:8080 and I was returned my index.html as I should.
When I run curl -vvv http://minutepolitics-minutepolitics.rhcloud.com/ I get this response:
RESPONSE:
Hostname was NOT found in DNS cache
Trying 54.81.203.46...
Connected to minutepolitics-minutepolitics.rhcloud.com (54.81.203.46) port 80 (#0)
GET / HTTP/1.1
User-Agent: curl/7.37.1
Host: minutepolitics-minutepolitics.rhcloud.com
Accept: */*
HTTP/1.1 302 Found
Date: Thu, 23 Oct 2014 03:26:06 GMT
Server Apache/2.2.15 (Red Hat) is not blacklisted
Server: Apache/2.2.15 (Red Hat)
Vary: Host
X-Powered-By: PHP/5.3.3
Location: http://minutepolitics-minutepolitics.rhcloud.com/
Connection: close
Accept-Ranges: none
Content-Length: 0
Content-Type: text/html
Closing connection 0
Also, when I ssh into my machine and run /etc/init.d/haproxy start the output is: Starting haproxy: [ALERT] 294/230821 (134951) : Starting frontend main: cannot bind socket [FAILED]
From here, I don't know what to do or try to get this working again.
Any and all help will be greatly apprecaited! Thanks!!

Resources