Codespaces and https - node.js

I have a working node.js express based server (and client) application here that shows RPC over http+websockets. This works perfectly when run locally (using devcontainers) and includes the Dockerfile as well as devcontainer.json. However, when run from a codespace, it fails with the following client-side error messages.
client.js:9 Mixed Content:
The page at 'https://aniongithub-jsonrpc-bidirectional-example-<redacted>-8080.preview.app.github.dev/'
was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint
'ws://aniongithub-jsonrpc-bidirectional-example-<redacted>-8080.preview.app.github.dev/api'.
This request has been blocked; this endpoint must be available over WSS.
(anonymous) # client.js:9
client.js:9 Uncaught DOMException: Failed to construct 'WebSocket':
An insecure WebSocket connection may not be initiated from a page loaded over HTTPS
at 'https://aniongithub-jsonrpc-bidirectional-example-<redacted>-8080.preview.app.github.dev/client.js:9:10'
The documentation here states that By default, GitHub Codespaces forwards ports using HTTP but you can update any port to use HTTPS, as needed. When I check the settings indicated:
it's set to http. What am I missing here? How can I get it to serve my express application over http?
Note: My intention is that when locally cloned and opened in a devcontainer, the code works just as it would if opened in a CodeSpace. This means I need to ensure that the certs generated by CodeSpaces are somehow factored into my local devcontainer process or that I forego authentication altogether. Alternatively, I need to find out if I'm running on CodeSpaces and do different things, which seems messy and shouldn't be the case. Hope this makes my intentions for asking this question clearer!

It turns out that I just couldn't use http for the RPC endpoint when running over https, so the solution was to use location.protocol and ws/wss depending on the current protocol to initialize the client RPC endpoint.

Related

Nginx:504 Gateway Timeout

I am using Nginx as my https server to serve my http content from my node server.
I am also hosting my server on google cloud.
I have been keep getting a 504 Gateway Timeout Error; So I wonder if it is because I didnt set my upstream server (node server) 8080 port open. Then it works. Not so sure if it is the correct way to do it
But then I kept looking other docs or tutorial online. I never see people configure in such way to connect to node server. They mainly only left the port 80 opened. So I wondered if my config in server block causing the 504 gateway problem
----------second update
this is my setting, and the default_server is written by default
but i always see doc have included a variable - server_name ; Actually I dont quite understand this varibale. May I know should I consider it or not for later use, although it works now
Aside, I got an
Server Error from my app.
FetchError: request to https://34.96.213.54:443/search/guest2 failed, reason: self-signed certificate
Why is that it works on chrome,although I get that api directly and postman successfully.
third updated------
About self-signed certificate: You need to buy one or using a free service like https://letsencrypt.org .Beside that your questions are so basic so you have to research more on nginx docs (http://nginx.org/en/docs/http/server_names.html)

Error during WebSocket handshake: 'Connection' header is missing

I'm completely new to Node, and even newer to Socket.io. I just got my first chat application online at spaiglas.com, which works despite an error in the developer console that is fairly straightforward...
WebSocket connection to 'ws://example.com/...' failed
: Error during WebSocket handshake
: 'Connection' header is missing
Here is a codepen with all of my code. I've uploaded it to my hosting provider, which is using Passenger via cPanel on an Apache server in a Node 9.11.2 environment.
From what I've been reading, the 'Connection' headers can't be set using AJAX, which is supposedly a security risk, but instead is handled by the server? Is it possible to manually set this header?
I have noticed by looking at the headers that early on usually one of them always successfully switches/upgrades the protocol to WebSockets, but then the platform always seems to revert back to HTTPS/polling. In the case below, which I observed just now, there were actually 2 out of now 67 instances whereby it successfully switched to and used the WebSockets protocol.
You need to initialize socket.io before you start your HTTP server that is listening on port 80. In the docs it is...
var http = require('http').Server(app);
var io = require('socket.io')(http);
And then later, you call http.listen(3000, ...). This will start the socket.
On the client, your path is also incorrect. Websockets is a protocol (ws://somedomain.com), just like HTTP. When you connect via http:// that is a different protocol. I would either not pass it anything, or use namespaces which you can find in the socket.io documentation.
Socket.io reverts to long polling and sometimes doesn't even use websockets (which is partly why it is generally slower than libraries like ws on npm). Because of that, passing http:// into the io(...) on the client may not be wrong with their library, but I would remove it anyway and do my above suggestion.

NodeJS request -- how to disable automatic proxy from environment

I am using the request npm module for making http requests in my program. The default behavior of request seems to be that it will try to use proxy server, when one is defined in environment.
I am testing this in a shared unix server used by multiple developers, who keep changing proxy settings. Further more, I do not need proxy, because I just connect other web services within the lan directly.
So, is there a way to tell the 'request' not to use the proxy option, even though if it is set in environment?
Credit goes to #mh-cbon in the comments. Codifying here to complete the answer.
Either blank out the configured proxies prior to starting nodejs
HTTPS_PROXY="" node script.js
Or use NO_PROXY, to disable proxies for specified patterns (or all)
NO_PROXY="*" node script.js
Alternatively within your node js script, do the above before loading and using of request module.
// Disable proxy from being used by request module
process.env["NO_PROXY"]="";
// Then go on as per normal
const request = require("request")
... do stuff ..

Openshift Websocket custom domain

I've recently changed my openshift default domain myapp.rhcloud.com in www.myapp.com with a custom ssl certificate. The config works perfectly well until the web page ask the server for a websocket connection. I use node with socket.io and websockets enabled
I first tried:
io.connect(www.myapp.com:8443/...)
But this return an error.
So I set back the socket connection url to:
io.connect(myapp.rhcloud.com:8443/...)
But I get this error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.myapp.com' is therefore not allowed access.
Is there a way to allow websocket connection via a custom domain on Openshift ? Or, do I need to set up cors?
EDIT
I left socket.io prefix the websocket url I do not pass the protocol to socket.io
From my understanding, WebSockets use something like this (wss instead of ws for secure)
wss://www.yourapp.com:8443
Make sure you setup openshift with your domain alias
https://www.openshift.com/kb/kb-e1096-how-to-setup-an-alias-for-your-application
When I log to https://www.myapp.com:8443/socket.io/1/ in Chrome, I get the error
Identity not verified
which is not the case on https://www.myapp.com... after few tests and searchs I think that this error is due to the websocket preview environnement on openshift. Source (https://www.openshift.com/blogs/paas-websockets):
Update: There is one more known complication. When using our
preview-deployment of WebSockets with HTTPS and WSS protocols, you
will face self-signed certificate. That is because this environment is
only temporary to give you insight into upcoming features. Once we
move the new routing layer to standard ports 80 and 443, i.e. we move
WebSockets support into production, the certificates used will be
signed and valid as they are with current deployment.

How to get full request URL in Node.js running on Heroku

I'm running a node application on heroku and I would like to find the full request URL through which my application is being requested. In particular, I want to know if it has been accessed through HTTP or HTTPS, so that I can redirect clients connecting through HTTP to use the same URL but with HTTPS instead.
Since the application is running under proxies, etc., the protocol and host portions of the requests I can read are the ones where node is running, as forwarded by Heroku infrastructure.
Hints appreciated!
BTW, my app uses requestjs, in case that is relevant

Resources