Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requests library can hang indefinitely on windows, even if a timeout is set #5433

Closed
earonesty opened this issue Apr 21, 2020 · 2 comments
Closed

Comments

@earonesty
Copy link

earonesty commented Apr 21, 2020

Summary.

Assume you have a website that listens for and accepts connections, but never responds.

requests.get('https://sitethatneverresponds.com', timeout=1)

I expect this should always raise a timeout error.

Instead, if you put Windows into "sleep" mode during an openssl handshake, then wake it up a few minute later, socket events are silently dropped and the socket hangs forever.

Reproduction Steps

On a laptop run do this a bunch of times:

requests.get('https://sitethatneverresponds.com', timeout=1)

Then close the laptop lid, and lift it up 5 minutes later (or whatever the tcp discard window is). The get request never times out, and never returns. If someone knows a better way of making a socket "disappear" and not time out, let me know.

It's possible to get a call stack by turning on python's tracing system and killing the process:

Call stack of hung thread:

Thread 0x000070000823a000 (most recent call first):
  File "site-packages/OpenSSL/SSL.py", line 1813 in recv_into
  File "site-packages/urllib3/contrib/pyopenssl.py", line 313 in recv_into
  File "socket.py", line 586 in readinto
  File "http/client.py", line 258 in _read_status
  File "http/client.py", line 297 in begin
  File "http/client.py", line 1331 in getresponse
  File "site-packages/urllib3/connectionpool.py", line 421 in _make_request
  File "site-packages/urllib3/connectionpool.py", line 677 in urlopen
  File "site-packages/requests/adapters.py", line 449 in send
  File "site-packages/requests/sessions.py", line 643 in send

Related Issue with pyopenssl:

pyopnessl, by not doing it themselves, has essentially decided that the caller must handle this by putting the socket into non-blocking mode, and calling select in a loop:

See: pyca/pyopenssl#168 for potential solutions.

System Information

$ python -m requests.help
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": "2.8"
  },
  "idna": {
    "version": "2.9"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.8"
  },
  "platform": {
    "release": "10",
    "system": "Windows"
  },
  "pyOpenSSL": {
    "openssl_version": "1010104f",
    "version": "19.1.0"
  },
  "requests": {
    "version": "2.23.0"
  },
  "system_ssl": {
    "version": "1000211f"
  },
  "urllib3": {
    "version": "1.25.8"
  },
  "using_pyopenssl": true
@earonesty
Copy link
Author

I'm going to write a program that makes this easy to reproduce, then reopen if I can figure it out.

@sigmavirus24
Copy link
Contributor

@earonesty I belive you're confused about what functionality timeout provides in requests. Please search open and closed issues and read those, or read the docs

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 1, 2021
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants