Dexus / pem

Create private keys and certificates with node.js
Other
570 stars 129 forks source link

way to remove certs if changing from https back to http? #296

Closed ffd8 closed 4 years ago

ffd8 commented 4 years ago

I have a strange usecase... implementing this for the https activation of a nodejs website that should be booted in either http or https mode (reason to keep both, is localstorage data that's isolated between the two). I've got it working where I can boot server with http... then i can boot with https (and optionally forward any http calls to https or run both parallel) – but if I stop and try to boot http again, the browser (Chrome) won't allow it, forcing the url to https. I'm guessing this has to do with the certificates created for that domain:port by pem (amazing lib for making this process accessible). Soo, is there an easy way within the lib or otherwise to remove these certificates? I saw a function called deleteTempFiles(files) – but you have to know the files first... can post some code snippets if it helps, but more a general question of either how to destroy these certs or if it's something else at play that is preventing going back to http after having loaded with https once.

Dexus commented 4 years ago

I don’t think it’s a pen lib problem. It sounds like your framework problem. So I can‘t help you there. Or you should go a bit more into details... I‘m not able to clear things into the blue....

Am 03.05.2020 um 20:53 schrieb ffd8 notifications@github.com:

 I have a strange usecase... implementing this for the https activation of a nodejs website that should be booted in either http or https mode (reason to keep both, is localstorage data that's isolated between the two). I've got it working where I can boot server with http... then i can boot with https (and optionally forward any http calls to https or run both parallel) – but if I stop and try to boot http again, the browser (Chrome) won't allow it, forcing the url to https. I'm guessing this has to do with the certificates created for that domain:port by pem (amazing lib for making this process accessible). Soo, is there an easy way within the lib or otherwise to remove these certificates? I saw a function called deleteTempFiles(files) – but you have to know the files first... can post some code snippets if it helps, but more a general question of either how to destroy these certs or if it's something else at play that is preventing going back to http after having loaded with https once.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

ffd8 commented 4 years ago

Ack.. thanks for the quick reply. You're right.. must be some messed up logic on my end (since I'm trying to auto-forward an http request to https if in that mode.. or visa-versa if in the opposite.. funny though, impossible to search forwarding an https request to http since everyone swims the opposite way). Nevertheless, stripped the code and simply swapping between http or https works just fine.

ffd8 commented 4 years ago

Got it working! Thanks again for maintaining this awesome library- def makes life easier for serving both localhost + local lan machines!

FYI an insight to this weird setup (maybe helpful for someone searching in the future), can boot in either secure or unsecure and forwarding takes place between the two if opposite request is made.

npm start (unsecure) npm start https (secure)

server.js

// serve BOTH http + https on same port!

'use strict';
let express = require('express');
let app = express();
let httpx = require('./includes/js/httpx');
let pem = require('pem');
let server;

// https mode
let useHTTPS = false;
if(process.argv.indexOf('https') > -1){
    useHTTPS = true;
}

// custom port
let tPort = process.env.PORT || 5015;
for(let arg of process.argv){
    if(!isNaN(arg)){
        tPort = arg;
    }
}

pem.createCertificate({ days: 1, selfSigned: true }, function (err, keys) {
    if (err) { throw err }
        server = httpx.createServer({ key: keys.serviceKey, cert: keys.certificate }, app, useHTTPS);
        let urlPath = 'http';
        if(useHTTPS){
            urlPath = 'https';
        }
        let listener = server.listen(tPort, () => console.log('LIVE » '+urlPath+'://localhost:' + listener.address().port));
    })

app.use(express.static('./'));

httpx.js (modified from original):

'use strict';
let net = require('net');
let http = require('http');
let https = require('https');

exports.createServer = (opts, handler, useHTTPS) => {
    let server = net.createServer(socket => {
        socket.once('data', buffer => {
            // Pause the socket
            socket.pause();

            // Determine if this is an HTTP(s) request
            let byte = buffer[0];

            let protocol;
            if (byte === 22) {
                protocol = 'https';
            } else if (32 < byte && byte < 127) {
                protocol = 'http';
            }

            let proxy = server[protocol];
            if (proxy) {
                // Push the buffer back onto the front of the data stream
                socket.unshift(buffer);

                // Emit the socket to the HTTP(s) server
                proxy.emit('connection', socket);
            }

            // As of NodeJS 10.x the socket must be
            // resumed asynchronously or the socket
            // connection hangs, potentially crashing
            // the process. Prior to NodeJS 10.x
            // the socket may be resumed synchronously.
            process.nextTick(() => socket.resume());
        });
    });

    // switching logic http/https
    if(useHTTPS){
       // http » https
        server.http = http.createServer(function (req, res) {
         res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
         res.end();
        });

        server.https = https.createServer(opts, handler);
    }else{
        server.http = http.createServer(handler);

        // https » http
        server.https = https.createServer(opts, function (req, res) {
            res.writeHead(301, { "Location": "http://" + req.headers['host'] + req.url });
            res.end();
        });
    }

    return server;
};