How do I test https on socket.io locally? - javascript

I've implemented an application using socket.io. All working nicely.
Converting it to a progressive web app required SSL so I've done that and that's working nicely. The app installs as a web app and works.
My problem is that when I go back to work on new features, the local installation of the app server ignores my secure client requests (On the production system, nginx handles the SSL).
These are the offending lines in the client:
const socket_url = 'https://' + url.hostname + ':' + port;
const socket = openSocket(socket_url, {query: 'clientId=' + clientId, secure: true});
I could edit the relevant line in the client conditionally on production versus local development but I'm hoping there is a more elegant solution.

A couple ideas for dealing with the test environment vs. production environment issue:
You could get a self-signed certificate and use it locally on your https server and have your test browser trust it. Then, you run https locally. You will, of course, have to adapt your server code to be an https server also when run in the test environment.
You could set up your own NGINX locally with a self-signed certificate and have it provide the same https role that you have in production.
When running locally, your server could generate a slightly different web page that inserts http:// instead of https:// in the code you show in your question so the client would just automatically use the desired protocol (https in production and http in test). This could be done with a template engine or could be done manually with search/replace when serving the relevant script.
The client-side Javascript could use location.protocol instead of a hard code https which will then automatically use the protocol that the web page was loaded from which could then be either http or https. So, if the web page is loaded via http, then socket.io would use http. If the web page was loaded via https, then socket.io would use https.

Related

websocket server/client only works on LAN

I'm trying to make a chat server with a web client and python backend. Everything works fine on the local network (both localhost and different computers under the same router). However, when I try to connect with my external IP it doesn't work. (this is true for both a JavaScript and Python client). The external port is forwarded on TCP.
Backend server content is the basic server shown on the documentation for the Python websockets library.
Client is a JS oneliner that is only trying to connect: var client = new WebSocket("ws://ip:port");
EDIT: I'm actually stupid. I thought you could access the external IP on the local network and it would have the same effect. I believed this because ssh works that way.

Angular application to support both http and https

I built an application for demo purposes that uses an Angular front-end hosted on a web server (nginx). The nginx instance, in addition to serving the compiled JS code, also acts as a reverse proxy for an application server that the browser needs to connects to. The flow is such that when I deploy this nginx on an infrastructure with any IP/FQDN, I can connect to this IP/FQDN and subsequent calls to the application server happens against the same IP/FQDN. You can see the architecture and the flow in this diagram.
The way it works is that the JS code contains an endpoint that I configure in the environment.ts file which contains this:
export const environment = {
production: true,
envName: 'prod',
appserver_env: 'http://' + window.location.host
};
Every time the code needs to connect to the app server it uses the appserver_env variable that resolves to the same IP/FQDN it pulled the JS code from.
This works just fine if I deploy my application without any security (i.e. http). It doesn't work if my webserver only works with https. I can obviously change the environment.ts to specify https instead and that would work (in a secured environment) after recompiling the Angular code.
However, I am trying to figure out if there is an easy way to tell Angular that this configuration needs to be working with EITHER http or https depending on the deployment method I am using. This is a demo application that I want to use in the most flexible way.
Any suggestion? Thanks!

Communicating between cordova and a python server

I've been trying to make a cordova app get information from a python server. I am relatively new to JavaScript but I've been trying to connect using sockets, but I couldn't get them to communicate and I can't use API since cordova blocks cross domain APIs.
How can I get them to communicate?
First, run two servers in the same domain. And use proxy server.
Here's an example case.
If your major app is one of Python, set proxy as:
yourdomain.com/ -> Python server
yourdomain.com/elsewhere/ -> Cordova server
Or you could set cordova app as the major app.
Second, communicate between them via HTTP or socket. It also can be done sharing a temp file or database.
The issue is that your API Server does not respond using CORS. If you can setup your python server to respond using CORS (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). There would be no issues. If it will work with the chrome developer Console then it works with cordova.
If it you can not make that, I would suggest writing a Firebase Functions that becomes a man in the middle to the story.

socket.io.js 404 (Using apache to host site)

