Need some help serving a NodeJS Express service over HTTPs

Hi there folks :). Long time no posting, still here in the lab, pushing hard at a major Haxe project that I’ve been working on for a while. Getting ready for a public launch. And such a launch cannot happen without HTTPS. Alas, I’ve been working just via HTTP for all this time and now I can’t get it to work over HTTPS.

I’m using hxnodejs and some externs that dts2hx made for me from Express. HTTP is simple:

var app: express_serve_static_core.Express = Express.call();
app.listen(port, () -> logger.info('Nexus Server listening at http://localhost:${port}'));

HTTPS is not simple:

		var privateKey = File.getContent('certificate/private.key');
		var certificate = File.getContent('certificate/certificate.crt');
		var ca = [File.getContent('certificate/ca.pem')]; // If you have a CA chain

		var credentials = {
			key: privateKey,
			cert: certificate,
			ca: ca // Omit if you don't have a CA chain
		};

		// Create an HTTPS server with the express app and credentials
		var httpsServer = Https.createServer(credentials, app);

		// Start the HTTPS server
		httpsServer.listen(port, function()
		{
			logger.info('Nexus Server listening at https://localhost:${port}');
		});

For the above, I’m hit with the following errors:

 Could not find a suitable overload, reasons follow
 Overload resolution failed for (?requestListener : Null<(request : js.node.http.IncomingMessage, response : js.node.http.ServerResponse) -> Void>) -> js.node.https.Server
 { key : String, cert : String, ca : Array<String> } should be Null<(request : js.node.http.IncomingMessage, response : js.node.http.ServerResponse) -> Void>
 ... For optional function argument 'requestListener'
 Overload resolution failed for (options : js.node.HttpsCreateServerOptions, ?requestListener : Null<(request : js.node.http.IncomingMessage, response : js.node.http.ServerResponse) -> Void>) -> js.node.https.Server
 express_serve_static_core.Express should be Null<(request : js.node.http.IncomingMessage, response : js.node.http.ServerResponse) -> Void>
 ... For optional function argument 'requestListener'
 End of overload failure reasons

Would SERIOUSLY appreciate a hand here. I feared this day would come and now it did and I’m a bit lost due to the rather few examples available for how all this should work.

I don’t know if this would fit your use case, but if you deploy your app to a server then using nginx as a reverse proxy is pretty easy: How to Configure Nginx as an HTTPS Reverse Proxy (Easily) - Super Easy.

With it you can keep your app as http and nginx will wrap as https, you can even add a http → https redirect and the nginx config is supported by the let’s encrypt cli tool.
And if you want to host more than one website on the server (so a single port 80/443) then it’s a must.

2 Likes

That sounds like a very interesting approach indeed. Haven’t even considered that. Thank you for the suggestion. I actually DO need to serve two websites but on different ports. One of them is a React front-end that I just serve as static, but I will have to switch that to HTTPS as well, since it has to access the service via HTTPS. I guess I could use nginx for all this wiring.

Still curious if Haxe could serve over HTTPS. Worst case I guess I would have to inject raw JS code to handle that part, but I hoped I could handle it with extens. But to be honest I just asked chat GPT to produce the code and even after giving it the HTTPS extern class from hxnodejs it still errors out.

Have you tried casting your app object in createServer()? e.g.:

var httpsServer = Https.createServer(credentials, cast(app));

1 Like

Amazing! :slight_smile: :smiley: How did you figure that one out? It worked :smiley: and it actually runs on HTTPS, albeit with a broken certificate. But still awesome. Thank you very much! :slight_smile:

Thank you both, applies to @ibilon too. The way things get solved in our small community here is one of the chief reasons I’m staying with Haxe for this intense ride I’m on with this project.

The short answer is, just a bit of googling and following how it would be done if you’re just using vanilla JS :slight_smile: The first result for expressjs https leads here: node.js - Enabling HTTPS on express.js - Stack Overflow which shows (in the top answer) that the express app object should be an acceptable argument in https.createServer().

The longer answer, which is just based on my understanding and may be incorrect, is if you look at the node.js docs for https.createServer(): HTTPS | Node.js v21.1.0 Documentation you’ll see that the second parameter is named requestListener, which is just a function callback to handle the requests. Turns out that when you create an express object it’s returning a function and that’s why you can just pass your app object in https.createServer(). However, in Haxe we have to cast it, probably because the way the externs/types are generated.

Have you looked at using Let’s Encrypt to facilitate getting a certificate?

1 Like

Great job man :slight_smile: . And thanks for joining the community and your first post helping me!

Yeah, I’m good with all the rest of the stuff. It was just the Haxe part giving me the blues because I lack the time for a proper investigation. I’m split into 10 directions. The project I’m doing is quite massive :slight_smile: and I’m alone. Fortunately nowadays I have chat GPT to help me with the rest of the logistics. It’s already running on a server, but it’s just HTTP and a friend of mine started developing a client for my platform and it was jolly time to switch to HTTPS. Thank you both for coming to my rescue. It shall be remembered! :slight_smile: