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

Connection timeout doesn't work for chunk-encoded requests #4402

Closed
isobit opened this issue Nov 27, 2017 · 4 comments
Closed

Connection timeout doesn't work for chunk-encoded requests #4402

isobit opened this issue Nov 27, 2017 · 4 comments

Comments

@isobit
Copy link

isobit commented Nov 27, 2017

Original issue was #1422, but I was able to reproduce in 2.18.4.

Expected Result

Chunk-encoded requests timeout after the specified timeout if the server does not respond.

Actual Result

Request holds connection open and never times out.

Reproduction Steps

First, run a test server that accepts POST requests and waits 10 seconds before responding:

from http.server import BaseHTTPRequestHandler, HTTPServer
import time

class Handler(BaseHTTPRequestHandler):
    def do_POST(self):
        time.sleep(10)
        self.send_response(200)
        self.end_headers()

if __name__ == '__main__':
    httpd = HTTPServer(('', 8000), Handler)
    print('Listening on :8000')
    httpd.serve_forever()

Then, in another REPL, verify timeout works for non-chunk-encoded requests:

import requests
requests.post('http://localhost:8000', timeout=2.0, data='hello'.encode('utf-8'))

A timeout exception should be thrown.

Then, verify timeout does not work for chunk-encoded requests:

def gen():
    yield 'hello'.encode('utf-8')
requests.post('http://localhost:8000', timeout=2.0, data=gen())

A <Response [200]> will be returned, indicating that the timeout did not work properly (a timeout exception should have been thrown instead).

System Information

$ python -m requests.help
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.6"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.3"
  },
  "platform": {
    "release": "4.4.0-43-Microsoft",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.18.4"
  },
  "system_ssl": {
    "version": "1000207f"
  },
  "urllib3": {
    "version": "1.22"
  },
  "using_pyopenssl": false
}

Workaround

Insert the following on line 454 of requests/adapters.py:

low_conn.timeout = timeout.connect_timeout
@Lukasa
Copy link
Member

Lukasa commented Nov 27, 2017

This would be resolved by moving to use urllib3's chunked encoding logic as well. I concur with @sigmavirus24's notes on another issue: if we can get some socket-level tests of our chunked handling, we can move to using urllib3's logic to resolve this issue.

@ddzialak
Copy link

In the consequence of that bug, when using with sessions, the chunked request have a timeout from the http request previously executed on that connection (!) if any... I've spent some time to explain why sometimes timeout happened and sometimes not.

@thomas-riccardi
Copy link

@ddzialak comment is important: it's a nasty issue to debug.

I assume this is fixed by #5128, merged but not released yet.
@nateprewitt when can we expect a new maintenance release?

@sethmlarson
Copy link
Member

Requests is now using urllib3's chunking API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants