-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
Content-Length is missing #223
Comments
Should be good now |
import requests
URL = "http://github.com"
g_url = "http://clients6.google.com/rpc?key=AIzaSyCKSbrvQasunBoV16zDH9R33D88CeLr9gQ"
params = {
'method': 'pos.plusones.get',
'id': 'p',
'params': {
'nolog': 'true',
'id': URL,
'source': 'widget',
'userId': '@viewer',
'groupId':'@self'
},
'jsonrpc': '2.0',
'key': 'p',
'apiVersion': 'v1'
}
headers = {
'Content-type': 'application/json'
}
r = requests.post(g_url, params=params, headers=headers)
print r.request.headers content length still isn't set in this code with version 0.8.3 |
You're not uploading any body. Why would there be a content-length? |
kennethreitz, iirc - the Content-length header should always be set (even if it's zero) when a POST is involved. But by looking at the code pasted by zoranzaric, he is indeed sending a POST with a request body - so the content-length should surely be included? Am I missing something here?? Cal |
foxx, I thought setting params was correct for a POST. What am I doing wrong? kennethreitz, the Google API that I'm talking to responds with 411 (Length Required) |
@zoranzaric: |
@kennethreitz ok yeah snap... with |
@zoranzaric, no worries! A lot of other libraries are quite inconsistent, so I completely understand the confusion. That's the whole reason I started Requests :) |
Ah - sorry I missed the 'params' / 'data' difference. My bad! |
This is still broken with regard to sending a blank POST request: r = requests.post(full_uri) While a Content-Length header is sent, the value is blank (it should be 0 per the RFC). The request as the server see is below:
|
Are you working on the invalid content-length for POST requests without data payload issue? I was just bit by this bug while trying to POST and PUT to a WCF service. I could luckily work around it by specifying a content-length of 0 via the 'headers' keyword argument to the 'post' and 'put' functions. |
@aknuds1 what version are you using? This is what I see in trunk:
|
@slingamn Ah, maybe it's fixed in trunk then. I'm just using the version installed via pip, i.e. 0.11.2. |
Oh, weird, I get Can you try the above test case and post the result? |
I tried your case and get the following output:
Is there a bug at httpbin.org then, since there is clearly a difference in the request when I define the content-length header myself? |
Sorry, I'm confused. Isn't that the expected output?
|
@slingamn It's the desired output, yes, but why is there a difference towards WCF when I define the content-length header myself? I mean, httpbin.org reports that the request has defined content-length as "0", even though the same request directed at WCF fails with error 411. |
I'm inclined to suspect a bug with the WCF service, since I get the same result using http://requestb.in.
and Requestbin saw the following headers:
|
But there must be a difference wrt. content-length, since defining that header myself in the client library (requests) results in a request accepted by WCF. I'll see if I can get hold of the POST request received by WCF. |
One possible explanation: this results in the headers appearing in a different order, and the WCF service (incorrectly) takes note of this. To get the POST request, you could (as a last resort) try something like Wireshark. |
According to Fiddler, the POST request without user-defined content-length header looks like so:
If I define the content-length header, via the 'headers' argument to requests.post, however, the request looks like so:
|
Interesting! The line of code that produces the bad behavior is just |
I'm on Python 2.7.2. Here's what I see in my httplib.py: def _set_content_length(self, body):
# Set the content-length based on the body.
thelen = None
try:
thelen = str(len(body))
except TypeError, te:
# If this is a file-like object, try to
# fstat its file descriptor
try:
thelen = str(os.fstat(body.fileno()).st_size)
except (AttributeError, OSError):
# Don't send a length if this failed
if self.debuglevel > 0: print "Cannot stat!!"
if thelen is not None:
self.putheader('Content-Length', thelen) If you can't provide a reproducible test case for security/privacy reasons (totally understandable), can you try and monkeypatch your httplib and see if that |
My code is as simple as this (the HTTP proxy is Fiddler):
If you run this script against Fiddler on your machine, you would probably see the same request as I do. I can't see that httplib._set_content_length is called at all. I injected some code in there to see if it was called by requests, but that code wasn't hit. |
And Fiddler shows a |
|
We've clarified this in HTTPbis (although it's there in 2616 too). Content-Length is not required on requests; if it's missing, the default is a length of 0. See: |
I need to set the "Content-Length" for a GET request. Anybody knows how to fix this? |
@nettok something along the lines of: from requests import get
r = get('http://httpbin.org', headers={'Content-Length': '0'}) But of course if you're sending data, it wouldn't be zero. If you're sending a body, e.g., r = get('http://httpbin.org/get', data='spam')
r.json['headers']['Content-Length'] == '4' # True |
Also, just realized this had bitten me a while back here. If @kennethreitz still wants a PR attaching Content-Length to everything, I'd be happy to do so. |
Yes. |
@kennethreitz where should I branch from, develop or adapters? |
develop, adapters will be a while :) |
Roger that. |
I am getting a 411 while using netflix API too. I am getting this while trying to get the request token using the requests-oauth module. Things were working fine, but the API end point have changed recently which may indicate additional changes in server side as well. Code: https://github.com/amalakar/pyflix2/blob/master/pyflix2/pyflix2.py#L76 Surprisingly even though I am passing post data as Headers sent are: I am on requests-0.14.0, not sure if the issue is in requests or the oauth module. I would be happy to provide additional information. |
@kennethreitz Looks like the content-length is being set in case of GET request as well. Where the data being passed is going as query params in the URL. This could be a 400 Bad Request case (which is what is happening for me). Following is an example of headers sent: And this was for a GET request. |
Can you provide the call @amalakar? This must be a mistake on my part and I'd like to fix it. |
To clarify @amalakar, testing against HTTPBIN, with
which is a bit bizarre but probably a bug on HTTPBIN's end. (The fact that Content-Length is |
Notice I am using data argument here, not params. The server side script is a simple php script that prints all the http headers it received in the http request. You can see that it got the Content-Length as 7.
|
Well this seems to be more of a problem with the server if I'm reading RFC https://tools.ietf.org/html/rfc2616#page-119 The Content-Length entity-header field indicates the size of the
An example is
Applications SHOULD use this field to indicate the transfer-length of (And section 4.4 doesn't mention anything about sending data on a GET Any Content-Length greater than or equal to zero is a valid value. Note that the meaning of this field is significantly different from |
Yup, the server is doing the wrong thing here. (Though, in its defense, your request is semantically meaningless, as @piotr-dobrogost has pointed out. =D ) |
Well, on the contrary. The semantics of such a request is clearly defined :) |
Well from the documentation I get the following:
Given this can I conclude that if I provide the dictionary as Well I have another problem it seems. So far I have been using the https://github.com/maraujop/requests-oauth and the
Notice that here the data dictionary has become query params as seen in the URL. This seems inconsistent wrt ``requests.get` in which case data dictionary is not sent as query params but as the body. |
As far as I know, data has always been for the body and parameters for the query string. requests-coauthor must have messed that up unless he did it purposefully. |
Please see the following example
In this example, the 'Content-Length' is missing.
Haven't got any spare time to try and patch the bug - as this was only a quick test to explore new libs.
Cal
[revised post 3 - multiple edits due to mistake on bug report]
The text was updated successfully, but these errors were encountered: