python - 使用 Python 'requests' 库的 HTTPS POST 请求出现不一致的 IOError 异常
问题描述
尝试使用 HTTPS POST 时,我不断收到以下异常requests
此问题偶尔会发生,并且在重试(使用backoff
模块)成功通过时相同的请求。我不知道如何重现此问题,但当我运行大量 HTTPS POST 请求时会看到此问题。
Traceback (most recent call last):
File \"/usr/local/lib/python2.7/dist-packages/shared/util/http_util.py\", line 71, in send_https_post_request
response = session.post(url, cert=cert, data=data)
File \"/usr/local/lib/python2.7/dist-packages/requests/sessions.py\", line 522, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File \"/usr/local/lib/python2.7/dist-packages/requests/sessions.py\", line 475, in request
resp = self.send(prep, **send_kwargs)
File \"/usr/local/lib/python2.7/dist-packages/requests/sessions.py\", line 596, in send
r = adapter.send(request, **kwargs)
File \"/usr/local/lib/python2.7/dist-packages/requests/adapters.py\", line 423, in send
timeout=timeout
File \"/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py\", line 595, in urlopen
chunked=chunked)
File \"/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py\", line 352, in _make_request
self._validate_conn(conn)
File \"/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py\", line 831, in _validate_conn
conn.connect()
File \"/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connection.py\", line 289, in connect
ssl_version=resolved_ssl_version)
File \"/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py\", line 306, in ssl_wrap_socket
context.load_cert_chain(certfile, keyfile)
IOError: [Errno 2] No such file or directory
相关代码:
@contextlib.contextmanager
def pem_bytes_as_cert_file(pem_cert_bytes):
'''
Given bytes, return a temporary file which can be used as the cert
'''
with tempfile.NamedTemporaryFile(delete=True, suffix='.pem') as t_pem:
f_pem = open(t_pem.name, 'wb')
f_pem.write(pem_cert_bytes)
f_pem.close()
yield t_pem.name
def send_https_post_request(session, url, data, pem_cert_in_bytes):
with pem_bytes_as_cert_file(pem_cert_in_bytes) as cert:
response = session.post(url, cert=cert, data=data)
response.raise_for_status()
response.close()
你能帮我更多地了解这个问题吗?
解决方案
... context.load_cert_chain(certfile, keyfile) IOError: [Errno 2] No such file or directory
上下文显然是在加载证书和密钥
with pem_bytes_as_cert_file(pem_cert_in_bytes) as cert: response = session.post(url, cert=cert, data=data)
您似乎将证书和密钥作为字符串并尝试创建一个临时文件以将其作为cert
参数
with tempfile.NamedTemporaryFile(delete=True, suffix='.pem') as t_pem:
f_pem = open(t_pem.name, 'wb')
f_pem.write(pem_cert_bytes)
f_pem.close()
yield t_pem.name
您创建一个临时文件tempfile.NamedTemporaryFile
并将 cert+key 字符串写入其中。然后关闭临时文件。NamedTemporaryFile的文档指出:
如果 delete 为 true(默认值),则文件一关闭就会被删除。
因此,一旦您关闭该文件,该文件就会被删除。仅当您很幸运(竞争条件)时,当您尝试从内部使用该文件时,该文件仍然可以在系统中访问session.post
。
推荐阅读
- ticket-system - 票务系统 - 最终用户的透明度
- javascript - 单击内部函数内部的按钮时如何返回外部函数的值?
- php - 如何用composer安装omnipay的ipay88包?
- laravel - 在 laravel 中为自定义验证规则自定义验证错误消息
- javascript - 在 nuxtjs 的另一个页面中调用 API
- aframe - 自定义图像跟踪无法正常工作
- testing - 在环回 4 中调用 API
- javascript - 我们面临错误 DevTools failed to load SourceMap
- kubernetes - Kubernetes Executor 的 Airflow 无法采用和移除工作 pod
- docker - 在 Redhat AWS EC2 实例上安装 Docker(RHEL_7.9)