HTTPS proxies support in Go 1.10

Michał Łowicki
2 min readFeb 21, 2018

--

Couple of days ago Go 1.10 has been released — six months after 1.9. New version brings bigger and smaller changes (release notes) but I would like to discuss one related to net/http package. Version 1.10 supports proxies talking over HTTPS (commit). Previously it was possible to communicate only with proxies using plain (unencrypted) HTTP. Let’s create an environment to confirm it actually works.

Server

To test this change please launch simple HTTP(S) proxy server written in Golang:

Client

package mainimport (
"crypto/tls"
"fmt"
"net/http"
"net/http/httputil"
"net/url"
)
func main() {
u, err := url.Parse("https://localhost:8888")
if err != nil {
panic(err)
}
tr := &http.Transport{
Proxy: http.ProxyURL(u),
// Disable HTTP/2.
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://google.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
dump, err := httputil.DumpResponse(resp, true)
if err != nil {
panic(err)
}
fmt.Printf("%q", dump)
}

1.9 vs 1.10

> go version
go version go1.10 darwin/amd64
> go run proxyclient.go
"HTTP/1.1 200 OK\r\nTransfer-Encoding: ...
> go version
go version go1.9 darwin/amd64
> go run proxyclient.go
panic: Get https://google.com: malformed HTTP response "\x15\x03\x01\x00\x02\x02\x16"
...

In the first output where Go 1.10 is used we’ve received correct response from https://google.com proxied by server listening on https://localhost:8888. 2nd result shows that HTTP client in Go 1.9 is confused.

👏👏👏 below to help others discover this story. Please follow me here or on Twitter if you want to get updates about new posts or boost work on future stories.

--

--

Michał Łowicki

Software engineer at Datadog, previously at Facebook and Opera, never satisfied.