How to listen for node http-proxy traffic?

I am using node-http-proxy . However, in addition to relaying HTTP requests, I also need to listen to incoming and outgoing data.

Intercepting response data is where I fear. The Node ServerResponse object (and the more general WritableStream interface) does not dispatch the 'data' event. http-proxy seems to create its own internal request, which creates a ClientResponse object (which broadcasts the 'data' event), however this object is not published publicly outside the proxy.

Any ideas on how to solve this problem without intercepting node-http-proxy monkeys or creating a wrapper around the response object?

+4
source share
3 answers

A related issue in node-http-proxy issues on Github seems to imply that this is not possible. For future attempts by others, here is how I cracked the problem:

  • you will quickly find out that the proxy only calls the writeHead() , write() and end() methods of the res object
  • since res already an EventEmitter , you can fire new custom events
  • listen to these new events to collect response data and then use it
 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) 
+5
source

This is a simple proxy server that sniffs traffic and writes to the console:

 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
source

I tried your hack, but it did not work for me. My use case is simple: I want to register incoming and outgoing traffic from an Android application to our intermediate server, which is protected by basic auth.

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

was a decision for me. My node-http-proxy always returned 500 (while the direct request to the stage was not executed). Perhaps the authorization headers will not be sent correctly or something else.

Hoxy did a great job right from the start.

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

As the rules for logging, I indicated:

 request: $aurl.log() request: @log-headers() request: $method.log() request: $request-body.log() response: $url.log() response: $status-code.log() response: $response-body.log() 

Beware, this prints any binary content.

0
source

Source: https://habr.com/ru/post/1401866/


All Articles