如何监听节点的http-proxy流量?

时间:2012-03-16 17:12:03

标签: http node.js proxy

我正在使用node-http-proxy。但是,除了中继HTTP请求之外,我还需要监听传入和传出的数据。

拦截响应数据是我挣扎的地方。节点的ServerResponse对象(更通常是WritableStream接口)不会广播'data'事件。 http-proxy似乎创建了它自己的内部请求,它产生了一个ClientResponse对象(它确实广播了'data'事件)但是这个对象没有公开地暴露在代理之外。

如果没有使用Monkey-patching node-http-proxy或在响应对象周围创建包装器,如何解决这个问题?

3 个答案:

答案 0 :(得分:5)

Github上node-http-proxy问题的相关问题似乎暗示这是不可能的。对于其他人未来的尝试,以下是我黑客攻击问题的方法:

  • 您很快就会发现代理只调用writeHead()对象的write()end()res方法
  • 由于res已经是EventEmitter,您可以开始发布新的自定义事件
  • 听取这些新事件来汇总响应数据,然后使用它
var eventifyResponse = function(res) {
  var methods = ['writeHead', 'write', 'end'];
  methods.forEach(function(method){
    var oldMethod = res[method]; // remember original method
    res[method] = function() {   // replace with a wrapper
      oldMethod.apply(this, arguments); // call original method
      arguments = Array.prototype.slice.call(arguments, 0);
      arguments.unshift("method_" + method);
      this.emit.apply(this, arguments); // broadcast the event
    };
  });
};

res = eventifyResponse(res), outputData = '';

res.on('method_writeHead', function(statusCode, headers) { saveHeaders(); });
res.on('method_write',     function(data) { outputData += data; });
res.on('method_end',       function(data) { use_data(outputData + data); });
proxy.proxyRequest(req, res, options)

答案 1 :(得分:2)

这是一个简单的代理服务器,可以嗅探流量并将其写入控制台:

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

//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});

// assign events
proxy.on('proxyRes', function (proxyRes, req, res) {

    // collect response data
    var proxyResData='';
    proxyRes.on('data', function (chunk) {
        proxyResData +=chunk;
    });
    proxyRes.on('end',function () {


        var snifferData =
        {
            request:{
                data:req.body,
                headers:req.headers,
                url:req.url,
                method:req.method},
            response:{
                data:proxyResData,
                headers:proxyRes.headers,
                statusCode:proxyRes.statusCode}
        };
        console.log(snifferData);
    });

    //    console.log('RAW Response from the target', JSON.stringify(proxyRes.headers, true, 2));
});


proxy.on('proxyReq', function(proxyReq, req, res, options) {
    // collect request data
    req.body='';
    req.on('data', function (chunk) {
        req.body +=chunk;
    });
    req.on('end', function () {
    });

});

proxy.on('error',
    function(err)
    {
        console.error(err);
    });

// run the proxy server
var server = http.createServer(function(req, res) {

    // every time a request comes proxy it:
    proxy.web(req, res, {
        target: 'http://localhost:4444'
    });

});

console.log("listening on port 5556")
server.listen(5556);

答案 2 :(得分:0)

我试过你的黑客,但它对我不起作用。我的用例很简单:我想将来自Android应用程序的输入和输出流量记录到由基本身份验证保护的登台服务器。

https://github.com/greim/hoxy/

对我来说是解决方案。我的node-http-proxy总是返回500(而直接请求阶段没有)。也许授权标题不会被正确转发或者其他任何内容。

Hoxy从一开始就做得很好。

npm install hoxy [-g]
hoxy --port=<local-port> --stage=<your stage host>:<port>

作为我指定的日志记录规则:

request: $aurl.log()
request: @log-headers()
request: $method.log()
request: $request-body.log()


response: $url.log()
response: $status-code.log()
response: $response-body.log()

请注意,这会打印任何二进制内容。