2

举一个我想要实现的简短示例,假设我们有一个 HTTP 服务器已经在为给定的请求提供服务:

require('http').createServer(function(req, res) {
    var payload = new Buffer('Hello World\n', 'utf8');
    res.writeHead(200, {
        'Content-Type': 'text/plain',
        'Content-Length': payload.length,
        'Connection': 'Keep-Alive'
    });
    res.end(payload);
}).listen(8888);

现在,考虑接收请求的第二个 HTTP 服务器的存在,为了服务它,它需要调用第一个服务器。(例如,当我们有一个需要调用给定 RESTful 端点的 Web 应用程序时的经典场景)。

var http = require('http');
http.createServer(function(req, res) {

    var fwdrq = http.request({
        hostname: 'localhost',
        port: 8888,
        path: '/',
        method: 'GET'
    });

    fwdrq.on('response',function(response){
        response.pipe(res);
    });

    fwdrq.on('error', function(error){
        console.log(error);
    });

    fwdrq.end();

}).listen(9999);

现在,我喜欢将原始请求与第二台服务器完成的内部请求的响应进行管道传输的想法,这非常方便,这正是我所需要的。但在我将响应发送回客户端之前,我希望有机会从第一台服务器发送的响应中删除任何逐跳标头。我肯定想要整个有效负载,并且我想要它的响应中的一些标头,但肯定不是全部。

例如,我想避免发送像 Proxy-Authenticate 或 Connection 这样的标头,或者任何被认为是逐跳标头的标头。另外,如果我希望我的第二台服务器这样操作,我想考虑不发回保持活动状态的可能性,等等。

我知道如何在响应传递之前添加标头,但是一旦通过管道传输,我不知道如何从管道传输的响应中删除标头。

不要误会我的意思,我知道我可以通过订阅事件然后自己构建响应来做到这一点,但我想知道如果我正在管道响应,这是否仍然可行。

有没有人知道如何实现这个技巧?

4

1 回答 1

3

根据我对pipe的测试,只有有效负载被管道传输,而不是标头。

打开 Chrome 开发者控制台(Firefox 上的 Firebug,桌面上的 Fiddler)并查看从服务器返回的 HTTP 响应。来自上游服务器的标头不会传回给最终用户。如果您在代理服务器上手动添加标头,您会看到它们确实显示给最终用户。

var http = require('http');

http.createServer(function(req, res) {
    var payload = new Buffer('Hello World\n', 'utf8');
    res.writeHead(200, {
        'Content-Type': 'text/plain',
        'Content-Length': payload.length,
        'Connection': 'Keep-Alive',
        'UpstreamHeader': 'Test'
    });
    res.end(payload);
}).listen(8888);

http.createServer(function(req, res) {

    var fwdrq = http.request({
        hostname: 'localhost',
        port: 8888,
        path: '/',
        method: 'GET'
    });

    //Uncomment the lines below to add headers from the proxy server
    /*res.writeHead(200, {
        'ProxyHeader': 'Test'
    });*/

    fwdrq.on('response', function(response) {
        response.pipe(res);
    });

    fwdrq.on('error', function(error) {
        console.log(error);
    });

    fwdrq.end();

}).listen(80);
于 2015-03-22T20:43:51.457 回答