Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js - Create a proxy, why is request.pipe needed?

Tags:

node.js

Can some one explain this code to create a proxy server. Everything makes sense except the last block. request.pipe(proxy - I don't get that because when proxy is declared it makes a request and pipes its response to the clients response. What am I missing here? Why would we need to pipe the original request to the proxy because the http.request method already makes the request contained in the options var.

var http = require('http');

function onRequest(request, response) {
    console.log('serve: ' + request.url);

    var options = {
        hostname: 'www.google.com',
        port: 80,
        path: request.url,
        method: 'GET'
    };

    var proxy = http.request(options, function (res) {
        res.pipe(response, {
            end: true
        });
    });

    request.pipe(proxy, {
        end: true
    });
}

http.createServer(onRequest).listen(8888);
like image 622
SukyaMaki Avatar asked Mar 30 '14 03:03

SukyaMaki


1 Answers

What am I missing here? [...] the http.request method already makes the request contained in the options var.


http.request() doesn't actually send the request in its entirety immediately:

[...] With http.request() one must always call req.end() to signify that you're done with the request - even if there is no data being written to the request body.

The http.ClientRequest it creates is left open so that body content, such as JSON data, can be written and sent to the responding server:

var req = http.request(options);

req.write(JSON.stringify({
    // ...
}));

req.end();

.pipe() is just one option for this, when you have a readable stream, as it will .end() the client request by default.


Although, since GET requests rarely have a body that would need to be piped or written, you can typically use http.get() instead, which calls .end() itself:

Since most requests are GET requests without bodies, Node provides this convenience method. The only difference between this method and http.request() is that it sets the method to GET and calls req.end() automatically.

http.get(options, function (res) {
    res.pipe(response, {
        end: true
    });
});
like image 133
Jonathan Lonowski Avatar answered Sep 20 '22 15:09

Jonathan Lonowski