Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple node.js proxy by piping http server to http request

Trying to learn more about node.js by making a simple http proxy server. The use scenario is simple: user -> proxy -> server -> proxy -> user

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.

What is the proper way to implement this logic with pipes?

like image 263
Nikolai Gorchilov Avatar asked Nov 20 '12 11:11

Nikolai Gorchilov


People also ask

How do I proxy a request in Node JS?

The server is built with the Node.js http library, and uses the request library from npm to send the external HTTP request that is proxied. Node.js code to proxy a request Before jumping into the example, this is the line of code to proxy a request in Node.js: req.pipe (request (' [URL_TO_PROXY]')).pipe (res);

How to make a simple HTTP proxy server?

Trying to learn more about node.js by making a simple http proxy server. The use scenario is simple: user -> proxy -> server -> proxy -> user The following code works until the last step.

Do I need Express to use HTTP-proxy?

The http-proxy package doesn't require you to use Express. You can also use Node's built-in HTTPServer class: With a proxy server, there's two HTTP requests: the inbound request that the proxy server received, and the outbound request that the proxy server sends. In the previous examples, the inbound request is the same as the outbound request.

What are the two types of HTTP requests sent by proxy servers?

With a proxy server, there's two HTTP requests: the inbound request that the proxy server received, and the outbound request that the proxy server sends. In the previous examples, the inbound request is the same as the outbound request.


2 Answers

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

like image 50
Jay Avatar answered Sep 20 '22 14:09

Jay


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

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();
});
like image 32
Nikolai Gorchilov Avatar answered Sep 21 '22 14:09

Nikolai Gorchilov