You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Content-Length header is missing in POST/DELETE/PUT/PATCH requests without body #987
httpx version: 0.13.1 Python version: 3.7.3 OS: Windows 7
Question
I am not sure how to classify this issue: it could be a bug, since it is an incompatible with requests, on the other hand, it could be feature request, if you consider it is not that important. So, I decided to go with question. :D
Was replacing requests with httpx in my small script and received an error from the server httpx._exceptions.HTTPError: 411 Client Error: Length Required for url: ... while doing a POST request without a body (same behavior is applicable for PUT and PATCH requests too).
requests adds Content-Length header in every possible http method, except GET and HEAD. httpx does not add Content-Length header at all, unless requests has a body.
#866 added Content-Length to all methods, but since it is not needed in GET and HEAD methods, it was reverted.
I assume, it should be handled during the Request building. httpx decides whether to add Content-Length depending on the steam type, which is handled in _content_streams.py#L314.
Thoughts on how to solve it
To be honest, I am not sure what is the proper way to deal with this. :-(
My first idea was to use method inside the stream:
But this approach is not great, since it requires to pass method from Request to encode and then to ByteStream inside it. Also, it is not clear what method should I use when building stream in read methods.
I believe this is a bug as we're not following the RFC:
A user agent SHOULD send a Content-Length in a request message when no Transfer-Encoding is sent and the request method defines a meaning for an enclosed payload body. For example, a Content-Length header field is normally sent in a POST request even when the value is 0 (indicating an empty payload body).
Reacted by Florimond Manca, Yevhenii Kovalchuk and Malika Srivastava
As you mentioned I think it's best if content streams stay agnostic of the HTTP semantics here.
The .get_headers() method is called in Request.prepare(), so other options I can see as far as implementation goes…
Pass .get_headers(method=...); this would fix the "pass method down the content stream chain" item but streams would then have to be aware of HTTP semantics, not great.
Make streams include Content-Length in all cases, but ignore that header in Request.prepare() if method does not accept a body.
^Sounds good to me too — let the content stream not return a Content-Length if there's no body, and add a default Content-Length: 0 in the request if it's required by the method.
3.3.2 - "A user agent SHOULD send a Content-Length in a request message when no Transfer-Encoding is sent and the request method defines a meaning for an enclosed payload body"
And
4.3.5 - "A payload within a DELETE request message has no defined semantics;"
Activity
yeraydiazdiaz commentedon May 24, 2020
I believe this is a bug as we're not following the RFC:
florimondmanca commentedon May 24, 2020
Thanks!
As you mentioned I think it's best if content streams stay agnostic of the HTTP semantics here.
The
.get_headers()method is called inRequest.prepare(), so other options I can see as far as implementation goes….get_headers(method=...); this would fix the "passmethoddown the content stream chain" item but streams would then have to be aware of HTTP semantics, not great.Content-Lengthin all cases, but ignore that header inRequest.prepare()ifmethoddoes not accept a body.lovelydinosaur commentedon May 24, 2020
I’d suggest auto including it in Request.prepare, if the method requires one, and none is currently present.
florimondmanca commentedon May 24, 2020
^Sounds good to me too — let the content stream not return a
Content-Lengthif there's no body, and add a defaultContent-Length: 0in the request if it's required by the method.lovelydinosaur commentedon May 25, 2020
We should cover
POST,PUT, andPATCHhere.And