-
-
Notifications
You must be signed in to change notification settings - Fork 175
Open
Description
As the title suggests, I think the library is too strict in regards to 204 (No Content) responses that contain a Content-Length response header, in the context of HTTP/2.
While the HTTP/1.1 spec explicitly forbid this case (RFC 7230 section 3.3.2, as well as RFC 9110 section 8.6), my understanding is that the HTTP/2 spec does not. According to RFC 9113, chapter 8.1.1, a response without content may have a content-length header field:
A request or response is also malformed if the value of a content-length header field does not equal the sum of the DATA frame payload lengths that form the content, unless the message is defined as having no content. For example, 204 or 304 responses contain no content, as does the response to a HEAD request. A response that is defined to have no content, as described in Section 6.4.1 of [HTTP], MAY have a non-zero content-length header field, even though no content is included in DATA frames.
Versions used
gun 2.1.0
cowlib 2.13.0
erlang/otp 26
Steps to reproduce
Using an HTTP/2 server that responds with a 204 (No Content) response with or without a Content-Length response header (in my case https://github.com/iqltd/go-h2-yourself):
- when the 204 (No Content) response doesn't contain a
Content-Lengthresponse header, the response is handled correctly - when the 204 (No Content) response contains a
Content-Lengthresponse header, we get astream_error
Eshell V14.2.4 (press Ctrl+G to abort, type help(). for help)
1> application:ensure_all_started([gun]).
{ok,[cowlib,gun]}
2> ConnectionOpts = #{ transport => tls, tls_opts => [{verify, verify_none}] }.
#{transport => tls,tls_opts => [{verify,verify_none}]}
3> {ok, Pid} = gun:open("0.0.0.0", 8000, ConnectionOpts).
{ok,<0.642.0>}
4> gun:await_up(Pid, 1000).
{ok,http2}
5> Ref = gun:get(Pid, "/without-content-length", []).
#Ref<0.1964309148.1156317188.132308>
6> gun:await(Pid, Ref).
{response,fin,204,
[{<<"content-type">>,<<"application/json">>},
{<<"date">>,<<"Tue, 27 Aug 2024 10:01:38 GMT">>}]}
7> Ref2 = gun:get(Pid, "/with-content-length", []).
#Ref<0.1964309148.1156317188.132351>
8> gun:await(Pid, Ref2).
{error,{stream_error,{stream_error,protocol_error,
'Content-length header received in a 204 response. (RFC7230 3.3.2)'}}}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels