Is there any chances of having websocket client connecting to an aws ec2 server behind a load balancer? - node.js

I'm working on a webchat that runs nodejs on port 8080 to publish and 4555 to subscribe using websocket at client side(javascript). When I do this connection direclty to the ec2 instance it works like a charm but in this case I won't have scalability and also have to open port 443 to world. If I make the connection through Load Balancer, chrome/firefox console shows this output and it fails to connect:
WebSocket connection to 'wss://www.domain.com/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 200
These are the headers:
Request URL: wss://www.domain.com/socket.io/?EIO=3&transport=websocket
Request Method: GET
Status Code: 200 OK
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: keep-alive
Content-Type: text/html; charset=UTF-8
Date: Sat, 25 May 2019 13:52:55 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Server: nginx/1.12.2
Transfer-Encoding: chunked
X-Powered-By: PHP/5.6.40
Accept-Encoding: gzip, deflate, br
Accept-Language: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: Upgrade
Cookie: PHPSESSID=nt35ln6ipvbkhflic3obfhd615; AWSALB=l1rePGzfT+/sXpFl0uWliWsb9/Cqdy7V/FjiHF8slLY2pRJ2IbN86SsQJ2UBQZBIfFk8iHKKuCBbe+lLrKcN6toxjiOVVJNxzL2Xaz7BC9aShLzOCTuxkRgmC9/I
Host: www.domain.com
Origin: https:/ /www.domain.com
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: fN1LLn8igDR5CadSE9UVIw==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36
EIO: 3
transport: websocket
The javascript client is very simple, for tests purposes:
var socket = io('https: //www.domain.com/chat',{'secure':true,transports: ['websocket', 'polling', 'flashsocket']});
In nginx config files I have a location /chat proxying the request to :4555 and there is nodejs running and listening.
I have spent 2 days on this and then decided to hire someone who could do that, I had two guys working on it and they couldn't be able to fix.
Can anyone here show me the way?

Related

Azure APIM throws error for WebSocket API due to Connection: Keep-Alive,Upgrade

I have REST and WebSocket APIs on the Azure API Management services portal. WebSocket is redirecting to different Web Pubsub service based on input parameters from clients/frontend for different development environments.
When hitting WebSocket api from Google Chrome, I am able to successfully establish connection end-to-end.
When hitting same WebSocket api from Firefox, I am getting InvalidWebsocketUpgrade error from APIM service.
This happens because Chrome is sending Connection: Upgrade in the socket connection request header, while Firefox is sending Connection: Keep-Alive, Upgrade in the header.
Chrome Request:
GET wss://apim-test.azure-api.net/qa/socket?access_token=eyJhbGc HTTP/1.1
Host: apim-ecv.azure-api.net
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36
Upgrade: websocket
Origin: https://abc.xyz.com
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Sec-WebSocket-Key: GTWCGvTFJN82sAl8gVv+VA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: json.webpubsub.azure.v1
Firefox request:
GET wss://apim-test.azure-api.net/qa/socket?access_token=eyJhbGciOi HTTP/1.1
Host: apim-ecv.azure-api.net
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Sec-WebSocket-Version: 13
Origin: https://az-qa2.ecarevault.com
Sec-WebSocket-Protocol: json.webpubsub.azure.v1
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: r764n2hSpKKr0Y63z1Ok3A==
Connection: keep-alive, Upgrade
Sec-Fetch-Dest: websocket
Sec-Fetch-Mode: websocket
Sec-Fetch-Site: cross-site
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Do I need to configure anything to support this on APIM or anywhere else??
Glad that you got the Solution in Microsoft Q&A. Posting the suggestions over here to help the other community members as this is a feature request and would be helpful for the members with related discussions.
According to this document in the connection header, you need to use only Upgrade because it is a WebSocket protocol and as of now APIM is enabled only with Upgrade as a value of connection header and MS is working on enabling keep-alive, Upgrade values this could be a feature request.

ERR_INVALID_SIGNED_EXCHANGE error in Google Chrome