Alright, so I had my socket.io server listening on a different port, but in order to get it to work with https, I needed to have it listen without passing in a port (default). (It works fine on a different port loaded with http, but I need it to work on https)
My project was working fine, client could connect and send data fine. However, I moved the site over to my main domain, which has an SSL certificate. The site loads everything via https, so it couldn't load the http version of socket.io.js
However, now that I switched it to just var client = require("socket.io").listen().sockets; instead of listening on a different/specific port , it's still not working. Instead of giving me a connection error, it's not including the file at all.
My fear is that I'd end up needing to remake my whole site to host my files via node.js and I'd rather not have to do that.
I'm not using any other module than mysql-node and socket.io, and I'd prefer to keep it that way if possible. I am new to node.js, so I'm sorry if there's an obvious answer that I'm unaware of.
I looked around, however, and can't seem to find the answer anywhere. Or, at least a clear answer.
Would I be better off using websockets instead of socket.io?
If so, how would I go about doing this? I'd be more willing to remake my node application instead of remaking my site, honestly.
I am including the socket.io.js file in the client-side like so:
<script src="https://mysite/socket-io/socket.io.js"></script>
but of course, 404 since it's not an actual file that's on my apache server. There's no folder/directory named socket-io in my public_html directory, so that makes sense to me.
But, how can I get this to work? Would I need to host my files via node.js or would I be better off using HTML5 websockets? A fairly large demographic of my site's users use mobile devices, so I'd have to be sure it works on mobile as well.
If you're going to use apache to host the socket.io.js file, then you need to put that file on your Apache server at a path that it can be served from by Apache, just like any other web file that you want the Apache server to serve. Or, you can just serve socket.io.js from a public CDN also and use the public CDN URL. It's just a JS file. You can put it anywhere or use any URL that reaches a place where the file will be served from. There are some advantages to letting node.js and socket.io serve it for you because it guarantees that client and server socket.io versions are always in sync, but you don't have to do it that way.
If you are using node.js (which it sounds like you are at least in some capacity), then the socket.io built into node.js will serve the file automatically if you are using node.js to serve your web page too and you've configured socket.io to listen on the same port as your node.js web server. In that case, your webpage and socket.io will use the same port and both will run through the node.js server.
You haven't really explained why you're using both node.js and Apache, how that architecture works and why you're serving some of your site with Apache rather than just using node.js for the whole site as that is certainly the cleaner option with socket.io.
You can use plain webSockets if you want instead of socket.io, but then you will likely have to build some of the socket.io functionality on top of the webSockets (auto-reconnect, message passing, etc...) and using plain webSockets won't really simplify any of the Apache/node.js questions you have. It's trivial to serve up the socket.io.js file to the client using either Apache or node.js and once the client has the file, it is actually more work to use plain webSockets than to use socket.io because of the extra features that socket.io has already built.

Is there a performance difference when if "http" is appended on CDN calls?

I'm creating a local static site and appended CDN script links for jQuery and Bootstrap.
I noticed that it wouldn't connect and had to add the http: prefix in the src attribute (which I think is needed locally). Is there a performance difference once I have the site live in production and the prefix is left?
It will only matter if https is involved with the page, as anything with http will flag a security warning. Since you are requesting an external file from another server, the protocol moniker is required (as you experienced)
To make the request protocol agnostic, do something like:
<script ..... src="//cdn.domain.com/file.ext" >
The cleanest solution is to run a local web server (allowing you to leverage HTTP resource conventions and protocol agnostic resources). On OSX you can start up a simple http server with the following commands
> cd /path/to/project/folder
> python -m SimpleHTTPServer 8080
If an absolute URL in a link or script starts with //, it means that it should use the same protocol as the current page.
If you specify the http (or https) protocol, you are forcing the browser to retrieve that resource using that protocol.
If a page is downloaded using a secure connection and there is a JS or CSS resource in the page that wants be downloaded as normal http, then most browsers will generate a security warning. So having the URL omit the protocol and start with // will have the benefit that it will be fast on an http page (as http is faster than https), and will still be secure on an https page (so no browser warning).
The problem with this is that if you use a protocol different from http or https (most notably the protocol for local file system file:, i.e. when you open an HTML file in your hard disk), then it will be unable to locate the resource because, using the same protocol as the main page, it will try to find the resource in your local file system, which most likely does not contain it, resulting in an error.

Categories

Resources