Во-первых, давайте посмотрим, смогу ли я прояснить проблему.Вы ограничены одним (1) процессом node.js, но этот процесс может прослушивать два (2) сетевых порта, 80 и 443, верно?(Когда вы говорите один сервер, неясно, имеете ли вы в виду один процесс или только один сетевой порт.)как-то ваши клиенты подключаются не к тому порту.Это причудливый крайний случай, потому что по умолчанию клиенты отправляют HTTP-запросы на порт 80 и HTTPS на порт 443. И когда я говорю «по умолчанию», я имею в виду, что в URL-адреса не включены конкретные порты.Поэтому, если вы явно не используете перекрещенные URL-адреса, такие как http://example.com:443 и https://example.com:80,, у вас действительно не должно быть никакого перекрещенного трафика, попадающего на ваш сайт.Но так как вы задали вопрос, я полагаю, что он у вас есть, хотя я уверен, что вы используете нестандартные порты, а не значения по умолчанию 80/443.
Итак, для справки: ДА некоторые веб-серверы обрабатывают этодостаточно хорошоНапример, если вы введете http://example.com:443 для nginx, он ответит HTTP 400 «Плохой запрос», указывающий «Простой HTTP-запрос был отправлен на порт HTTPS».ДА, вы можете прослушивать 80 и 443 из одного и того же процесса node.js.Вам просто нужно создать 2 отдельных экземпляра express.createServer()
, так что это не проблема.Вот простая программа, демонстрирующая обработку обоих протоколов.
var fs = require("fs");
var express = require("express");
var http = express.createServer();
var httpsOptions = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
var https = express.createServer(httpsOptions);
http.all('*', function(req, res) {
console.log("HTTP: " + req.url);
return res.redirect("https://" + req.headers["host"] + req.url);
});
http.error(function(error, req, res, next) {
return console.log("HTTP error " + error + ", " + req.url);
});
https.error(function(error, req, res, next) {
return console.log("HTTPS error " + error + ", " + req.url);
});
https.all('*', function(req, res) {
console.log("HTTPS: " + req.url);
return res.send("Hello, World!");
});
http.listen(80);
И я могу проверить это через cURL следующим образом:
$ curl --include --silent http://localhost/foo
HTTP/1.1 302 Moved Temporarily
X-Powered-By: Express
Content-Type: text/html
Location: https://localhost/foo
Connection: keep-alive
Transfer-Encoding: chunked
<p>Moved Temporarily. Redirecting to <a href="https://localhost/foo">https://localhost/foo</a></p>
$ curl --include --silent --insecure https://localhost:443/foo
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 13
Connection: keep-alive
Hello, World!%
И показать перенаправление с HTTP на HTTPS ...
curl --include --silent --location --insecure 'http://localhost/foo?bar=bux'
HTTP/1.1 302 Moved Temporarily
X-Powered-By: Express
Content-Type: text/html
Location: https://localhost/foo?bar=bux
Connection: keep-alive
Transfer-Encoding: chunked
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 13
Connection: keep-alive
Hello, World!%
Так что это будет работать, чтобы обслуживать оба протокола для обычного случая и правильно перенаправлять.Тем не менее, крест-накрест не работают вообще.Я полагаю, что перекрещенный запрос, попадающий на сервер экспресс-доставки, не будет маршрутизироваться через стек промежуточного программного обеспечения, поскольку с самого начала он будет рассматриваться как ошибка и даже не сможет правильно проанализировать URI запроса, что необходимо дляотправить его через цепочку промежуточного программного обеспечения маршрута.Я думаю, что экспресс-стек их даже не получает, потому что они не являются допустимыми запросами, поэтому они игнорируются где-то в стеке узлов TCP.Вероятно, можно написать сервер для этого, и там уже может быть модуль, но вам придется написать его непосредственно на уровне TCP.И вам придется обнаружить обычный HTTP-запрос в первом фрагменте данных клиента, который попадает на TCP-порт, и подключить это соединение к HTTP-серверу вместо обычного рукопожатия TLS.
Когда я выполняю любое из этих действиймои экспресс-обработчики ошибок НЕ вызываются.
curl --insecure https://localhost:80/foo
curl: (35) Unknown SSL protocol error in connection to localhost:80
curl http://localhost:443/foo
curl: (52) Empty reply from server