请求库https通过代理导致错误

时间:2013-10-23 00:40:06

标签: python authentication proxy python-requests

尝试通过代理发送简单的get请求。我有代理授权'和'授权'标题,不要以为我需要授权'标题,但无论如何都加了它。

import requests
URL = 'https://www.google.com'
sess = requests.Session()
user = 'someuser'
password = 'somepass'
token = base64.encodestring('%s:%s'%(user,password)).strip()
sess.headers.update({'Proxy-Authorization':'Basic %s'%token})
sess.headers['Authorization'] = 'Basic %s'%token
resp = sess.get(URL)

我收到以下错误:

requests.packages.urllib3.exceptions.ProxyError: Cannot connect to proxy. Socket error: Tunnel connection failed: 407 Proxy Authentication Required.

但是,当我将网址更改为简单http://www.google.com时,它可以正常工作。

代理是否对https使用Basic,Digest或其他类型的身份验证?是代理服务器特定的吗?我如何发现这些信息?我需要使用请求库来实现这一点。

更新

似乎对于HTTP请求,我们必须传入Proxy-Authorization标头,但是对于HTTPS请求,我们需要使用用户名和密码格式化代理URL

#HTTP
import requests, base64
URL = 'http://www.google.com'
user = <username>
password = <password>
proxy = {'http': 'http://<IP>:<PORT>}
token = base64.encodestring('%s:%s' %(user, password)).strip()
myheader = {'Proxy-Authorization': 'Basic %s' %token}
r = requests.get(URL, proxies = proxies, headers = myheader)
print r.status_code # 200


#HTTPS
import requests
URL = 'https://www.google.com'
user = <username>
password = <password>
proxy = {'http': 'http://<user>:<password>@<IP>:<PORT>}
r = requests.get(URL, proxies = proxy)
print r.status_code  # 200

发送HTTP请求时,如果我遗漏标题并传入使用user / pass格式化的代理,我会收到407响应。

发送HTTPS请求时,如果我传入标头并保留代理未格式化,我会收到前面提到的ProxyError。

我正在使用请求2.0.0和Squid代理缓存Web服务器。为什么标题选项不适用于HTTPS?为什么格式化的代理不适用于HTTP?

1 个答案:

答案 0 :(得分:4)

答案是HTTP案例被窃听。在这种情况下,预期的行为与HTTPS情况相同:即,您在代理URL中提供身份验证凭据。

标头选项不适用于HTTPS的原因是通过代理的HTTPS 完全与HTTP通过代理不同。当您通过代理路由HTTP请求时,您基本上只是向代理发送标准HTTP请求,其路径指示完全不同的主机,如下所示:

GET http://www.google.com/ HTTP/1.1
Host: www.google.com

然后代理基本上转发了这个。

对于无法工作的HTTPS,因为您需要与远程服务器协商SSL连接。不是像HTTP一样做任何事情,而是使用CONNECT动词。代理服务器代表客户端连接到远程端,并且仅代理TCP数据从它们连接到远程端。 (更多信息here。)

当您将Proxy-Authorization标头附加到HTTPS请求时,我们不会将其放在CONNECT消息上,我们将其放在隧道HTTPS消息上。这意味着代理永远不会看到它,因此拒绝您的连接。我们特殊情况下代理URL中的身份验证信息,以确保它正确地将标头附加到CONNECT消息。

请求和urllib3目前正在讨论这个错误修复的正确位置。 GitHub问题目前是here。我希望修复程序将在下一个Requests版本中。