2011-11-17 43 views
17

Tôi đang phát triển một ứng dụng máy chủ proxy node.js và tôi muốn nó hỗ trợ các giao thức HTTPHTTPS(SSL) (làm máy chủ).Máy chủ ủy quyền HTTPS trong node.js

Tôi hiện đang sử dụng node-http-proxy như thế này:

const httpProxy = require('http-proxy'), 
     http = require('http'); 

var server = httpProxy.createServer(9000, 'localhost', function(req, res, proxy) { 
    console.log(req.url); 
    proxy.proxyRequest(req, res); 
}); 

http.createServer(function(req, res) { 
    res.end('hello!'); 
}).listen(9000); 

server.listen(8000); 

tôi thiết lập trình duyệt của tôi để sử dụng HTTP proxy trên localhost:8000 và nó hoạt động. Tôi cũng muốn bắt các yêu cầu HTTPS (ví dụ: thiết lập trình duyệt của tôi cũng sử dụng localhost:8000 làm HTTPS proxy và nắm bắt các yêu cầu trong đơn đăng ký của tôi). Bạn có thể vui lòng giúp tôi làm thế nào tôi có thể làm điều đó?

PS:

Nếu tôi đăng ký vào upgrade trường hợp httpProxy đối tượng máy chủ tôi có thể nhận được các yêu cầu nhưng tôi không biết làm thế nào để chuyển tiếp các yêu cầu và gửi thư trả lời cho khách hàng:

server.on('upgrade', function(req, socket, head) { 
    console.log(req.url); 
    // I don't know how to forward the request and send the response to client 
}); 

Mọi trợ giúp sẽ được đánh giá cao.

Trả lời

2

Tài liệu về nút-http-proxy chứa các ví dụ về điều này. Tìm "Proxying to HTTPS from HTTPS" tại https://github.com/nodejitsu/node-http-proxy Quá trình định cấu hình hơi khác nhau trong mọi trình duyệt. Một số có tùy chọn sử dụng cài đặt proxy của bạn cho tất cả các giao thức; một số bạn cần phải cấu hình proxy SSL một cách riêng biệt.

7

Tôi đã tạo ra một http/https proxy với sự trợ giúp của http-proxy mô-đun: https://gist.github.com/ncthis/6863947

Mã như của bây giờ:

var fs = require('fs'), 
    http = require('http'), 
    https = require('https'), 
    httpProxy = require('http-proxy'); 

var isHttps = true; // do you want a https proxy? 

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

// this is the target server 
var proxy = new httpProxy.HttpProxy({ 
    target: { 
    host: '127.0.0.1', 
    port: 8080 
    } 
}); 

if (isHttps) 
    https.createServer(options.https, function(req, res) { 
    console.log('Proxying https request at %s', new Date()); 
    proxy.proxyRequest(req, res); 
    }).listen(443, function(err) { 
    if (err) 
     console.log('Error serving https proxy request: %s', req); 

    console.log('Created https proxy. Forwarding requests from %s to %s:%s', '443', proxy.target.host, proxy.target.port); 
    }); 
else 
    http.createServer(options.https, function(req, res) { 
    console.log('Proxying http request at %s', new Date()); 
    console.log(req); 
    proxy.proxyRequest(req, res); 
    }).listen(80, function(err) { 
    if (err) 
     console.log('Error serving http proxy request: %s', req); 

    console.log('Created http proxy. Forwarding requests from %s to %s:%s', '80', proxy.target.host, proxy.target.port); 
    }); 
+1

Liên kết đến ý chính đã lỗi thời. Tôi đã cập nhật nó lên https://gist.github.com/ncthis/6863947 – david

+1

@david Hết ngày trở lại – fidev

+0

'httpProxy.HttpProxy không phải là chức năng' –

15

