node-http-proxy
node-http-proxy copied to clipboard
Document `forward` vs. `target`
After reading the docs and examples, the purpose and distinction between forward and target is still not clear to me (including forward-and-target-proxy.js example - I can't tell what this is actually demonstrating). After implementing a very simple single-step target proxy behind Express, I wanted to place a transparent forward proxy in between Node and backend server in order to cache some large, expensive API requests. I was not successful with any permutation of forward or target options. My intuition was that target would be used to "fix up" the outbound request (setupOutgoing), while forward would be the immediate server to hand off to (the local caching proxy). It appears that changeOrigin will use the forward host, not the target host. This is likely due to logic in stream and setupOutgoing that appears to modify the request for both cases. I'm not sure I understand the precedence of the piping. Also forward will not convert a relative path request to an absolute URL request required by an upstream transparent HTTP proxy.
It would be nice to have a some more docs on how to use forward and target in combination or separately, and whether handoff to transparent proxy is supported out of the box (e.g. inference from combination of forward and target would be nice).
I managed to manually perform these fixups when in 'transparent handoff' mode as advised on StackOverflow:
opts = target: remoteServer
if process.argv[2]?
localProxy = process.argv[2]
opts.forward = localProxy
opts.toProxy = true
opts.prependPath = false # fix it up ourselves
console.log "Proxying #{apiRoot} to #{remoteServer}" + (if localProxy? then " via #{localProxy}" else "")
proxy = httpProxy.createProxyServer opts
app.use apiRoot, (req, res, next) ->
console.log "Proxying: #{req.method} #{req.path} to #{remoteServer}"
console.log "Original URL #{req.url}"
console.log "Original Host #{req.headers.host}"
# explicitly fix up host and request url if forwarding to local proxy
if localProxy?
remote = url.parse(remoteServer)
incoming = url.parse(req.url)
req.headers.host = remote.host
# update the host and path to match remote target
incoming.protocol = remote.protocol
incoming.host = remote.host
incoming.pathname = remote.pathname + incoming.pathname
req.url = url.format(incoming)
console.log "Outbound Host #{req.headers.host}"
console.log "Outbound URL #{req.url}"
proxy.web req, res, (e) ->
console.log e
Citation from damonmcminn's an answer;
http.createServer(function(req, res) {
/* target NOT forward
* target === final server to receive request
* forward === another proxy server to pass request through
*/
var options = {
target: targets[req.headers.host]
};
proxy.web(req, res, options, errorCallback); // errorCallback is optional
}).listen(1443);
+1, the documentation should definitely explain the difference between target and forward.
+1 on putting this:
* target === final server to receive request
* forward === another proxy server to pass request through
in the readme.
https://github.com/nodejitsu/node-http-proxy/issues/917 yuuup, still really unclear and missing from the doc.
I had to look to find this post, it's istll unclear in the doc right now.
it's 2018.9.12
It seems "forward" does not send the response back to the requesting side. In fact, docs says exactly that:
/**
* Does the actual proxying. If `forward` is enabled fires up
* a ForwardStream, same happens for ProxyStream. **The request
* just dies otherwise.**
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {Object} Options Config object passed to the proxy
*
* @api private
*/
stream: function stream(req, res, options, _, server, clb) {
Note, the The request just dies otherwise.
Source code follows the docs (from /node-http-proxy/lib/http-proxy/passes/web-incoming.js):
if(options.forward) {
// If forward enable, so just pipe the request
...
if(!options.target) { return res.end(); }
}
Note, the return res.end(). The empty response is sent back.
It seems, when one need to forward the request to another proxy, that proxy should still be specified in the "target" field. The "changeOrigin" should be set to "false". The "toProxy" option didn't make any difference in my experiments, but keeping it in "true" did not harm.
The intention of the "forward" option is still very much unclear.
2020.05.29 it's still unclear
I believe the functionality of forward was accurately described in the README of the previous incarnation of node-http-proxy, see https://github.com/http-party/node-http-proxy/tree/840f6d8d29dffc11d3726123c2d400940ca2bdda#proxy-requests-with-an-additional-forward-proxy
Proxy requests with an additional forward proxy
Sometimes in addition to a reverse proxy, you may want your front-facing server to forward traffic to another location. For example, if you wanted to load test your staging environment. This is possible when using node-http-proxy using similar JSON-based configuration to a proxy table: …
It seems when the entire project was rewritten in https://github.com/http-party/node-http-proxy/pull/552, the functionality was preserved but the documentation went away.