Nodejs HTTP 和 HTTPS 通过同一端口 [英] Nodejs HTTP and HTTPS over same port

查看:41
本文介绍了Nodejs HTTP 和 HTTPS 通过同一端口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在谷歌上搜索并查看stackoverflow,但找不到我喜欢的答案;-)

I've been googling and looking here at stackoverflow, but I can't find an answer I like ;-)

我有一个通过 HTTPS 和端口 3001 运行的 NodeJS 服务器.现在我想在端口 3001 上获取所有传入的 HTTP 请求,并将它们重定向到相同的 URL,但通过 HTTPS.

I have a NodeJS server that runs over HTTPS and port 3001. Now I'd like to fetch all incoming HTTP requests on port 3001 and redirect them to the same URL but over HTTPS.

这一定是可能的.不是吗?

This must be possible. Isn't it?

谢谢!

推荐答案

如果你遵循约定,你就不需要监听同一个端口

按照惯例,当您请求 http://127.0.0.1 时,您的浏览器将尝试连接到端口 80.如果您尝试打开 https://127.0.0.1> 您的浏览器将尝试连接到端口 443.因此,为了保护所有流量,常规做法是在 http 上侦听端口 80,并重定向到 https,我们已经有一个用于端口 443 的 https 侦听器. 这是代码:

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);

使用 https 进行测试:

Test with https:

$ curl https://127.0.0.1 -k
secure!

使用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

如果你必须监听同一个端口

没有简单的方法可以让 http/https 在同一个端口上监听.最好的办法是在一个简单的网络套接字上创建代理服务器,该网络套接字根据传入连接的性质(http 与 https)连接到(http 或 https).

If you must listen on same port

There isn't simple way to have http / https listen on the same port. You best bet is to create proxy server on a simple net socket that pipes to (http or https) based on the nature of the incoming connection (http vs. https).

这是完整的代码(基于 https://gist.github.com/bnoordhuis/4740141)正是这样做的.它侦听 localhost:3000 并将其通过管道传输到 http(然后将其重定向到 https),或者如果传入连接在 https 中,则它只是将其传递给 https 处理程序

Here is the complete code (based on https://gist.github.com/bnoordhuis/4740141) that does exactly that. It listens on localhost:3000 and pipes it to http (which in turn redirects it to https) or if the incomming connection is in https it just passes it to https handler

var fs = require('fs');
var net = require('net');
var http = require('http');
var https = require('https');

var baseAddress = 3000;
var redirectAddress = 3001;
var httpsAddress = 3002;
var httpsOptions = {
    key: fs.readFileSync('./key.pem'),
    cert: fs.readFileSync('./cert.pem')
};

net.createServer(tcpConnection).listen(baseAddress);
http.createServer(httpConnection).listen(redirectAddress);
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 : redirectAddress;
        var proxy = net.createConnection(address, function () {
            proxy.write(buf);
            conn.pipe(proxy).pipe(conn);
        });
    });
}

function httpConnection(req, res) {
    var host = req.headers['host'];
    res.writeHead(301, { "Location": "https://" + host + req.url });
    res.end();
}

function httpsConnection(req, res) {
    res.writeHead(200, { 'Content-Length': '5' });
    res.end('HTTPS');
}

作为测试,如果您将其与 https 连接,您将获得 https 处理程序:

As a test, If you connect it with https you get the https handler:

$ curl https://127.0.0.1:3000 -k
HTTPS

如果您将它与 http 连接,您将获得重定向处理程序(它只是将您带到 https 处理程序):

if you connect it with http you get the redirect handler (which simply takes you to the https handler):

$ curl http://127.0.0.1:3000 -i
HTTP/1.1 301 Moved Permanently
Location: https://127.0.0.1:3000/
Date: Sat, 31 May 2014 16:36:56 GMT
Connection: keep-alive
Transfer-Encoding: chunked

这篇关于Nodejs HTTP 和 HTTPS 通过同一端口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