Giải pháp chỉ tồn tại cho điều này, và các tài liệu là người nghèo lúc tốt nhất để hỗ trợ cả hai trên một máy chủ. Bí quyết ở đây là hiểu rằng cấu hình proxy của khách hàng có thể gửi yêu cầu https tới máy chủ proxy http. Điều này đúng với Firefox nếu bạn chỉ định một proxy HTTP và sau đó kiểm tra "tương tự cho tất cả các giao thức".

Bạn có thể xử lý các kết nối https được gửi đến máy chủ HTTP bằng cách lắng nghe sự kiện "kết nối". Lưu ý rằng bạn sẽ không có quyền truy cập vào đối tượng phản hồi trên sự kiện kết nối, chỉ có socket và bodyhead. Dữ liệu được gửi qua ổ cắm này sẽ vẫn được mã hóa cho bạn dưới dạng máy chủ proxy.

Trong giải pháp này, bạn không phải tạo chứng chỉ của riêng mình và bạn sẽ không có xung đột chứng chỉ. Lưu lượng truy cập chỉ đơn giản là proxy, không bị chặn và viết lại với các chứng chỉ khác nhau.

// Install npm dependencies first 
// npm init 
// npm install --save [email protected] 
// npm install --save [email protected] 

var httpProxy = require("http-proxy"); 
var http = require("http"); 
var url = require("url"); 
var net = require('net'); 

var server = http.createServer(function (req, res) { 
    var urlObj = url.parse(req.url); 
    var target = urlObj.protocol + "//" + urlObj.host; 

    console.log("Proxy HTTP request for:", target); 

    var proxy = httpProxy.createProxyServer({}); 
    proxy.on("error", function (err, req, res) { 
    console.log("proxy error", err); 
    res.end(); 
    }); 

    proxy.web(req, res, {target: target}); 
}).listen(8080); //this is the port your clients will connect to 

var regex_hostport = /^([^:]+)(:([0-9]+))?$/; 

var getHostPortFromString = function (hostString, defaultPort) { 
    var host = hostString; 
    var port = defaultPort; 

    var result = regex_hostport.exec(hostString); 
    if (result != null) { 
    host = result[1]; 
    if (result[2] != null) { 
     port = result[3]; 
    } 
    } 

    return ([host, port]); 
}; 

server.addListener('connect', function (req, socket, bodyhead) { 
    var hostPort = getHostPortFromString(req.url, 443); 
    var hostDomain = hostPort[0]; 
    var port = parseInt(hostPort[1]); 
    console.log("Proxying HTTPS request for:", hostDomain, port); 

    var proxySocket = new net.Socket(); 
    proxySocket.connect(port, hostDomain, function() { 
     proxySocket.write(bodyhead); 
     socket.write("HTTP/" + req.httpVersion + " 200 Connection established\r\n\r\n"); 
    } 
); 

    proxySocket.on('data', function (chunk) { 
    socket.write(chunk); 
    }); 

    proxySocket.on('end', function() { 
    socket.end(); 
    }); 

    proxySocket.on('error', function() { 
    socket.write("HTTP/" + req.httpVersion + " 500 Connection error\r\n\r\n"); 
    socket.end(); 
    }); 

    socket.on('data', function (chunk) { 
    proxySocket.write(chunk); 
    }); 

    socket.on('end', function() { 
    proxySocket.end(); 
    }); 

    socket.on('error', function() { 
    proxySocket.end(); 
    }); 

}); 
+0

Yêu ví dụ của bạn. Tôi đã tự hỏi làm thế nào bạn có thể augment nó cũng xử lý các kết nối nâng cấp websocket – lzc

+0

@ y3sh bạn vui lòng kiểm tra câu hỏi của tôi ở đây http://stackoverflow.com/questions/43908640/node-js-http-proxy-with-https? Tôi nghĩ rằng ví dụ của bạn có thể giúp tôi, nhưng tôi không biết làm thế nào để thực hiện nó .. – Valip

+0

Làm thế nào tôi có thể thêm xác thực người dùng và mật khẩu vào điều này để tôi chỉ chuyển tiếp các yêu cầu từ tôi và địa chỉ IP động của tôi? – koampapapa

Các vấn đề liên quan