I've set up my simple website with valid Let's Encrypt SSL certificate (from certbot). My nginx config is very short and trivial.
Website shows up correctly in latest Firefox. It shows 404 page, which is OK to me and should work as expected: 404 page.
If I try Google Chrome, i get an error:
The webpage at https://example.org/ might be temporarily down or it
may have moved permanently to a new web address.
ERR_INVALID_SIGNED_EXCHANGE
I assume that the application/signed-exchange header may cause this.
What is this header and should i remove it from response?
Request
GET / HTTP/1.1
Host: example.org
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,ru;q=0.8
DNT: 1
example.org example.org
Response
HTTP/1.1 404 Not Found
Server: nginx
Date: Fri, 29 Mar 2019 12:05:49 GMT
Content-Type: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Content-Length: 345
Connection: keep-alive
What to fix?
The Content-Type in the response is incorrect. It should be a single type, as Steffen Ullrich said. For a 404 page, I suspect you want Content-Type: text/html.
This may be something particular to your nginx config. On my server, 404 pages have Content-Type: text/html.

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.

Secure WebSockets with Socket.io, Node.js, and iisnode

I have an application that works perfectly fine with websockets through iisnode to a Node.js/Express/Socket.io application.
Windows Server 2012
iisnode 2.21
IIS 8.5
Node 6.2.1
socket.io 1.4.8
express.js 4.14
When visiting via HTTPS, however, WebSockets are falling back to polling after a seemingly successful wss negotiation:
GET wss://x.com/socket/a145e1f7-c8e7-4b26-96d3-a4d9869b5f3a/?id=a145e1f7-c8e7-4b26-96d3-a4d9869b5f3a&EIO=3&transport=websocket&sid=2nKT2dHWKrmO5xaHAAAM HTTP/1.1
Host: x.com
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: https://x.com
Sec-WebSocket-Version: 13
DNT: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8
Cookie: io=2AAAM; _ga=GA1.2.452745265.1462472455; connect.sid=s%3M8aVwM; rl-sticky-key=!1z8WBml+V4=
Sec-WebSocket-Key: qocdK/MRQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Server: Microsoft-IIS/8.5
server: Microsoft-IIS/8.5
Connection: Upgrade
sec-websocket-accept: VOFznVr/l4fsY=
sec-websocket-extensions: permessage-deflate
x-powered-by: ASP.NET
X-Powered-By: ASP.NET
Date: Mon, 19 Sep 2016 18:20:04 GMT
But there are no frames in this WebSocket, and Socket.io returns to HTTP polling. If TLS is handled by IIS, how could WebSockets be effected after wss protocol negotiation?
It turned out there were load balancer problems that caused this issue, nothing that the technology software stack was doing wrong.

Client caching recommendations for custom web fonts

What is the best way to get IIS to set the headers for woff files so that they can be served from the client browser cache.
I'm working on an MVC .NET site that is hosted in IIS7.5, served through cloudflare with static caching turned on. The site uses a custom woff web font. When requests are made for pages that use these fonts IIS is serving them with the headers shown below. Subsequent requests all look the same. To me it looks like these are not getting cached by the client browser. I'd expect the server to be responding with 304 (Not Modified) and then the browser should serve the woff from its cache.
Request Headers
GET /blah/Content/fonts/AzoSans-Thin-webfont.woff HTTP/1.1
Host: blah.co.uk
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
Accept: */*
DNT: 1
Referer: http://blah.co.uk/bundles/Content/stylesheets/main?v=f9NXr53WMUdV9DfYJMkEU_5QZZi0g8eB1lB5lqxgdXc1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: __cfduid=d96b367152ae58725c15e5946cf1d67f41415385741070; ASP.NET_SessionId=3tcc3e1nd0z005tlknrbph5h; redesign#lang=en
Response Headers
HTTP/1.1 200 OK
Date: Fri, 07 Nov 2014 19:27:57 GMT
Content-Type: application/font-woff
Content-Length: 27728
Connection: keep-alive
Last-Modified: Thu, 06 Mar 2014 10:40:46 GMT
ETag: "0cbfc872839cf1:0"
X-Powered-By: ASP.NET
CF-Cache-Status: HIT
Vary: Accept-Encoding
Expires: Fri, 07 Nov 2014 23:27:57 GMT
Cache-Control: public, max-age=14400
Accept-Ranges: bytes
Server: cloudflare-nginx
CF-RAY: 185bee60092d0a90-LHR
The problem here seems to be that cloudflare is changing the headers. If I bypass cloudflare I get
Cache-Control:max-age=0
and the server responds with a 304 and the browser uses content from its cache.

Resources