DEV Community

Stefan Werfling
Stefan Werfling

Posted on

Redirect HTTP to HTTPS on the same port

Intro

I've found that I can document things very well and yet others get it wrong.

The best example is

after installation, open the interface at https://localhost:3000

Watch here "https". People then wrote to me saying that the access wasn't working. During my research I discovered that the person was trying to access it via "http".

Image description

The URL also had a copy action, you just had to copy the line.

Alright, let's tackle the problem!

I then sat down and poked around in the depths of the express classes.

Code

import https from 'https';
import express from 'express';

const exp = express();

// todo somthing with express
// ...

const httpsServer = https.createServer({
   key: ck.key,
   cert: ck.crt,
}, exp);
Enter fullscreen mode Exit fullscreen mode

At the beginning we create a server with https, pass the key and the crt.

Next we adapt the event to tlsClientError, here we open it when the browser tries to access an https connection via http. This attempt produces a TLS error.

httpsServer.on('tlsClientError', (err, tlsSocket) => {
//....
});
Enter fullscreen mode Exit fullscreen mode

To help, I created the following classes:

import * as net from 'net';
import * as tls from 'tls';

export class TlsClientError extends Error {

    public library: string = '';

    public reason: string = '';

    public code: string = '';

    public stack: string = '';

}

export class TlsSocket extends tls.TLSSocket {

    public _parent?: net.Socket;

}

Enter fullscreen mode Exit fullscreen mode

We now catch the tls error, check whether it was an http request and if it was, we send a blank header in http 1.1 format with the 'location' to https.

httpsServer.on('tlsClientError', (err, tlsSocket) => {
   const tlsError = err as TlsClientError;

   if (tlsError.reason === 'http request') {
      const tTlsSocket = tlsSocket as TlsSocket;

      if (tTlsSocket._parent) {
         tTlsSocket._parent.write('HTTP/1.1 302 Found\n' +
            `Location: https://localhost:${this._port}`);
      }
   }
});
Enter fullscreen mode Exit fullscreen mode

this._port is in my class and gets the port from the setting. tTlsSocket._parent is the socket stream before the TLS encryption, everything we write on it goes to the browser unencrypted.

As a last step we start the listing:

httpsServer.listen(this._port, () => {
   console.log('Listen start.');
});
Enter fullscreen mode Exit fullscreen mode

Summary

Now express runs with https and if you call the http you are redirected again.

If you know of a better way, let me know, I'm open to ideas! ;)

Top comments (0)