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

Sending an empty body from a file, with Content-Length: 0 header times out #4215

Closed
dobesv opened this issue Aug 1, 2017 · 2 comments
Closed

Comments

@dobesv
Copy link

dobesv commented Aug 1, 2017

Sending a POST request with an empty body read from an empty file and a Content-Length: 0 header times out after a long time instead of doing normal processing.

Expected Result

Sending an empty body from a file with Content-Length: 0 should send the request and return a result in a similar amount of time as a non-empty request, or a request without Content-Length: 0, or an empty body provided as a string.

For example:

$ cat repro2.py 
import requests, tempfile

with tempfile.NamedTemporaryFile() as tf:
    print requests.Session().send(requests.Request('POST', 'https://www.google.com', data=open(tf.name)).prepare())

$ python repro2.py 
<Response [405]>

Or using a string body:

$ cat repro3.py 
import requests, tempfile

print requests.Session().send(requests.Request('POST', 'https://www.google.com', headers={'Content-Length': u'0'}, data='').prepare())

$ python repro3.py 
<Response [405]>

Or a non-empty file:

$ cat repro5.py 
import requests, tempfile

with tempfile.NamedTemporaryFile() as tf:
    tf.write('x')
    tf.flush()
    print requests.post('https://www.google.com', headers={'Content-Length': u'0'}, data=open(tf.name))

$ python repro5.py 
<Response [405]>

Actual Result

However, with the specific combination of a Content-Length: 0 header and an empty open file descriptor, the request times out after 4 minutes with an error.

$ pip freeze | grep requests
requests==2.18.2
$ cat repro1.py
import requests, tempfile

with tempfile.NamedTemporaryFile() as tf:
    requests.Session().send(requests.Request('POST', 'https://www.google.com', headers={'Content-Length': u'0'}, data=open(tf.name)).prepare())
$ time python repro1.py 
Traceback (most recent call last):
  File "repro1.py", line 4, in <module>
    requests.Session().send(requests.Request('POST', 'https://www.google.com', headers={'Content-Length': u'0'}, data=open(tf.name)).prepare())
  File "/home/ubuntu/env/lib/python2.7/site-packages/requests/sessions.py", line 612, in send
    r = adapter.send(request, **kwargs)
  File "/home/ubuntu/env/lib/python2.7/site-packages/requests/adapters.py", line 490, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine("''",))

real	4m0.480s
user	0m0.296s
sys	0m0.040s
$ cat repro4.py 
import requests, tempfile

with tempfile.NamedTemporaryFile() as tf:
    print requests.post('https://www.google.com', headers={'Content-Length': u'0'}, data=open(tf.name))

$ time python repro4.py 
Traceback (most recent call last):
  File "repro4.py", line 4, in <module>
    print requests.post('https://www.google.com', headers={'Content-Length': u'0'}, data=open(tf.name))
  File "/home/ubuntu/env/lib/python2.7/site-packages/requests/api.py", line 112, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/home/ubuntu/env/lib/python2.7/site-packages/requests/api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/ubuntu/env/lib/python2.7/site-packages/requests/sessions.py", line 502, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/ubuntu/env/lib/python2.7/site-packages/requests/sessions.py", line 612, in send
    r = adapter.send(request, **kwargs)
  File "/home/ubuntu/env/lib/python2.7/site-packages/requests/adapters.py", line 490, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine("''",))

real	4m5.474s
user	0m0.288s
sys	0m0.036s

Reproduction Steps

import requests, tempfile

with tempfile.NamedTemporaryFile() as tf:
    print requests.post('https://www.google.com', headers={'Content-Length': u'0'}, data=open(tf.name))

System Information

$ python -m requests.help
{
  "chardet": {
    "version": "3.0.4"
  }, 
  "cryptography": {
    "version": "1.5.2"
  }, 
  "implementation": {
    "name": "CPython", 
    "version": "2.7.13"
  }, 
  "platform": {
    "release": "4.4.0-78-generic", 
    "system": "Linux"
  }, 
  "pyOpenSSL": {
    "openssl_version": "1000207f", 
    "version": "16.1.0"
  }, 
  "requests": {
    "version": "2.18.2"
  }, 
  "system_ssl": {
    "version": "1000207f"
  }, 
  "urllib3": {
    "version": "1.22"
  }, 
  "using_pyopenssl": true
}

Workaround

Check if the file is empty before sending and, if it is, substitute the file descriptor for an empty string.

@nateprewitt
Copy link
Member

Hey @dobesv, this is a known bug in the 2.x versions of requests and was originally recorded in #3066. We have a patch submitted (#3897) and merged into the 3.0.0 branch which will address this.

For the time being, Requests should be capable of determining the required headers in it's current state. If you don't manually pass a Content-Length header for empty files, you should find that this is a non-issue unless your endpoint is incapable of handling Transfer-Encoding: chunked. I'm going to close this out as a duplicate and the issue will be resolved in a future release. Please let us know if you have any further questions or comments. Thanks!

@dobesv dobesv changed the title Sending an empty body from a file, with Content-Length: 0 header times out instead of er Sending an empty body from a file, with Content-Length: 0 header times out Aug 1, 2017
@dobesv
Copy link
Author

dobesv commented Aug 2, 2017

@nateprewitt Thanks, sounds great. Sorry I didn't find the other issue in the first place.

cloudlab-autobuild pushed a commit to salt-formulas/salt-formula-artifactory that referenced this issue Feb 1, 2018
This patch fixes issue with timeout during empty file deploy.
More details here psf/requests#4215

Change-Id: I44c11605badf0d30be6c220e9964be22aadd27f0
@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.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants