diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bbed24e..b946079 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,19 +16,9 @@ jobs: strategy: fail-fast: false matrix: - 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 + otp_version: [24, 25] + os: [ubuntu-22.04] + rebar3_version: [3.22] steps: - uses: actions/checkout@v4 diff --git a/elvis.config b/elvis.config index c96c782..346a11b 100644 --- a/elvis.config +++ b/elvis.config @@ -1,48 +1,27 @@ [ - { - elvis, - [ - {config, - [#{dirs => [ - "src" - %% TODO: "test" - ], - filter => "*.erl", - rules => [ - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace}, - {elvis_style, no_if_expression}, - {elvis_style, no_nested_try_catch}, - {elvis_style, invalid_dynamic_call, - #{ignore => [ - elli, - elli_http, - elli_middleware, - elli_test - ]}}, - {elvis_style, used_ignored_variable}, - {elvis_style, no_behavior_info}, - {elvis_style, state_record_and_type}, - {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself}, - {elvis_style, no_debug_call} - ], - ruleset => erl_files - }, - #{dirs => ["."], - filter => "Makefile", - ruleset => makefiles - }, - #{dirs => ["."], - filter => "rebar.config", + {elvis, [ + {config, [ + #{ + dirs => ["src/**", "test/**"], + filter => "*.erl", + ruleset => erl_files, + rules => [ + {elvis_style, operator_spaces, disable}, + {elvis_style, invalid_dynamic_call, disable}, + {elvis_style, dont_repeat_yourself, disable}, + {elvis_style, no_throw, disable} + ] + }, + #{ + dirs => ["."], + filter => "rebar.config", ruleset => rebar_config - }, - #{dirs => ["."], - filter => "elvis.config", + }, + #{ + dirs => ["."], + filter => "elvis.config", ruleset => elvis_config - } - ] - } - ] - } + } + ]} + ]} ]. diff --git a/rebar.config b/rebar.config index 706b4e0..fae2cba 100644 --- a/rebar.config +++ b/rebar.config @@ -1,12 +1,12 @@ {erl_first_files, ["src/elli_handler.erl"]}. {erl_opts, [debug_info, {i, "include"}]}. -{minimum_otp_vsn, "22.0"}. +{minimum_otp_vsn, "24"}. {deps, []}. {xref_checks, [undefined_function_calls,locals_not_used]}. {profiles, [ {docs, [ - {deps, [{edown, "0.8.1"}]}, + {deps, [{edown, "0.9.1"}]}, {edoc_opts, [ {preprocess, true}, {def, [ @@ -16,18 +16,18 @@ ]} ]}, {test, [ - {deps, [{hackney, "1.17.4"}]} + {deps, [{hackney, "1.20.1"}]} ]} ]}. {shell, [{script_file, "bin/shell.escript"}]}. {project_plugins, [ - {covertool, "2.0.3"}%, - %{rebar3_lint, "v0.1.10"} + {covertool, "2.0.6"}, + {rebar3_lint, "3.2.5"} ]}. -%{provider_hooks, [{pre, [{eunit, lint}]}]}. +{provider_hooks, [{pre, [{eunit, lint}]}]}. {dialyzer, [{plt_extra_apps, [ssl]}]}. {cover_enabled, true}. diff --git a/src/elli.erl b/src/elli.erl index 9f233ce..3cfcdfc 100644 --- a/src/elli.erl +++ b/src/elli.erl @@ -28,6 +28,7 @@ %% @type req(). A record representing an HTTP request. -type req() :: #req{}. +-elvis([{elvis_style, private_data_types, disable}]). %% @type http_method(). An uppercase atom representing a known HTTP verb or a %% binary for other verbs. @@ -162,11 +163,7 @@ init([Opts]) -> | SSLSockOpts]), Acceptors = ets:new(acceptors, [private, set]), - [begin - Pid = elli_http:start_link(self(), Socket, Options, - {Callback, CallbackArgs}), - ets:insert(Acceptors, {Pid}) - end + [http_start(Socket, Options, Callback, CallbackArgs, Acceptors) || _ <- lists:seq(1, MinAcceptors)], {ok, #state{socket = Socket, @@ -175,6 +172,9 @@ init([Opts]) -> options = Options, callback = {Callback, CallbackArgs}}}. +http_start(Socket, Options, Callback, CallbackArgs, Acceptors) -> + Pid = elli_http:start_link(self(), Socket, Options, {Callback, CallbackArgs}), + ets:insert(Acceptors, {Pid}). %% @hidden -spec handle_call(get_acceptors, {pid(), _Tag}, state()) -> diff --git a/src/elli_http.erl b/src/elli_http.erl index cd549e4..d733e88 100644 --- a/src/elli_http.erl +++ b/src/elli_http.erl @@ -36,6 +36,8 @@ -define(CONNECTION_HEADER, <<"connection">>). -define(TRANSFER_ENCODING_HEADER, <<"Transfer-Encoding">>). +-elvis([{elvis_style, max_function_arity, disable}]). + %% TODO: use this %% -type connection_token() :: keep_alive | close. @@ -58,7 +60,7 @@ start_link(Server, ListenSocket, Options, Callback) -> Options :: proplists:proplist(), Callback :: elli_handler:callback(). accept(Server, ListenSocket, Options, Callback) -> - case catch elli_tcp:accept(ListenSocket, Server, accept_timeout(Options)) of + case elli_tcp:accept(ListenSocket, Server, accept_timeout(Options)) of {ok, Socket} -> t(accepted), ?MODULE:keepalive_loop(Socket, Options, Callback); @@ -729,7 +731,7 @@ parse_path({abs_path, FullPath}) -> 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}) -> +parse_path({'absoluteURI', Scheme, Host, Port, Path}) -> setelement(2, parse_path({abs_path, Path}), {Scheme, Host, Port}); parse_path(_) -> {error, unsupported_uri}. diff --git a/src/elli_request.erl b/src/elli_request.erl index 6500ee2..bc235ed 100644 --- a/src/elli_request.erl +++ b/src/elli_request.erl @@ -44,6 +44,7 @@ | {offset, Offset::non_neg_integer()} | {suffix, Length::pos_integer()}. +-elvis([{elvis_style, god_modules, disable}]). %% %% Helpers for working with a #req{} diff --git a/src/elli_sendfile.erl b/src/elli_sendfile.erl index d67ded4..5a11a67 100644 --- a/src/elli_sendfile.erl +++ b/src/elli_sendfile.erl @@ -6,6 +6,7 @@ -export([sendfile/5]). -type sendfile_opts() :: [{chunk_size, non_neg_integer()}]. +-export_type([sendfile_opts/0]). %% @doc Send part of a file on a socket. %% diff --git a/test/elli_middleware_tests.erl b/test/elli_middleware_tests.erl index ea303ee..8761643 100644 --- a/test/elli_middleware_tests.erl +++ b/test/elli_middleware_tests.erl @@ -28,9 +28,9 @@ hello_world() -> ?assertMatch(<<"Hello World!">>, body(Response)). compress() -> - Url = "http://localhost:3002/compressed", + URL = "http://localhost:3002/compressed", Headers = [{<<"Accept-Encoding">>, <<"gzip">>}], - Response = hackney:get(Url, Headers), + Response = hackney:get(URL, Headers), ?assertHeadersEqual([{<<"Connection">>, <<"Keep-Alive">>}, {<<"Content-Encoding">>, <<"gzip">>}, {<<"Content-Length">>, <<"41">>}], diff --git a/test/elli_tests.erl b/test/elli_tests.erl index fb62ed1..266808c 100644 --- a/test/elli_tests.erl +++ b/test/elli_tests.erl @@ -472,7 +472,8 @@ sendfile_range() -> ?assertMatch(206, status(Response)), ?assertHeadersEqual([{<<"connection">>, <<"Keep-Alive">>}, {<<"content-length">>, <<"400">>}, - {<<"Content-Range">>, iolist_to_binary(["bytes 300-699/", integer_to_binary(Size)])}], + {<<"Content-Range">>, + iolist_to_binary(["bytes 300-699/", integer_to_binary(Size)])}], headers(Response)), ?assertEqual(Expected, body(Response)). @@ -735,7 +736,8 @@ register_test() -> ok. invalid_callback_test() -> - case catch elli:start_link([{callback, elli}]) of - E -> - ?assertMatch(invalid_callback, E) + try + elli:start_link([{callback, elli}]) + catch _:E -> + ?assertMatch(invalid_callback, E) end.