如何使用代理进行https请求

7

我可以在不设置代理的情况下执行http或https客户端请求。

enter code here
tr := &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},     
}

client := &http.Client{}
client.Transport = tr

request, err := http.NewRequest("HEAD", "http://www.???.com", nil)
request.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36")

resp, err := client.Do(request)

if err != nil {
    log.Fatalln(err)
    return
}
defer resp.Body.Close()

httpcode = resp.Status

这个脚本正常工作,当我请求https网址时,返回200 ok状态码,但如果我设置代理,脚本就会出问题:

proxyString := "https://47.91.179.xxx:443"
proxyUrl, _ := url.Parse(proxyString)

tr := &http.Transport{
    Proxy: http.ProxyURL(proxyUrl),
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 
    
}

client := &http.Client{}
client.Transport = tr

....................

我总是得到“Bad request”错误,我阅读了文档:https://golang.org/pkg/net/http/

........... 从Go 1.6开始,当使用HTTPS时,http包对HTTP/2协议有透明支持。必须禁用HTTP/2的程序可以通过将Transport.TLSNextProto(用于客户端)或Server.TLSNextProto(用于服务器)设置为非nil、空映射来实现。另外,目前支持以下GODEBUG环境变量: ..............

因此,我试图停止http2:

tr := &http.Transport{
    Proxy: http.ProxyURL(proxyUrl),
    //Proxy: http.ProxyFromEnvironment,
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    TLSNextProto:    make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
}

出现了相同的问题,"Bad request"。我尝试了 os.Setenv("HTTPS_PROXY", "47.91.???.???:443"),但结果还是一样。 这个问题被记录在服务器上:

{S;}220.255.95.68{S;}-{S;}07/Mar/2017:17:01:47 +0800{S;}CONNECT www.panpacific.com:443 HTTP/1.1{S;}400{S;}173{S;}340{S;}-{S;}-{S;}-{S;}-{S;}-{S;}www.panpacific.com

所以,Golang是否支持通过代理进行https客户端请求?我如何获得正确的结果?

我已经使用我的代理服务器测试了你的代码,它运行良好。这可能是你的代理配置问题。你尝试过使用普通的网络浏览器来访问这个代理吗? - IanB
你好,IanB 你的代理服务器是什么?我使用nginx(反向代理)。 你是否使用[TLSNextProto]来停止http2? - Operations Zhang Jun
我使用Squid代理。不,我没有指定TLSNextProto。反向代理不应要求客户端使用任何特殊的代理配置,即它应该是透明的。 - IanB
重复标题:如何编写Go程序以使用代理?,但不是同样的问题。 - Brent Bradburn
我非常确定问题出在代理URL上。具体而言,代理必须使用HTTP协议进行访问,而您指定的是HTTPS。 - Svyatoslav Pidgorny
1个回答

1
没有发现你的 Client.Transport.Proxy 配置有任何问题。 两种尝试的方法(ProxyURLProxyFromEnvironment)都应该可以很好地指定一个转发代理
相关问题: 如何编写Go程序以使用代理? 需要注意的是,虽然不太可能,但要注意客户端后续调用不能绕过使用 WriteProxy 并直接调用 Write - 因为这将使代理规范无效。
根据提供的信息,“Bad Request”可能表明您正在访问代理,但它作为通用HTTP/HTTPS转发代理未能正常工作,这就是Client.Transport.Proxy所指定的内容。
也许在此处可以添加一些明确性:如何使用Nginx作为HTTP/HTTPS代理服务器?。总之,NGINX通常不用作转发代理,因此这可能不是您想要做的事情。 如果您尝试将NGINX用作反向代理,则配置是服务器端关注的问题,您的客户端不需要特殊的代理配置--只需更改请求URL以指向代理即可。

顺便提一下:如果没有特别说明,&http.Client{}将使用DefaultTransport,它自动包含ProxyFromEnvironment,因此只有在构建非默认传输(如问题中所做的以指定InsecureSkipVerify)或您想要具有应用程序特定代理配置时才需要额外的代理配置。并且,重申一遍,只有在使用转发代理时才需要客户端代理配置。


正向HTTP代理:代理是如何工作的? - Brent Bradburn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接