httplib2中的SSL版本 - EOF违反协议

时间:2013-07-29 04:53:34

标签: python ssl httplib2

我正在向httplib2拥有的REST服务发出HTTPS GET请求但我们收到错误:

[Errno 8] _ssl.c:504: EOF occurred in violation of protocol

所有其他客户端运行良好(浏览器,Java客户端等等),但需要将PHP curl设置为使用SSL v3。

我已经四处搜索,似乎确实是关于SSL版本的错误,但我似乎找不到在httplib2中更改它的方法。 除了更改源代码中的以下行之外,还有什么办法吗?

# We should be specifying SSL version 3 or TLS v1, but the ssl module
# doesn't expose the necessary knobs. So we need to go with the default
# of SSLv23.
return ssl.wrap_socket(sock, keyfile=key_file, certfile=cert_file,
                       cert_reqs=cert_reqs, ca_certs=ca_certs)

2 个答案:

答案 0 :(得分:5)

我为httplib2开发了这个解决方法:

import httplib2

# Start of the workaround for SSL3
# This is a monkey patch / module function overriding 
# to allow pages that only work with SSL3

# Build the appropriate socket wrapper for ssl
try:
    import ssl # python 2.6
    httplib2.ssl_SSLError = ssl.SSLError
    def _ssl_wrap_socket(sock, key_file, cert_file,
                         disable_validation, ca_certs):
        if disable_validation:
            cert_reqs = ssl.CERT_NONE
        else:
            cert_reqs = ssl.CERT_REQUIRED
        # Our fix for sites the only accepts SSL3
        try:
            # Trying SSLv3 first
            tempsock = ssl.wrap_socket(sock, keyfile=key_file, certfile=cert_file,
                                       cert_reqs=cert_reqs, ca_certs=ca_certs,
                                       ssl_version=ssl.PROTOCOL_SSLv3)
        except ssl.SSLError, e:
            tempsock = ssl.wrap_socket(sock, keyfile=key_file, certfile=cert_file,
                                       cert_reqs=cert_reqs, ca_certs=ca_certs,
                                       ssl_version=ssl.PROTOCOL_SSLv23)
        return tempsock
    httplib2._ssl_wrap_socket = _ssl_wrap_socket
except (AttributeError, ImportError):
    httplib2.ssl_SSLError = None
    def _ssl_wrap_socket(sock, key_file, cert_file,
                         disable_validation, ca_certs):
        if not disable_validation:
            raise httplib2.CertificateValidationUnsupported(
                    "SSL certificate validation is not supported without "
                    "the ssl module installed. To avoid this error, install "
                    "the ssl module, or explicity disable validation.")
        ssl_sock = socket.ssl(sock, key_file, cert_file)
        return httplib.FakeSocket(sock, ssl_sock)
    httplib2._ssl_wrap_socket = _ssl_wrap_socket

# End of the workaround for SSL3

if __name__ == "__main__":
    h1 = httplib2.Http()
    resp, content = h1.request("YOUR_SSL3_ONLY_LINK_HERE", "GET")
    print(content)

此解决方法基于此错误报告http://bugs.python.org/issue11220中提供的urllib2的变通方法,

更新:为httplib2提供解决方案。我没注意到你在使用httplib2,我以为是urllib2。

答案 1 :(得分:0)

请参阅指定解决方案的其他StackOverflow threads。指定TLS版本的方式会强制SSL版本为TLSv1,如用户 favoretti 在提供的链接中的响应中所述。

希望这有效