Trying to learn more about node.js by making a simple http proxy server. The use scenario is simple: user -> proxy -> server -> proxy -> user
试图了解更多关于node的信息。通过创建一个简单的http代理服务器。使用场景很简单:用户—>代理—>服务器—>代理—>用户
The following code works until the last step. Couldn't find way to pipe connector's output back to the user.
下面的代码一直工作到最后一步。无法找到将连接器的输出传输回用户的方法。
#!/usr/bin/env node
var
url = require('url'),
http = require('http'),
acceptor = http.createServer().listen(3128);
acceptor.on('request', function(request, response) {
console.log('request ' + request.url);
request.pause();
var options = url.parse(request.url);
options.headers = request.headers;
options.method = request.method;
options.agent = false;
var connector = http.request(options);
request.pipe(connector);
request.resume();
// connector.pipe(response); // doesn't work
// connector.pipe(request); // doesn't work either
});
Using tcpflow I see the incoming request from the browser, then the outgoing proxy request, then the server response back to the proxy. Somehow i couldn't manage to retransmit the response back to the browser.
使用tcpflow,我可以看到来自浏览器的传入请求,然后是传出的代理请求,然后是服务器对代理的响应。不知何故,我无法将响应重新发送回浏览器。
What is the proper way to implement this logic with pipes?
用管道实现这种逻辑的正确方法是什么?
3 个解决方案
#1
21
you dont have to 'pause', just 'pipe' is ok
你不需要“暂停”,只要“烟斗”就可以了
var connector = http.request(options, function(res) {
res.pipe(response, {end:true});//tell 'response' end=true
});
request.pipe(connector, {end:true});
http request will not finish until you tell it is 'end';
http请求直到你告诉它“结束”才会结束;
#2
21
OK. Got it.
好的。明白了。
UPDATE: NB! As reported in the comments, this example doesn't work anymore. Most probably due to the Streams2 API change (node 0.9+)
更新:注意!正如在评论中所报道的,这个示例不再有效。最可能的原因是Streams2 API的更改(节点0.9+)
Piping back to the client has to happen inside connector's callback as follows:
回到客户端的管道必须在连接器的回调中发生,如下所示:
#!/usr/bin/env node
var
url = require('url'),
http = require('http'),
acceptor = http.createServer().listen(3128);
acceptor.on('request', function(request, response) {
console.log('request ' + request.url);
request.pause();
var options = url.parse(request.url);
options.headers = request.headers;
options.method = request.method;
options.agent = false;
var connector = http.request(options, function(serverResponse) {
serverResponse.pause();
response.writeHeader(serverResponse.statusCode, serverResponse.headers);
serverResponse.pipe(response);
serverResponse.resume();
});
request.pipe(connector);
request.resume();
});
#3
1
I used the examples from this post to proxy http/s requests. Faced with the problem that cookies were lost somewhere.
我使用了本文中的示例来代理http/s请求。面对饼干在某处丢失的问题。
So to fix that you need to handle headers from the proxy response.
为了解决这个问题,你需要处理来自代理响应的头信息。
Below the working example:
以下工作的例子:
req = service.request(options, function(res) {
response.writeHead(res.statusCode, res.headers);
return res.pipe(response, {end: true});
});
request.pipe(req, {end: true});
#1
21
you dont have to 'pause', just 'pipe' is ok
你不需要“暂停”,只要“烟斗”就可以了
var connector = http.request(options, function(res) {
res.pipe(response, {end:true});//tell 'response' end=true
});
request.pipe(connector, {end:true});
http request will not finish until you tell it is 'end';
http请求直到你告诉它“结束”才会结束;
#2
21
OK. Got it.
好的。明白了。
UPDATE: NB! As reported in the comments, this example doesn't work anymore. Most probably due to the Streams2 API change (node 0.9+)
更新:注意!正如在评论中所报道的,这个示例不再有效。最可能的原因是Streams2 API的更改(节点0.9+)
Piping back to the client has to happen inside connector's callback as follows:
回到客户端的管道必须在连接器的回调中发生,如下所示:
#!/usr/bin/env node
var
url = require('url'),
http = require('http'),
acceptor = http.createServer().listen(3128);
acceptor.on('request', function(request, response) {
console.log('request ' + request.url);
request.pause();
var options = url.parse(request.url);
options.headers = request.headers;
options.method = request.method;
options.agent = false;
var connector = http.request(options, function(serverResponse) {
serverResponse.pause();
response.writeHeader(serverResponse.statusCode, serverResponse.headers);
serverResponse.pipe(response);
serverResponse.resume();
});
request.pipe(connector);
request.resume();
});
#3
1
I used the examples from this post to proxy http/s requests. Faced with the problem that cookies were lost somewhere.
我使用了本文中的示例来代理http/s请求。面对饼干在某处丢失的问题。
So to fix that you need to handle headers from the proxy response.
为了解决这个问题,你需要处理来自代理响应的头信息。
Below the working example:
以下工作的例子:
req = service.request(options, function(res) {
response.writeHead(res.statusCode, res.headers);
return res.pipe(response, {end: true});
});
request.pipe(req, {end: true});