Standard HTTP library in Go reads the environment variables HTTP_PROXY
, HTTPS_PROXY
, and NO_PROXY
. But in some situations, those variables are ignored. On the other hand, the developer may want to disable the reading of those variables.
🇨🇿 V češtině si lze článek přečíst na kutac.cz
A proxy might be useful to go over the firewall of a company network when access to some sites is blocked. But a proxy is often used to debug and inspect communication during development. For example tools like HTTP Toolkit creates a local proxy server.
Every program in Go using net/http
will read HTTP(S)_PROXY
and NO_PROXY
variables and acts accordingly. But what if the developer wants to be sure, users cannot use proxy at all? The code below is an example for explaining further issues.
func main() {
fmt.Println(os.Getenv("HTTP_PROXY"))
client := &http.Client{}
resp, err := client.Get("http://localhost:8090/vm/1")
if err != nil {
log.Fatal(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))
}
I set HTTP_PROXY and it is ignored
In the code above the content of HTTP_PROXY
is printed out and then called GET
request. But even if the value is set correctly, it is ignored. The main reason is the request is made to localhost which is ignored as well as 127.x.x.x. Luckily it is easy to go around this.
It is enough to set custom domain in /etc/hosts
on Linux or C:\Windows\System32\drivers\etc\hosts
on Windows by adding 127.0.0.1 localserver.loc
and then change the code above.
resp, err := client.Get("http://localserver.loc:8090/vm/1")
This is documented behavior, but quite deeply. You can find it in source opensource.google/x/net/http/httpproxy/proxy.go line 118 and on line 181 is exact if which is responsible for that.
How to disable reading PROXY environment variables
You can use variable NO_PROXY
to set which URLs will never go through a proxy. You can specify all with NO_PROXY=*
or list URLs delimited by comma. But what to do if you as a developer wants to ignore all those variables? Then the own Transport
of HTTP Client must be set.
transport := http.DefaultTransport
transport.(*http.Transport).Proxy = nil
client := &http.Client{
Transport: transport,
}
Top comments (0)