我正在向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)
答案 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 在提供的链接中的响应中所述。
希望这有效