kar*_*kpl 5 python ssl openssl urllib2 python-2.7
我在使用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)>
Run Code Online (Sandbox Code Playgroud)
我能够在 OS X 10.10.3 上重复您的问题,其库存 Python 是使用 OpenSSL 0.9.8zd 构建的 2.7.6。
问题是 TLS 握手中缺少服务器名称指示(SNI) 扩展,而 twitrss.me 站点显然需要该扩展:
服务器名称指示 (SNI) 是 TLS 计算机网络协议的扩展,客户端通过该协议在握手过程开始时指示它尝试连接到的主机名。
我通过使用 OpenSSL 编写一个小型 C++ 程序并插入 OpenSSL 调用来验证这一点
SSL_set_tlsext_host_name(ssl, "twitrss.me");
Run Code Online (Sandbox Code Playgroud)
允许连接成功,同时忽略失败。我还查看了数据包转储,以验证在尝试使用 Python 连接时是否缺少 SNI。
Python SSL 模块显然支持 Python 3 中的 SNI,但可能需要 Python 2 中的解决方法。看来PEP 0466包含 SNI 并登陆了 Python 2.7.9,所以你应该拥有它,但我不知道是否可以urllib2/urllib3在没有解决方法的情况下利用它。
| 归档时间: |
|
| 查看次数: |
9306 次 |
| 最近记录: |