如何侦听节点http代理流量?

如何侦听节点http代理流量?,http,node.js,proxy,Http,Node.js,Proxy,我正在使用。然而,除了中继HTTP请求之外,我还需要监听传入和传出的数据 截取响应数据是我努力的方向。节点的ServerResponse对象(更一般地说是writeablestream接口)不广播'data'事件http proxy似乎创建了它自己的内部请求,该请求生成一个ClientResponse对象(它会广播“数据”事件),但是该对象不会公开在代理之外 如何解决这个问题而不使用猴子修补节点http代理或在响应对象周围创建包装器?Github上节点http代理问题中的相关问题似乎暗示这是不可

我正在使用。然而,除了中继HTTP请求之外,我还需要监听传入和传出的数据

截取响应数据是我努力的方向。节点的
ServerResponse
对象(更一般地说是
writeablestream
接口)不广播
'data'
事件
http proxy
似乎创建了它自己的内部请求,该请求生成一个ClientResponse对象(它会广播
“数据”
事件),但是该对象不会公开在代理之外


如何解决这个问题而不使用猴子修补节点http代理或在响应对象周围创建包装器?Github上节点http代理问题中的相关问题似乎暗示这是不可能的。对于其他人的未来尝试,以下是我如何破解该问题的:

  • 您很快就会发现代理只调用
    res
    对象的
    writeHead()
    write()
    end()
    方法
  • 由于
    res
    已经是
    EventEmitter
    ,您可以开始发送新的自定义事件
  • 侦听这些新事件以组装响应数据,然后使用它
var eventifysponse=函数(res){
var方法=['writeHead','write','end'];
方法。forEach(函数(方法){
var oldMethod=res[method];//记住原始方法
res[method]=function(){//替换为包装器
apply(this,arguments);//调用原始方法
arguments=Array.prototype.slice.call(参数,0);
参数.unshift(“方法”+method);
this.emit.apply(this,arguments);//广播事件
};
});
};
res=事件响应(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);});
proxyRequest(请求、恢复、选项)

我试过你的破解方法,但对我无效。我的用例很简单:我想将Android应用程序的进出流量登录到我们的暂存服务器,该服务器由basic auth保护

这是我的解决办法。我的节点http代理始终返回500(而对stage的直接请求没有返回)。也许授权头不会被正确转发,或者其他什么

霍西从一开始就表现得很好

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

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

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

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

太好了,谢谢!但是,在将头发送回客户端之前,我需要重写头。您的示例只是侦听/录制数据,但不会更改数据。在发送回客户机之前,你知道如何实际更改吗?@Tauren-如果你需要发送修改后的数据,你真的需要3件事:1。读取传入数据,2。修改它,3。继续发送。
节点http代理的全部要点是封装代理过程,而在您的情况下,它并不会对您有多大帮助。因此,我建议使用node的内置HTTP服务器和mikeal的优秀HTTP客户端将您的代理修补在一起。谢谢您的反馈。这与我得出的结论相同,但我希望有某种方法可以实现这一点,并且仍然使用节点http代理。它解决了我99%的需求,但有一个问题给我带来了麻烦。我如何才能让代码正常工作?我将浏览器配置为使用端口5556,但在导航到不同网站时,控制台中没有显示任何内容。。。
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);