Harry
Harry

Reputation: 3

Why does an http client in Go return Unauthorized via a proxy when making an https request?

I've been trying to make a GET request from a client I've been working on in Go, via a proxy.

The curl equivalent may look a bit like this:

curl -v -x example.proxy.com:8080 -U username:password 'https://example.com'

While something like this will work, the equivalent in Go does not seem to, here's an example:

auth := "username:password"

basic := "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))

proxyURL, _ := url.Parse("http://example.proxy.com:8080")
url, _ := url.Parse("https://example.com")

transport := &http.Transport{
    Proxy: http.ProxyURL(proxyURL),
}
client := &http.Client{
    Transport: transport,
}

request, _ := http.NewRequest("GET", url.String(), nil)
request.Header.Add("Proxy-Authorization", basic)
request.Header.Add("Proxy-Connection", "Keep-Alive")

response, _ := client.Do(request)

The only difference between the two is that the curl command will be successful when making requests to both http and https urls, the Go code will work over http, but in the example above (https://example.com, or any other https URL), this will return a status of Unauthorized.

I feel like I'm missing something really obvious here, but can't seem to get to the bottom of it.

Upvotes: 0

Views: 1166

Answers (1)

Mr_Pink
Mr_Pink

Reputation: 109357

You are setting a header on the http.Request that is being sent to the upstream server, not the proxy. You can set basic auth in the proxy *url.URL:

proxyURL, _ := url.Parse("http://127.0.0.1:8080")
proxyURL.User = url.UserPassword("username", "password")

client := &http.Client{
    Transport: &http.Transport{
        Proxy: http.ProxyURL(proxyURL),
    },
}

Upvotes: 1

Related Questions