我正在尝试使用 python 中的请求库将 POST 调用发送到服务器。早些时候我能够成功发送 POST 调用,但最近,服务器弃用了 TLSv1.0,现在只支持 TLSv1.1 和 TLSv1.2。现在,相同的代码向我抛出“requests.exceptions.SSLError:EOF 发生在违反协议(protocol) (_ssl.c:590)”错误。
我在 stackoverflow 上找到了这个帖子 Python Requests requests.exceptions.SSLError: [Errno 8] _ssl.c:504: EOF occurred in violation of protocol这表示我们需要对 HTTPAdapter
进行子类化,之后 session 对象将使用 TLSv1。我相应地更改了我的代码,这是我的新代码
class MyAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
ssl_version=ssl.PROTOCOL_TLSv1
)
url="https://mywebsite.com/ui/"
headers={"Cookie":"some_value","X-CSRF-Token":"some value","Content-Type":"application/json"}
payload={"name":"some value","Id":"some value"}
s = requests.Session()
s.mount('https://', MyAdapter())
r=s.post(url,json=payload,headers=headers)
html=r.text
print html
但即使在使用它之后,我也会得到同样的错误 EOF occurred in violation of protocol (_ssl.c:590)
。
我的第一个问题是,我在某处读到请求默认使用 ssl。我知道我的服务器当时使用的是 TLSv1.0,所以我的代码能正常工作是因为 TLSv1.0 向后兼容 ssl3.0 吗?
我的第二个问题是,我在上面提到的用于将我的代码更改为子类 HTTPAdapter 的 stackoverflow 线程说这将适用于 TLSv1。但是由于 TLSv1.0 在我的服务器中已被弃用,此代码是否仍然有效?
最佳答案
TLS 堆栈将自动使用可用的最佳版本。如果在服务器上禁用 TLS 1.0 支持时它不再工作,这通常意味着您的本地 TLS 堆栈根本不支持更新的协议(protocol)版本,如 TLS 1.2。这在 Mac OS X 上很常见,因为它附带了一个糟糕的旧版本 OpenSSL (0.9.8)。在这种情况下,没有任何 Python 代码可以帮助您解决该问题,但您需要获得使用较新版本 OpenSSL 的 Python。
要检查您使用的是哪个 openssl 版本,请在 python 中执行以下命令:
import ssl
print(ssl.OPENSSL_VERSION)
要支持 TLS 1.2,您需要 OpenSSL 版本 1.0.2 或 1.0.1。如果你只有 1.0.0 或 0.9.8,你需要升级你的 python+OpenSSL。参见 Updating openssl in python 2.7有关如何执行此操作的更多信息。
关于python - 强制请求库在 Python 中使用 TLSv1.1 或 TLSv1.2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38501531/