diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6f7fbee..bbed24e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,17 +14,50 @@ jobs: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: - otp_version: ['24', '23', '22', '21'] - os: [ubuntu-latest] + include: + - otp_version: 25 + os: ubuntu-22.04 + rebar3_version: 3.22 + - otp_version: 24 + os: ubuntu-22.04 + rebar3_version: 3.22 + - otp_version: 23 + os: ubuntu-20.04 + rebar3_version: 3.18 + - otp_version: 22 + os: ubuntu-20.04 + rebar3_version: 3.18 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: erlef/setup-beam@v1 + id: setup-beam with: otp-version: ${{ matrix.otp_version }} - rebar3-version: '3.14' + rebar3-version: ${{ matrix.rebar3_version }} + + - name: Restore _build + uses: actions/cache@v3 + with: + path: _build + key: "_build-cache-for\ + -os-${{ matrix.os }}\ + -otp-${{ steps.setup-beam.outputs.otp-version }}\ + -rebar3-${{ steps.setup-beam.outputs.rebar3-version }}\ + -hash-${{ hashFiles('rebar.lock') }}" + + - name: Restore rebar3's cache + uses: actions/cache@v3 + with: + path: ~/.cache/rebar3 + key: "rebar3-cache-for\ + -os-${{ matrix.os }}\ + -otp-${{ steps.setup-beam.outputs.otp-version }}\ + -rebar3-${{ steps.setup-beam.outputs.rebar3-version }}\ + -hash-${{ hashFiles('rebar.lock') }}" - name: Compile run: rebar3 compile @@ -36,9 +69,8 @@ jobs: run: rebar3 xref - name: Covertool - if: ${{ always() }} run: rebar3 covertool generate - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v4 with: - file: _build/test/covertool/elli.covertool.xml + files: _build/test/covertool/elli.covertool.xml env_vars: OTP_VERSION diff --git a/rebar.config b/rebar.config index 07ba484..706b4e0 100644 --- a/rebar.config +++ b/rebar.config @@ -1,9 +1,7 @@ {erl_first_files, ["src/elli_handler.erl"]}. {erl_opts, [debug_info, - {i, "include"}, - {platform_define, "^2", binary_http_uri}, - {platform_define, "^2[1-9]", post20}]}. -{minimum_otp_vsn, "20.0"}. + {i, "include"}]}. +{minimum_otp_vsn, "22.0"}. {deps, []}. {xref_checks, [undefined_function_calls,locals_not_used]}. {profiles, [ @@ -25,11 +23,11 @@ {shell, [{script_file, "bin/shell.escript"}]}. {project_plugins, [ - {covertool, "2.0.3"}, - {rebar3_lint, "v0.1.10"} + {covertool, "2.0.3"}%, + %{rebar3_lint, "v0.1.10"} ]}. -{provider_hooks, [{pre, [{eunit, lint}]}]}. +%{provider_hooks, [{pre, [{eunit, lint}]}]}. {dialyzer, [{plt_extra_apps, [ssl]}]}. {cover_enabled, true}. diff --git a/src/elli_http.erl b/src/elli_http.erl index 4404a76..cd549e4 100644 --- a/src/elli_http.erl +++ b/src/elli_http.erl @@ -323,17 +323,17 @@ execute_callback(#req{callback = {Mod, Args}} = Req) -> catch throw:{ResponseCode, Headers, Body} when is_integer(ResponseCode) -> {response, ResponseCode, Headers, Body}; - ?WITH_STACKTRACE(throw, Exc, Stacktrace) + throw:Exc:Stacktrace -> handle_event(Mod, request_throw, [Req, Exc, Stacktrace], Args), {response, 500, [], <<"Internal server error">>}; - ?WITH_STACKTRACE(error, Error, Stacktrace) + error:Error:Stacktrace -> handle_event(Mod, request_error, [Req, Error, Stacktrace], Args), {response, 500, [], <<"Internal server error">>}; - ?WITH_STACKTRACE(exit, Exit, Stacktrace) + exit:Exit:Stacktrace -> handle_event(Mod, request_exit, [Req, Exit, Stacktrace], Args), @@ -708,7 +708,6 @@ is_header_defined(Key, Headers) -> get_header(Key, Headers) -> get_header(Key, Headers, undefined). --ifdef(OTP_RELEASE). get_header(Key, Headers, Default) -> CaseFoldedKey = string:casefold(Key), case lists:search(fun({N, _}) -> string:equal(CaseFoldedKey, N, true) end, Headers) of @@ -717,68 +716,23 @@ get_header(Key, Headers, Default) -> false -> Default end. --else. -get_header(Key, Headers, Default) -> - CaseFoldedKey = string:casefold(Key), - case search(fun({N, _}) -> string:equal(CaseFoldedKey, N, true) end, Headers) of - {value, {_, Value}} -> - Value; - false -> - Default - end. - -search(Pred, [Hd|Tail]) -> - case Pred(Hd) of - true -> {value, Hd}; - false -> search(Pred, Tail) - end; -search(Pred, []) when is_function(Pred, 1) -> - false. --endif. %% %% PATH HELPERS %% --ifdef(OTP_RELEASE). - -if(?OTP_RELEASE >= 22). - parse_path({abs_path, FullPath}) -> - URIMap = uri_string:parse(FullPath), - Host = maps:get(host, URIMap, undefined), - Scheme = maps:get(scheme, URIMap, undefined), - Path = maps:get(path, URIMap, <<>>), - Query = maps:get(query, URIMap, <<>>), - Port = maps:get(port, URIMap, case Scheme of http -> 80; https -> 443; _ -> undefined end), - {ok, {Scheme, Host, Port}, {Path, split_path(Path), uri_string:dissect_query(Query)}}; - parse_path({absoluteURI, Scheme, Host, Port, Path}) -> - setelement(2, parse_path({abs_path, Path}), {Scheme, Host, Port}); - parse_path(_) -> - {error, unsupported_uri}. - -else. - parse_path({abs_path, FullPath}) -> - Parsed = case binary:split(FullPath, [<<"?">>]) of - [URL] -> {FullPath, split_path(URL), []}; - [URL, Args] -> {FullPath, split_path(URL), split_args(Args)} - end, - {ok, {undefined, undefined, undefined}, Parsed}; - parse_path({absoluteURI, Scheme, Host, Port, Path}) -> - setelement(2, parse_path({abs_path, Path}), {Scheme, Host, Port}); - parse_path(_) -> - {error, unsupported_uri}. - -endif. --else. - %% same as else branch above. can drop this when only OTP 21+ is supported - parse_path({abs_path, FullPath}) -> - Parsed = case binary:split(FullPath, [<<"?">>]) of - [URL] -> {FullPath, split_path(URL), []}; - [URL, Args] -> {FullPath, split_path(URL), split_args(Args)} - end, - {ok, {undefined, undefined, undefined}, Parsed}; - parse_path({absoluteURI, Scheme, Host, Port, Path}) -> - setelement(2, parse_path({abs_path, Path}), {Scheme, Host, Port}); - parse_path(_) -> - {error, unsupported_uri}. --endif. +parse_path({abs_path, FullPath}) -> + URIMap = uri_string:parse(FullPath), + Host = maps:get(host, URIMap, undefined), + Scheme = maps:get(scheme, URIMap, undefined), + Path = maps:get(path, URIMap, <<>>), + Query = maps:get(query, URIMap, <<>>), + Port = maps:get(port, URIMap, case Scheme of http -> 80; https -> 443; _ -> undefined end), + {ok, {Scheme, Host, Port}, {Path, split_path(Path), uri_string:dissect_query(Query)}}; +parse_path({absoluteURI, Scheme, Host, Port, Path}) -> + setelement(2, parse_path({abs_path, Path}), {Scheme, Host, Port}); +parse_path(_) -> + {error, unsupported_uri}. split_path(Path) -> [P || P <- binary:split(Path, [<<"/">>], [global]), @@ -813,7 +767,7 @@ handle_event(Mod, Name, EventArgs, ElliArgs) -> try Mod:handle_event(Name, EventArgs, ElliArgs) catch - ?WITH_STACKTRACE(EvClass, EvError, Stacktrace) + EvClass:EvError:Stacktrace -> ?LOG_ERROR("~p:handle_event/3 crashed ~p:~p~n~p", [Mod, EvClass, EvError, Stacktrace]) end. diff --git a/src/elli_tcp.erl b/src/elli_tcp.erl index ee9ad39..b0f3fdc 100644 --- a/src/elli_tcp.erl +++ b/src/elli_tcp.erl @@ -42,7 +42,6 @@ accept({ssl, Socket}, Server, Timeout) -> {error, Reason} end. --ifdef(post20). handshake(S, Server, Timeout) -> case ssl:handshake(S, Timeout) of {ok, S1} -> @@ -53,18 +52,6 @@ handshake(S, Server, Timeout) -> {error, Reason} -> {error, Reason} end. --else. -handshake(S, Server, Timeout) -> - case ssl:ssl_accept(S, Timeout) of - ok -> - gen_server:cast(Server, accepted), - {ok, {ssl, S}}; - {error, closed} -> - {error, econnaborted}; - {error, Reason} -> - {error, Reason} - end. --endif. recv({plain, Socket}, Size, Timeout) -> gen_tcp:recv(Socket, Size, Timeout); diff --git a/src/elli_util.hrl b/src/elli_util.hrl index 557ec28..e844c95 100644 --- a/src/elli_util.hrl +++ b/src/elli_util.hrl @@ -1,17 +1,4 @@ - --ifdef(OTP_RELEASE). -include_lib("kernel/include/logger.hrl"). --else. --define(LOG_ERROR(Str), error_logger:error_msg(Str)). --define(LOG_ERROR(Format,Data), error_logger:error_msg(Format, Data)). --define(LOG_INFO(Format,Data), error_logger:info_msg(Format, Data)). --endif. - --ifdef(OTP_RELEASE). --define(WITH_STACKTRACE(T, R, S), T:R:S ->). --else. --define(WITH_STACKTRACE(T, R, S), T:R -> S = erlang:get_stacktrace(),). --endif. %% Bloody useful -define(IF(Test,True,False), case Test of true -> True; false -> False end). diff --git a/test/elli_tests.erl b/test/elli_tests.erl index c89ba17..fb62ed1 100644 --- a/test/elli_tests.erl +++ b/test/elli_tests.erl @@ -7,13 +7,7 @@ -define(VTB(T1, T2, LB, UB), time_diff_to_micro_seconds(T1, T2) >= LB andalso time_diff_to_micro_seconds(T1, T2) =< UB). --ifdef(OTP_RELEASE). -include_lib("kernel/include/logger.hrl"). --else. --define(LOG_ERROR(Str), error_logger:error_msg(Str)). --define(LOG_ERROR(Format,Data), error_logger:error_msg(Format, Data)). --define(LOG_INFO(Format,Data), error_logger:info_msg(Format, Data)). --endif. time_diff_to_micro_seconds(T1, T2) -> erlang:convert_time_unit(