Open felicienfrancois opened 8 years ago
Since https://github.com/joeferner/node-http-mitm-proxy/commit/0e40d2d550e3d815f6ef516086a34a256a398400 the onResponseData callback could be called with null chunk without breaking.
@felicienfrancois Hm, not sure I understand the proposed solution to this. I have a simple use case, I want to cache requests in memory after they have been requested one time. I'm trying to do something like this:
var Proxy = require('http-mitm-proxy')
var proxy = Proxy()
var port = 8081
var cache = {}
var chunks = []
proxy.onError(function (ctx, err) {
console.error('proxy error:', err)
})
proxy.onRequest(function (ctx, callback) {
chunks = []
callback()
})
proxy.onResponseData(function (ctx, chunk, dataCallback) {
chunks.push(chunk)
return dataCallback(null, chunk)
})
proxy.onResponseEnd(function (ctx, endCallback) {
const req = ctx.clientToProxyRequest
const url = req.url
const host = req.headers.host
cache[host + url] = chunks
return endCallback(null, chunks)
})
proxy.listen({ port: port })
console.log('listening on ' + port)
But I'm struggling to understand how I can cancel out the request and just return the cached data. Any pointers on how I can achieve that?
As always, finding the answer five seconds after asking the question. Solved it by doing something like this:
proxy.onRequest(function (ctx, callback) {
const req = ctx.clientToProxyRequest
const url = req.url
const host = req.headers.host
if (cache[host + url] !== undefined) {
ctx.proxyToClientResponse.end(cache[host + url].join())
return
}
chunks = []
callback()
})
@VictorBjelkholm Yes, that's it. I would just warn you that several requests may be handled in parallel, so having a global chunks array may not be the good solution (it can be erased before the end of the response data by another request).
Instead, you should store the chunks in the context (which sticks to one request):
ctx.chunks = []
Or define the chunks array in the context of each request like in this example: https://github.com/joeferner/node-http-mitm-proxy/blob/master/test/processFullResponseBody.js
Hah, yeah, learned that the hard way yesterday and did exactly what you said! Thanks for sharing that here though.
On Thu, Nov 26, 2015 at 10:09 AM Félicien FRANCOIS notifications@github.com wrote:
@VictorBjelkholm https://github.com/VictorBjelkholm Yes, that's it. I would just warn you that several requests may be handled in parallel, so having a global chunks array may not be the good solution (it can be erased before the end of the response data by another request).
Instead, you should store the chunks in the context (which sticks to one request):
ctx.chunks = []
— Reply to this email directly or view it on GitHub https://github.com/joeferner/node-http-mitm-proxy/issues/24#issuecomment-159853748 .
@VictorBjelkholm
Or you can try ctx.proxyToClientResponse.writeHead(504, 'Proxy Error');
Also When connection is not stopped onResponseData is still trigged and all data are loaded
So try to download 5Mb file you will see that onResponseEnd is executed even if you cancel connection, and data are still transfer, client don't get data but proxy still transfer it
__ Best solution will be to close socket connection after error, not only on this example but on time-out an on error
My TMP solution:
ctx.proxyToClientResponse.writeHead(504, 'Proxy Error'); ctx.proxyToClientResponse.end(''); ctx.serverToProxyResponse.complete = true;
Examples:
Maybe the best way is to rewrite the API with a switch to prevent default operation after the handler execution. Maybe the most transparent and intuitive way would be to test the second parameter of the callback and cancel default behavior if it is equals to
false
ornull
(but notundefined
)