diff options
author | Kirilll Zaborsky <qrilka@gmail.com> | 2015-07-20 16:38:33 +0300 |
---|---|---|
committer | Henrik Nord <henrik@erlang.org> | 2015-10-13 11:15:34 +0200 |
commit | f8750f121176c6cedc7b3162b6656ce201c9fe97 (patch) | |
tree | dd34f90b5f91ec81ecce16def8111bec585cb43d /lib | |
parent | 981dd4509dbabcf3af3d4df611163987e10bca41 (diff) | |
download | otp-f8750f121176c6cedc7b3162b6656ce201c9fe97.tar.gz otp-f8750f121176c6cedc7b3162b6656ce201c9fe97.tar.bz2 otp-f8750f121176c6cedc7b3162b6656ce201c9fe97.zip |
inets: fix suppport of HTTP headers with obs-fold
httpc should not fail when response contains (now deprecated)
multiline HTTP headers constructed with obs-folds. And as
RFC7230 specifies user agent should replace obs-folds with
spaces.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/inets/src/http_lib/http_response.erl | 30 | ||||
-rw-r--r-- | lib/inets/test/httpc_SUITE.erl | 15 |
2 files changed, 36 insertions, 9 deletions
diff --git a/lib/inets/src/http_lib/http_response.erl b/lib/inets/src/http_lib/http_response.erl index 58b30c4e9e..d13670700c 100644 --- a/lib/inets/src/http_lib/http_response.erl +++ b/lib/inets/src/http_lib/http_response.erl @@ -31,16 +31,11 @@ %% Value - string() %% %% Description: Creates a http_response_h-record used internally to -%% handle http-headers. +%% handle http-headers, assumes reversed list of headers +%% to unfold multiline headers with obs-folds %%------------------------------------------------------------------------- -headers([], Headers) -> - Headers; - -headers([Header | Tail], Headers) -> - {Key, [$: | Value]} = - lists:splitwith(fun($:) -> false; (_) -> true end, Header), - headers(Tail, headers(http_util:to_lower(string:strip(Key)), - string:strip(Value), Headers)). +headers(RevLines, Headers) -> + fill_headers(RevLines, [], Headers). %%------------------------------------------------------------------------- %% headers(#http_response_h{}) -> HeaderList @@ -68,6 +63,23 @@ header_list(Headers) -> %%%======================================================================== %%% Internal functions %%%======================================================================== +fill_headers([], _, Headers) -> + Headers; +fill_headers([[Ch|HeaderFold]|Tail], Folded, Headers) + when Ch == $\t; Ch == $\s -> + fill_headers(Tail, [HeaderFold|Folded], Headers); +fill_headers([Header | Tail], Folded, Headers) -> + Unfolded = unfold([Header|Folded]), + {Key, [$: | Value]} = + lists:splitwith(fun($:) -> false; (_) -> true end, Unfolded), + fill_headers(Tail, [], headers(http_util:to_lower(string:strip(Key)), + string:strip(Value), Headers)). + +unfold([L]) -> + L; +unfold(Folded) -> + string:join(Folded, " "). + headers("cache-control", Value, Headers) -> Headers#http_response_h{'cache-control'= Value}; headers("connection", Value, Headers) -> diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index 5b40d08859..2ad00bdf76 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -105,6 +105,7 @@ only_simulated() -> internal_server_error, invalid_http, headers_dummy, + headers_with_obs_fold, empty_response_header, remote_socket_close, remote_socket_close_async, @@ -893,6 +894,13 @@ headers_dummy(Config) when is_list(Config) -> %%------------------------------------------------------------------------- +headers_with_obs_fold(Config) when is_list(Config) -> + Request = {url(group_name(Config), "/obs_folded_headers.html", Config), []}, + {ok, {{_,200,_}, Headers, [_|_]}} = httpc:request(get, Request, [], []), + "a b" = proplists:get_value("folded", Headers). + +%%------------------------------------------------------------------------- + invalid_headers(Config) -> Request = {url(group_name(Config), "/dummy.html", Config), [{"cookie", undefined}]}, {error, _} = httpc:request(get, Request, [], []). @@ -1713,6 +1721,13 @@ handle_uri(_,"/dummy_headers.html",_,_,Socket,_) -> send(Socket, http_chunk:encode("obar</BODY></HTML>")), http_chunk:encode_last(); +handle_uri(_,"/obs_folded_headers.html",_,_,_,_) -> + "HTTP/1.1 200 ok\r\n" + "Content-Length:5\r\n" + "Folded: a\r\n" + " b\r\n\r\n" + "Hello"; + handle_uri(_,"/capital_transfer_encoding.html",_,_,Socket,_) -> Head = "HTTP/1.1 200 ok\r\n" ++ "Transfer-Encoding:Chunked\r\n\r\n", |