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 chunked-encoded request #1422

Closed
psushin opened this issue Jun 13, 2013 · 4 comments
Closed

Connection timeout doesn't work for chunked-encoded request #1422

psushin opened this issue Jun 13, 2013 · 4 comments

Comments

@psushin
Copy link

psushin commented Jun 13, 2013

Sample code:

def gen():
    for i in xrange(1, 1000):
        yield 'x'
import requests, datetime

print datetime.datetime.now()

try: requests.post(url='http://1.1.1.1', timeout=5, data=gen())
except Exception as e: print e

print datetime.datetime.now()

try: requests.post(url='http://1.1.1.1', timeout=5, data='a')
except Exception as e: print e

print datetime.datetime.now()

gives the following output

2013-06-14 00:33:03.079389
[Errno 110] Connection timed out
2013-06-14 00:34:06.236742
HTTPConnectionPool(host='1.1.1.1', port=80): Request timed out. (timeout=5)
2013-06-14 00:34:11.242869

The first request blocked for more than a minute, before a timeout has been thrown, while the second one is ok.

Requests 1.2.3
Python 2.7.3

@Lukasa
Copy link
Member

Lukasa commented Jun 14, 2013

Thanks for opening this issue!

Looking at the Requests code, I suspect you might be right. I'm at work at the moment and won't have internet at home until the 18th, but when I can get time I'll investigate this.

To begin with, I think the problem is around here. For chunked uploads, we do this:

low_conn = conn._get_conn(timeout=timeout)
low_conn.putrequest(request.method, url, skip_accept_encoding=True)

for header, value in request.headers.items():
    low_conn.putheader(header, value)

low_conn.endheaders()

for i in request.body:
    low_conn.send(hex(len(i))[2:].encode('utf-8'))
    low_conn.send(b'\r\n')
    low_conn.send(i)
    low_conn.send(b'\r\n')

low_conn.send(b'0\r\n\r\n')

r = low_conn.getresponse()
resp = HTTPResponse.from_httplib(r,
    pool=conn,
    connection=low_conn,
    preload_content=False,
    decode_content=False
 )

The only place we set the timeout is in the call to urllib3.HTTPConnectionPool._get_conn(), which passes down into its LifoQueue. This timeout affects how long we wait to obtain a connection object, but does not set the timeout on that connection.

I need to think about what's best to do here, but I think the answer is to set low_conn.timeout = timeout before the initial call to putrequest(). Feel free to try that out if I don't get around to testing it first.

@sigmavirus24
Copy link
Contributor

I wonder if our new Timeout system will fix this.

@isobit
Copy link

isobit commented Nov 27, 2017

Seems this is still happening with 2.18.4. I was able to fix it using low_conn.timeout = timeout.connect_timeout, like @Lukasa mentioned. Should I write a test and submit a pull request or just create a new issue?

@sethmlarson
Copy link
Member

sethmlarson commented Nov 27, 2017

Raise a new issue, link this one, and include your test case that can reproduce the problem consistently. Then you can submit a PR and link to your new issue if you have time :) Thanks @isobit!

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

No branches or pull requests

5 participants