ninenines / gun

HTTP/1.1, HTTP/2, Websocket client (and more) for Erlang/OTP.
ISC License
891 stars 232 forks source link

gun_sse_h failing because of strict `content-type` header validation #282

Closed rocveralfre closed 2 years ago

rocveralfre commented 2 years ago

In gun_sse_h.erl line 34, code verifies if the header content is equal to <<"text/event-stream">>.

init(ReplyTo, StreamRef, _, Headers, _) ->
    case lists:keyfind(<<"content-type">>, 1, Headers) of
        {_, <<"text/event-stream">>} ->
            {ok, #state{reply_to=ReplyTo, stream_ref=StreamRef,
                sse_state=cow_sse:init()}};
        _ ->
            disable
    end.

However, in case server replies with something like:

{gun_response,<0.19323.4>,#Ref<0.3629982879.1640759298.52140>,nofin,
                        200,
                        [{<<"server">>,<<"nginx">>},
                         {<<"date">>,<<"Tue, 08 Feb 2022 10:57:42 GMT">>},
                         {<<"content-type">>,
                          <<"text/event-stream; charset=utf-8">>},
                         {<<"x-xss-protection">>,<<"1; mode=block">>},
                         {<<"x-frame-options">>,<<"SAMEORIGIN">>},
                         {<<"x-content-type-options">>,<<"nosniff">>},
                         {<<"content-security-policy">>,
                          <<"default-src 'self'">>},
                         {<<"cache-control">>,<<"no-store">>},
                         {<<"pragma">>,<<"no-cache">>},
                         {<<"referrer-policy">>,<<"no-referrer">>}]}

Code still discards the middleware. I think a good compromise may be:

init(ReplyTo, StreamRef, _, Headers, _) ->
    case lists:keyfind(<<"content-type">>, 1, Headers) of
        {_, <<"text/event-stream", _/binary>>} ->
            {ok, #state{reply_to=ReplyTo, stream_ref=StreamRef,
                sse_state=cow_sse:init()}};
        _ ->
            disable
    end.
filmor commented 2 years ago

A slightly stricter patch for this is included in #271, in that I parse the content type and just ignore the optional part. Your current proposal here would also allow text/event-stream-2.

essen commented 2 years ago

Closing in favor of #271. Thanks!