From 75e8f2badf7e3369ac0aa508a1d2b71ffa5d52d2 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 18 Feb 2022 16:42:15 -0700 Subject: [PATCH] fix request scheme which was always undefined --- src/elli_example_callback.erl | 3 +++ src/elli_http.erl | 11 +++++++++-- test/elli_ssl_tests.erl | 9 ++++++++- test/elli_tests.erl | 11 ++++++++++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/elli_example_callback.erl b/src/elli_example_callback.erl index 7eda4b8..399dea2 100644 --- a/src/elli_example_callback.erl +++ b/src/elli_example_callback.erl @@ -188,6 +188,9 @@ handle('GET', [<<"shorthand">>], _Req) -> handle('GET', [<<"ip">>], Req) -> {<<"200 OK">>, elli_request:peer(Req)}; +handle('GET', [<<"scheme">>], Req) -> + {<<"200 OK">>, elli_request:scheme(Req)}; + handle('GET', [<<"304">>], _Req) -> %% A "Not Modified" response is exactly like a normal response (so %% Content-Length is included), but the body will not be sent. diff --git a/src/elli_http.erl b/src/elli_http.erl index 4404a76..0fb6e5c 100644 --- a/src/elli_http.erl +++ b/src/elli_http.erl @@ -610,7 +610,7 @@ do_check_max_size_x2(_, _, _, _) -> ok. mk_req(Method, PathTuple, Headers, ParsedHeaders, Body, V, Socket, {Mod, Args} = Callback) -> case parse_path(PathTuple) of {ok, {Scheme, Host, Port}, {Path, URL, URLArgs}} -> - #req{method = Method, scheme = Scheme, host = Host, + #req{method = Method, scheme = update_scheme(Socket, Scheme), host = Host, port = Port, path = URL, args = URLArgs, version = V, raw_path = Path, original_headers = Headers, body = Body, pid = self(), socket = Socket, @@ -625,7 +625,14 @@ mk_req(Method, PathTuple, Headers, ParsedHeaders, Body, V, Socket, {Mod, Args} = mk_req(Method, Scheme, Host, Port, PathTuple, Headers, ParsedHeaders, Body, V, Socket, Callback) -> Req = mk_req(Method, PathTuple, Headers, ParsedHeaders, Body, V, Socket, Callback), - Req#req{scheme = Scheme, host = Host, port = Port}. + Req#req{scheme = update_scheme(Socket, Scheme), host = Host, port = Port}. + +update_scheme({plain, _}, undefined) -> + <<"http">>; +update_scheme({ssl, _}, undefined) -> + <<"https">>; +update_scheme(_, Scheme) -> + Scheme. %% %% HEADERS diff --git a/test/elli_ssl_tests.erl b/test/elli_ssl_tests.erl index 7a7d1d5..3b7b4bf 100644 --- a/test/elli_ssl_tests.erl +++ b/test/elli_ssl_tests.erl @@ -13,7 +13,8 @@ elli_ssl_test_() -> ?_test(hello_world()), ?_test(chunked()), ?_test(sendfile()), - ?_test(acceptor_leak_regression()) + ?_test(acceptor_leak_regression()), + ?_test(check_scheme_parsing()) ]} ]}. @@ -33,6 +34,12 @@ hello_world() -> ?assertMatch(200, status(Response)), ?assertMatch({ok, 200, _, _}, Response). +check_scheme_parsing() -> + Response = hackney:get("https://localhost:3443/scheme", + [], <<>>, [insecure]), + ?assertMatch(200, status(Response)), + ?assertMatch(<<"https">>, body(Response)). + chunked() -> Expected = <<"chunk10chunk9chunk8chunk7chunk6chunk5chunk4chunk3chunk2chunk1">>, diff --git a/test/elli_tests.erl b/test/elli_tests.erl index c89ba17..79f07e9 100644 --- a/test/elli_tests.erl +++ b/test/elli_tests.erl @@ -63,7 +63,8 @@ elli_test_() -> ?_test(get_pipeline()), ?_test(head()), ?_test(no_body()), - ?_test(sends_continue()) + ?_test(sends_continue()), + ?_test(check_scheme_parsing()) ]} ]}. @@ -108,12 +109,14 @@ accessors_test_() -> RawPath = <<"/foo/bar">>, Headers = [{<<"content-type">>, <<"application/x-www-form-urlencoded">>}], Method = 'POST', + Scheme = <<"http">>, Body = <<"name=knut%3D">>, Name = <<"knut=">>, Req1 = #req{raw_path = RawPath, original_headers = Headers, headers = Headers, method = Method, + scheme = Scheme, body = Body}, Args = [{<<"name">>, Name}], Req2 = #req{original_headers = Headers, headers = Headers, args = Args, body = <<>>}, @@ -123,6 +126,7 @@ accessors_test_() -> ?_assertMatch(RawPath, elli_request:raw_path(Req1)), ?_assertMatch(Headers, elli_request:headers(Req1)), ?_assertMatch(Method, elli_request:method(Req1)), + ?_assertMatch(Scheme, elli_request:scheme(Req1)), ?_assertMatch(Body, elli_request:body(Req1)), ?_assertMatch(Args, elli_request:post_args_decoded(Req1)), ?_assertMatch(undefined, elli_request:post_arg(<<"foo">>, Req1)), @@ -595,6 +599,11 @@ sends_continue() -> ?assertMatch({ok, ExpectedResponse}, gen_tcp:recv(Socket, size(ExpectedResponse))). +check_scheme_parsing() -> + Response = hackney:get("http://localhost:3001/scheme"), + ?assertMatch(200, status(Response)), + ?assertMatch(<<"http">>, body(Response)). + %%% Slow client, sending only the specified byte size every millisecond start_slow_client(Port, Url) ->