4

我正在使用 httplib2 向我拥有的 REST 服务发出 HTTPS GET 请求,但出现错误:

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

除了 PHP curl 需要设置为使用 SSL v3 的小例外,所有其他客户端(浏览器、Java 客户端等)运行良好。

我四处搜索,似乎确实是关于 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)
4

2 回答 2

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。

于 2013-08-07T16:26:18.413 回答
0

请参阅指定解决方案的另一个StackOverflow 线程。指定 TLS 版本的方式将 SSL 版本强制为 TLSv1,如提供的链接中用户喜爱的响应中所述。

希望这有效

于 2013-07-29T05:59:00.277 回答