使用httplib2打开ssl连接时出错

2 投票
2 回答
4312 浏览
提问于 2025-04-17 05:38

我正在使用httplib2来打开一个ssl连接。下面是我的代码。

import httplib2

if __name__=='__main__':
    conn = httplib2.Http(disable_ssl_certificate_validation=True)
    conn.add_certificate('serverkey.pem', 'servercert.pem', '')
    resp, content = conn.request(uri = 'https://xxx.xxx.xxx.xxx:xxxx/Konfigurator
                   /REST/login?userName=xxx&pass=xxx', method = 'POST')
    print resp

这是我遇到的错误。

Traceback (most recent call last):
File "C:\eclipse-workspace\REST\src\examples.py", line 7, in <module>
resp, content = conn.request(uri = 'https://xxx.xxx.xxx.xxx:xxx/Konfigurator/REST/login?userName=xxx&pass=xxx', method = 'POST')
File "C:\Python27\lib\site-packages\httplib2-0.7.1-py2.7.egg\httplib2\__init__.py", line 1437, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
 File "C:\Python27\lib\site-packages\httplib2-0.7.1-py2.7.egg\httplib2\__init__.py", line 1189, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
 File "C:\Python27\lib\site-packages\httplib2-0.7.1-py2.7.egg\httplib2\__init__.py", line 1163, in _conn_request
conn.connect()
File "C:\Python27\lib\site-packages\httplib2-0.7.1-py2.7.egg\httplib2\__init__.py", line 925, in connect
raise socket.error, msg
socket.error: [Errno 10054] An existing connection was forcibly closed by the remote host

这个代码是正确的吗?还是我漏掉了什么?

2 个回答

1

你的代码看起来是对的,也就是说,下面这个简化版的代码能够正确地获取谷歌的HTTPS首页:

>>> import httplib2
... from pprint import pprint
... conn = httplib2.Http()
... resp, content = conn.request(uri="https://encrypted.google.com")
... pprint(resp)
{'cache-control': 'private, max-age=0',
 'content-location': 'https://encrypted.google.com',
 'content-type': 'text/html; charset=ISO-8859-1',
 'date': 'Fri, 04 Nov 2011 09:56:58 GMT',
 'expires': '-1',
 'server': 'gws',
 'set-cookie': 'PREF=ID=efe3264c0da8b563:FF=0:TM=1320400618:LM=1320400618:S=AsZHdP7eQQXrsYOw; expires=Sun, 03-Nov-2013 09:56:58 GMT; path=/; domain=.google.com, NID=52=RJx7UWMiVEQGLvS3nVLz4iit6Z-V0pMSXzbReygHwJVt40kg4rhs1NS2U025XEyz_0ajtbGhsUDqbqIK5gje16sxka4sStsV4KmQRPOnbpNoeL4mN9Nge-NSEoziU8yH; expires=Sat, 05-May-2012 09:56:58 GMT; path=/; domain=.google.com; HttpOnly',
 'status': '200',
 'transfer-encoding': 'chunked',
 'x-frame-options': 'SAMEORIGIN',
 'x-xss-protection': '1; mode=block'}

所以我猜测是你的证书出了问题,导致远程服务器拒绝连接并强制断开会话。你有控制这个服务器吗?如果有的话,你有没有从服务器上获取到任何日志或诊断信息?

其实,仔细看看,我想弄明白你提到的“add_certificate”这个调用。你为什么要把那个特定的IP地址作为证书的域名呢?服务器的密钥真的代表那个IP地址吗?你有没有试过用一个空字符串?

2

我搞定了。问题出在服务器只支持TLSv1和SSLv3这两种加密方式。而httplib2这个模块默认使用SSLv23,如果没有指定版本的话。这导致服务器发回了RST数据包。可能是他们代码里的一个bug。我在他们的init.py文件里做了个改动,在wrap_socket函数中加上了“ssl_version=3”(3代表TLS),这样就好了。

撰写回答