0

问题本身

请求 get(...).raw期间,我们得到了一个原始的urllib3.HTTPResponse类。由于其IO功能,这很好并且打算拥有。考虑到我真的不想修补,有没有办法告诉这个类嘿,看,我正在做raw.read()每次迭代都使用网络以避免一次读取太多数据来自大文件,所以如果在那段时间 ECONNRESET 来自服务器端,解决连接并继续它离开的地方?

服务器端是外部的,也就是我无法管理的,只有客户端。

我认为没有任何可能的方法可以重试此错误,即使使用 urllib3 的 util.Retry 类在本地调试使用的库本身也是如此。有点可能类似的追溯和问题在这里:https ://github.com/urllib3/urllib3/issues/1331

代码示例来说明

import requests

raw = requests.get('http://httpbin.org/stream/20', stream=True).raw
while not line := raw.read(chunk_size=16):
  print line

追溯:

Traceback (most recent call last):
  File "/python3.8/site-packages/urllib3/contrib/pyopenssl.py", 
  line 317, in recv_into
    return self.connection.recv_into(*args, **kwargs)
  File "/python3.8/site-packages/OpenSSL/SSL.py", line 1814, in recv_into
    self._raise_ssl_error(self._ssl, result)
  File "/python3.8/site-packages/OpenSSL/SSL.py", line 1614, in _raise_ssl_error
    raise WantReadError()
OpenSSL.SSL.WantReadError

During handling of the above exception, another exception occurred:Traceback (most recent call last):
  File "/python3.8/site-packages/urllib3/contrib/pyopenssl.py", line 317, in recv_into
    return self.connection.recv_into(*args, **kwargs)
  File "/python3.8/site-packages/OpenSSL/SSL.py", line 1814, in recv_into
    self._raise_ssl_error(self._ssl, result)
  File "/python3.8/site-packages/OpenSSL/SSL.py", line 1614, in _raise_ssl_error
    raise WantReadError()
OpenSSL.SSL.WantReadError

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/python3.8/site-packages/urllib3/contrib/pyopenssl.py", line 317, in recv_into
    return self.connection.recv_into(*args, **kwargs)
  File "/python3.8/site-packages/OpenSSL/SSL.py", line 1814, in recv_into
    self._raise_ssl_error(self._ssl, result)
  File "/python3.8/site-packages/OpenSSL/SSL.py", line 1631, in _raise_ssl_error
    raise SysCallError(errno, errorcode.get(errno))
OpenSSL.SSL.SysCallError: (104, 'ECONNRESET')

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/python3.8/site-packages/urllib3/response.py", line 438, in _error_catcher
    yield
  File "/python3.8/site-packages/urllib3/response.py", line 519, in read
    data = self._fp.read(amt) if not fp_closed else b""
  File "/python3.8/http/client.py", line 455, in read
    n = self.readinto(b)
  File "/python3.8/http/client.py", line 499, in readinto
    n = self.fp.readinto(b)
  File "/python3.8/socket.py", line 669, in readinto
    return self._sock.recv_into(b)
  File "/python3.8/site-packages/urllib3/contrib/pyopenssl.py", line 332, in recv_into
    return self.recv_into(*args, **kwargs)
  File "/python3.8/site-packages/urllib3/contrib/pyopenssl.py", line 332, in recv_into
    return self.recv_into(*args, **kwargs)
  File "/python3.8/site-packages/urllib3/contrib/pyopenssl.py", line 322, in recv_into
    raise SocketError(str(e))
OSError: (104, 'ECONNRESET')

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/My-Code-Calls-With_Fancypath/file.py", line XYZ, in func_name
    ...
  File "/python3.8/site-packages/urllib3/response.py", line 541, in read
    raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
  File "/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/python3.8/site-packages/urllib3/response.py", line 455, in _error_catcher
    raise ProtocolError("Connection broken: %r" % e, e)


urllib3.exceptions.ProtocolError: ('Connection broken: OSError("(104, \'ECONNRESET\')")', OSError("(104, 'ECONNRESET')"))

与我的问题有些相似的问题是:Python Requests package: lost connection while streaming。唯一的区别是,接受的答案会重试整个下载。

环境:

pyOpenSSL==18.0.0 urllib3==1.26.5 请求==2.25.1 python==3.8

最后

让我们假设理论上这种方式是不可能的。在不改变很多行为的情况下,您有什么好的建议吗?就像使用 urllib3.HTTPResponse.iter_content(...) 方法一样(尽管它的文档说NOT REENTRANT SAFE :( )?

4

0 回答 0