我在使用Python 2.7.10下的urllib2连接https时遇到了麻烦。
有什么想法我错过了吗?
Python 2.7.10 (default, Jun 18 2015, 10:53:24)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl, urllib2
>>> ssl.HAS_SNI
True
>>> ssl.OPENSSL_VERSION
'OpenSSL 0.9.8o 01 Jun 2010'
>>> opener = urllib2.build_opener()
>>> opener.open('https://twitrss.me/')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 431, in open
response = self._open(req, data)
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 449, in _open
'_open', req)
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 1240, in https_open
context=self._context)
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 1197, in do_open
raise URLError(err)
urllib2.URLError: <urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:590)>
答案 0 :(得分:2)
我能够在OS X 10.10.3上复制你的问题,OS X 10.6的版本是用OpenSSL 0.9.8zd构建的2.7.6。
问题是在TLS握手中缺少Server Name Indication(SNI)扩展,twitrss.me网站显然需要:
服务器名称指示(SNI)是TLS计算机的扩展 客户端指示它的主机名的网络协议 正在尝试在握手过程开始时连接。
我通过使用OpenSSL编写一个小型C ++程序并插入OpenSSL调用
来验证这一点SSL_set_tlsext_host_name(ssl, "twitrss.me");
允许成功连接而省略它失败。我还查看了数据包转储,以验证在尝试使用Python进行连接时是否缺少SNI。
Python SSL模块显然是supports SNI in Python 3但may require a workaround in Python 2。似乎PEP 0466包含SNI并且在Python 2.7.9中登陆,所以你应该拥有它,但我不知道urllib2/urllib3
是否在没有解决方法的情况下利用了它。