77

I'm trying to setup the HTTP client so that it uses a proxy, however I cannot quite understand how to do it. The documentation has multiple reference to "proxy" but none of the functions seem to allow to define the proxy. What I need is something like this:

client := &http.Client{}
client.SetProxy("someip:someport") // pseudo code
resp, err := client.Get("http://example.com") // do request through proxy

Any idea how to do this in Go?

6 Answers 6

161

lukad is correct, you could set the HTTP_PROXY environment variable, if you do this Go will use it by default.

Bash:

export HTTP_PROXY="http://proxyIp:proxyPort"

Go:

os.Setenv("HTTP_PROXY", "http://proxyIp:proxyPort")

You could also construct your own http.Client that MUST use a proxy regardless of the environment's configuration:

proxyUrl, err := url.Parse("http://proxyIp:proxyPort")
myClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}}

This is useful if you can not depend on the environment's configuration, or do not want to modify it.

You could also modify the default transport used by the "net/http" package. This would affect your entire program (including the default HTTP client).

proxyUrl, err := url.Parse("http://proxyIp:proxyPort")
http.DefaultTransport = &http.Transport{Proxy: http.ProxyURL(proxyUrl)}
Sign up to request clarification or add additional context in comments.

6 Comments

In fact, I need to concurrently send several requests, each using a different proxy, so your second solution is probably what I need. However, it doesn't seem to be working, I'm getting this error for all the proxies: Get http://stackoverflow.com: http: error connecting to proxy 87.236.233.92:8080: GetServByName: The requested name is valid, but no data of the requested type was found. Any idea what it means?
I got my answer to this question there - stackoverflow.com/q/14669958/561309
@voidlogic setting the env variable didn't work for me. I have to pass it to the http.Transport
If your proxy requires an username and password along with IP, the export HTTP_PROXY="http://proxyIp:proxyPort" becomes export HTTP_PROXY="http://PROXY_LOGIN:PROXY_PASS@proxyIp:proxyPort"
If you are requesting an HTTPS address, you should also add HTTPS_PROXY environment variable
|
16

Go will use the the proxy defined in the environment variable HTTP_PROXY if it's set. Otherwise it will use no proxy.

You could do it like this:

os.Setenv("HTTP_PROXY", "http://someip:someport")
resp, err := http.Get("http://example.com")
if err != nil {
    panic(err)
}

1 Comment

FYI -- the return after the panic is redundant.
8

May you could also try this:

url_i := url.URL{}
url_proxy, _ := url_i.Parse(proxy_addr)

transport := http.Transport{}    
transport.Proxy = http.ProxyURL(url_proxy)// set proxy 
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //set ssl

client := &http.Client{}
client.Transport = transport
resp, err := client.Get("http://example.com") // do request through proxy

3 Comments

I think you mean: transport := &http.Transport{}
make sure you actually want InsecureSkipVerify before you paste this in to your code
hint: you don't want InsecureSkipVerify
3

The Go built-in proxy use is briefly documented in the DefaultTransport:

// DefaultTransport .... It uses HTTP proxies
// as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and
// $no_proxy) environment variables.
var DefaultTransport RoundTripper = &Transport{
    Proxy: ProxyFromEnvironment,

This points to the usefulness of creating custom Transports from DefaultTransport vs. from scratch to take advantage of the built-in ProxyFromEnvironment function

Comments

0

For an alternative way, you can also use GoRequest which has a feature that you can set proxy easily for any single request.

request := gorequest.New()
resp, body, errs:= request.Proxy("http://proxy:999").Get("http://example.com").End()
resp2, body2, errs2 := request.Proxy("http://proxy2:999").Get("http://example2.com").End()

Or you can set for the whole at once.

request := gorequest.New().Proxy("http://proxy:999")
resp, body, errs:= request.Get("http://example.com").End()
resp2, body2, errs2 := request.Get("http://example2.com").End()

1 Comment

gorequest does not support socks proxies
0

If you run something like this:

HTTP_PROXY=89.x.y.z path_to_program

Then the HTTP_PROXY setting is set for that command only, which is useful if you don't want to set it for the whole shell session. Note: there's no ; between the setting and the path; if you put a semicolon, it would set (but not export) HTTP_PROXY for that shell

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.