When using net/http ProxyFromEnvironment to specify proxy using HTTP_PROXY environment variable, there is a special case to prevent use of a proxy when connecting to a localhost or 127.0.0.1 service.
Using a debugging proxy with local services is a common practice, and it was surprising to find this special case, as I can't find any logical reason why it is included. I did find it was documented (discussed in History below), but the document only describes the code and not any reason why. This behavior is surprising, which is the worst part, because it required debugging and work to figure out why my proxy wasn't working. The proxy works great for everything until someone tries to point to localhost. I would expect to be able to use a proxy to localhost. Why not? Surely, there's a reason. Here's what I dug up. *History* Here's my best attempt at reconstructing the history behind this change. 1. Issue which prompted the change: https://github.com/golang/go/issues/1589 It appears that this was introduced to fix tests. @rsc: > [...] we should not use $http_proxy for 127.0.0.1. This statement doesn't imply that this should be a universal law, but seems to apply only to this issue. 2. Commit which introduced the localhost and loopback special case: https://github.com/golang/go/commit/8dad7fec1d3c12a7ff50c2ad5178f4b77d4e48ef As a result of issue 1589, instead of fixing this for just the tests, proxy to localhost requests was disabled for ALL future usage of ProxyFromEnvironment. My best guess is that it was simply a hasty decision to fix some broken tests, but had further consequences than was probably intended. I can't find any other reason for including this special case in such a widely used package as net/http. An alternative solution may have been to use NO_PROXY="localhost 127.0.0.1" in the calling code that required such behavior. 3. Issue which raises the same question I'm asking, but results in only documentation being changed. https://github.com/golang/go/issues/7256 @bradfitz: > I don't remember why we do that. (in func useProxy) > If we have to keep it, it at least needs to be documented. Commit with documentation change: https://codereview.appspot.com/97590043 Documentation now reads: As a special case, if req.URL.Host is "localhost" (with or without a port > number), then a nil URL and nil error will be returned. 4. Current code looks to be at https://github.com/golang/go/blob/master/src/vendor/golang_org/x/net/http/httpproxy/proxy.go#L183-L191 (net/http uses x/net/http/httpproxy as the implementation) The special case of not proxying for localhost and loopback IPs is retained in the relocated code. *Pre-Proposal Feedback* Before I write a proposal to change- I thought I'd reach out to see if anyone knew a deeper reason why this is the case. This is what I would propose: 1. Remove the localhost and loopback restriction for using a proxy in the net/http (and now x/net/http/httpproxy) package. 2. Fix any broken tests by using NO_PROXY environment variable (or some other equivalent mechanism). Reasons: 1. Eliminate surprising library behavior. 2. The restriction is artificial, and prompts workarounds which shouldn't be necessary. 3. Could be serious if a user expects the proxy to be used when actually the proxy is being ignored. Implications: I'm not quite sure the impact of this change. More research would be needed. The obvious impact would be: 1. Any usage of ProxyFromEnvironment which relies on the special case of not proxying to localhost requests will now actually use the proxy. As far as knowing how many people rely on this behavior, I can't say at this point. The consequence of proxying isn't well known either because that is application-specific. My gut says this would be odd to require this behavior. Thanks, Kekoa -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.