From 465d072abf4a76104d4562ed15345b27fe9a0cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 21 Oct 2020 19:15:48 +0200 Subject: Fix cookie handling when tunnel and origin schemes mismatch The cookie_ignore_informational has been moved to http_opts and http2_opts. Also fix an issue when using 'protocols' in gun:open. When connecting via TLS the protocol's options were discarded. --- src/gun_cookies.erl | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/gun_cookies.erl') diff --git a/src/gun_cookies.erl b/src/gun_cookies.erl index 965c3a5..0537832 100644 --- a/src/gun_cookies.erl +++ b/src/gun_cookies.erl @@ -21,6 +21,7 @@ -export([query/2]). -export([session_gc/1]). -export([set_cookie/5]). +-export([set_cookie_header/7]). -ifdef(TEST). -export([wpt_http_state_test_files/1]). %% Also used in rfc6265bis_SUITE. @@ -341,6 +342,37 @@ store({Mod, State0}, Cookie) -> Error end. +-spec set_cookie_header(binary(), iodata(), iodata(), cow_http:status(), + Headers, Store, #{cookie_ignore_informational := boolean()}) + -> {Headers, Store} when Headers :: [{binary(), iodata()}], Store :: undefined | store(). +%% Don't set cookies when cookie store isn't configured. +set_cookie_header(_, _, _, _, _, Store=undefined, _) -> + Store; +%% Ignore cookies set on informational responses when configured to do so. +%% This includes cookies set to Websocket upgrade responses! +set_cookie_header(_, _, _, Status, _, Store, #{cookie_ignore_informational := true}) + when Status >= 100, Status =< 199 -> + Store; +set_cookie_header(Scheme, Authority, PathWithQs, _, Headers, Store0, _) -> + #{host := Host, path := Path} = uri_string:parse([Scheme, <<"://">>, Authority, PathWithQs]), + URIMap = uri_string:normalize(#{ + scheme => Scheme, + host => iolist_to_binary(Host), + path => iolist_to_binary(Path) + }, [return_map]), + SetCookies = [SC || {<<"set-cookie">>, SC} <- Headers], + lists:foldl(fun(SC, Store1) -> + case cow_cookie:parse_set_cookie(SC) of + {ok, N, V, A} -> + case set_cookie(Store1, URIMap, N, V, A) of + {ok, Store} -> Store; + {error, _} -> Store1 + end; + ignore -> + Store1 + end + end, Store0, SetCookies). + -ifdef(TEST). gc_test() -> URIMap = #{scheme => <<"http">>, host => <<"example.org">>, path => <<"/path/to/resource">>}, -- cgit v1.2.3