Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A node.js proxy that accepts HTTP and HTTPS traffic on the same port.
var fs = require('fs');
var net = require('net');
var http = require('http');
var https = require('https');
var httpAddress = '/path/to/http.sock';
var httpsAddress = '/path/to/https.sock';
fs.unlinkSync(httpAddress);
fs.unlinkSync(httpsAddress);
var httpsOptions = {
key: fs.readFileSync('/path/to/key.pem'),
cert: fs.readFileSync('/path/to/cert.pem')
};
net.createServer(tcpConnection).listen(8000);
http.createServer(httpConnection).listen(httpAddress);
https.createServer(httpsOptions, httpsConnection).listen(httpsAddress);
function tcpConnection(conn) {
conn.once('data', function(buf) {
// A TLS handshake record starts with byte 22.
var address = (buf[0] === 22) ? httpsAddress : httpAddress;
var proxy = net.createConnection(address, function() {
proxy.write(buf);
conn.pipe(proxy).pipe(conn);
});
});
}
function httpConnection(req, res) {
res.writeHead(200, { 'Content-Length': '4' });
res.end('HTTP');
}
function httpsConnection(req, res) {
res.writeHead(200, { 'Content-Length': '5' });
res.end('HTTPS');
}
@basarat

This comment has been minimized.

Copy link

basarat commented Jan 28, 2015

from: http://stackoverflow.com/a/23975955/390330

You don't need to listen on same port if you follow convention

By convention when you request http://127.0.0.1 your browser will try to connect to port 80. If you try to open https://127.0.0.1 your browser will try to connect to port 443. So to secure all traffic it is simply conventional to listen to port 80 on http with a redirect to https where we already have a listener for https for port 443. Here's the code:

var https = require('https');

var fs = require('fs');
var options = {
    key: fs.readFileSync('./key.pem'),
    cert: fs.readFileSync('./cert.pem')
};

https.createServer(options, function (req, res) {
    res.end('secure!');
}).listen(443);

// Redirect from http port 80 to https
var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
    res.end();
}).listen(80);

Test with https:

$ curl https://127.0.0.1 -k
secure!

With http:

$ curl http://127.0.0.1 -i
HTTP/1.1 301 Moved Permanently
Location: https://127.0.0.1/
Date: Sun, 01 Jun 2014 06:15:16 GMT
Connection: keep-alive
Transfer-Encoding: chunked
@davidlondono

This comment has been minimized.

Copy link

davidlondono commented Oct 29, 2015

It has a problem for multipart requests, the package is too large and some times it my not work

@DylanPiercey

This comment has been minimized.

Copy link

DylanPiercey commented Dec 20, 2015

Does anyone know if any issues exist with this method?

@CatTail

This comment has been minimized.

Copy link

CatTail commented Jan 4, 2017

@davidlondono can you provide sample code to reproduce the problem?

@ildrm

This comment has been minimized.

Copy link

ildrm commented Apr 21, 2018

Thank you @basarat . but when you use http://IP:PORT , req.headers['host'] returns IP:PORT and you should split IP from that and attach :PORT to that. 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.