From e10daf39fa08fb1367b277b31b4c9c9baad5239b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 2 Jan 2017 16:47:16 +0100 Subject: Numerous Dialyzer fixes --- src/cowboy.erl | 9 ++++++--- src/cowboy_constraints.erl | 1 + src/cowboy_handler.erl | 4 ++-- src/cowboy_http.erl | 4 ++-- src/cowboy_middleware.erl | 2 +- src/cowboy_req.erl | 30 +++++++++++++++++++----------- src/cowboy_rest.erl | 2 +- src/cowboy_static.erl | 3 +-- src/cowboy_stream_h.erl | 6 +++--- src/cowboy_tls.erl | 6 +++--- src/cowboy_websocket.erl | 11 ++++------- 11 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/cowboy.erl b/src/cowboy.erl index 3b272c5..95eb9cc 100644 --- a/src/cowboy.erl +++ b/src/cowboy.erl @@ -37,14 +37,17 @@ -type http_version() :: 'HTTP/2' | 'HTTP/1.1' | 'HTTP/1.0'. -export_type([http_version/0]). --spec start_clear(ranch:ref(), non_neg_integer(), ranch_tcp:opts(), - cowboy_protocol:opts()) -> {ok, pid()} | {error, any()}. +%% @todo We should hide NbAcceptors in a socket variable, even if Ranch +%% doesn't let us do that yet. +-spec start_clear(ranch:ref(), non_neg_integer(), ranch_tcp:opts(), opts()) + -> {ok, pid()} | {error, any()}. start_clear(Ref, NbAcceptors, TransOpts0, ProtoOpts) when is_integer(NbAcceptors), NbAcceptors > 0 -> TransOpts = [connection_type(ProtoOpts)|TransOpts0], ranch:start_listener(Ref, NbAcceptors, ranch_tcp, TransOpts, cowboy_clear, ProtoOpts). --spec start_tls(ranch:ref(), non_neg_integer(), ranch_ssl:opts(), opts()) -> {ok, pid()} | {error, any()}. +-spec start_tls(ranch:ref(), non_neg_integer(), ranch_ssl:opts(), opts()) + -> {ok, pid()} | {error, any()}. start_tls(Ref, NbAcceptors, TransOpts0, ProtoOpts) when is_integer(NbAcceptors), NbAcceptors > 0 -> TransOpts = [ diff --git a/src/cowboy_constraints.erl b/src/cowboy_constraints.erl index 9bd578e..72a6a18 100644 --- a/src/cowboy_constraints.erl +++ b/src/cowboy_constraints.erl @@ -58,3 +58,4 @@ int(Value) when is_binary(Value) -> nonempty(<<>>) -> false; nonempty(Value) when is_binary(Value) -> true. +%% @todo Perhaps return true for any other type except empty list? diff --git a/src/cowboy_handler.erl b/src/cowboy_handler.erl index af21342..4dbe226 100644 --- a/src/cowboy_handler.erl +++ b/src/cowboy_handler.erl @@ -39,7 +39,7 @@ execute(Req, Env=#{handler := Handler, handler_opts := HandlerOpts}) -> try Handler:init(Req, HandlerOpts) of {ok, Req2, State} -> Result = terminate(normal, Req2, State, Handler), - {ok, Req2, [{result, Result}|Env]}; + {ok, Req2, Env#{result => Result}}; {Mod, Req2, State} -> Mod:upgrade(Req2, Env, Handler, State, infinity, run); {Mod, Req2, State, hibernate} -> @@ -53,7 +53,7 @@ execute(Req, Env=#{handler := Handler, handler_opts := HandlerOpts}) -> erlang:raise(Class, Reason, erlang:get_stacktrace()) end. --spec terminate(any(), Req, any(), module()) -> ok when Req::cowboy_req:req(). +-spec terminate(any(), Req | undefined, any(), module()) -> ok when Req::cowboy_req:req(). terminate(Reason, Req, State, Handler) -> case erlang:function_exported(Handler, terminate, 3) of true -> diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index ae42e6d..f38db97 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -44,7 +44,7 @@ qs = undefined :: binary(), version = undefined :: cowboy:http_version(), headers = undefined :: map() | undefined, %% @todo better type than map() - name = undefined :: binary() + name = undefined :: binary() | undefined }). %% @todo We need a state where we wait for the stream process to ask for the body. @@ -1027,7 +1027,7 @@ terminate(_State, _Reason) -> %% System callbacks. --spec system_continue(_, _, #state{}) -> ok. +-spec system_continue(_, _, {#state{}, binary()}) -> ok. system_continue(_, _, {State, Buffer}) -> loop(State, Buffer). diff --git a/src/cowboy_middleware.erl b/src/cowboy_middleware.erl index 7b0e760..03c87e2 100644 --- a/src/cowboy_middleware.erl +++ b/src/cowboy_middleware.erl @@ -14,7 +14,7 @@ -module(cowboy_middleware). --type env() :: [{atom(), any()}]. +-type env() :: #{atom() => any()}. -export_type([env/0]). -callback execute(Req, Env) diff --git a/src/cowboy_req.erl b/src/cowboy_req.erl index df93ed6..a6f3c07 100644 --- a/src/cowboy_req.erl +++ b/src/cowboy_req.erl @@ -48,6 +48,7 @@ -export([read_body/2]). -export([read_urlencoded_body/1]). -export([read_urlencoded_body/2]). +%% @todo read_and_match_urlencoded_body? %% Multipart. -export([read_part/1]). @@ -63,7 +64,7 @@ -export([has_resp_header/2]). %% @todo resp_header -export([delete_resp_header/2]). --export([set_resp_body/2]). %% @todo Use set_resp_body for iodata() | {sendfile ...} +-export([set_resp_body/2]). %% @todo set_resp_body/3 with a ContentType or even Headers argument, to set content headers. -export([has_resp_body/1]). -export([reply/2]). @@ -80,15 +81,16 @@ %% Internal. -export([response_headers/2]). --type cookie_opts() :: cow_cookie:cookie_opts(). +%% @todo Get rid of this type, use cow_cookie directly. +-type cookie_opts() :: map(). -export_type([cookie_opts/0]). --type body_opts() :: #{ +-type read_body_opts() :: #{ length => non_neg_integer(), period => non_neg_integer(), timeout => timeout() }. --export_type([body_opts/0]). +-export_type([read_body_opts/0]). %% While sendfile allows a Len of 0 that means "everything past Offset", %% Cowboy expects the real length as it is used as metadata. @@ -97,7 +99,13 @@ | {sendfile, non_neg_integer(), pos_integer(), file:name_all()}. -export_type([resp_body/0]). --type push_opts() :: map(). %% @todo +-type push_opts() :: #{ + method => binary(), + scheme => binary(), + host => binary(), + port => binary(), + qs => binary() +}. -export_type([push_opts/0]). -type req() :: map(). %% @todo #{ @@ -107,7 +115,7 @@ % peer := {inet:ip_address(), inet:port_number()}, % % method := binary(), %% case sensitive -% version := cowboy:http_version(), +% version := cowboy:http_version() | atom(), % scheme := binary(), %% <<"http">> or <<"https">> % host := binary(), %% lowercase; case insensitive % port := inet:port_number(), @@ -408,7 +416,7 @@ body_length(#{body_length := Length}) -> read_body(Req) -> read_body(Req, #{}). --spec read_body(Req, body_opts()) -> {ok, binary(), Req} | {more, binary(), Req} when Req::req(). +-spec read_body(Req, read_body_opts()) -> {ok, binary(), Req} | {more, binary(), Req} when Req::req(). read_body(Req=#{has_body := false}, _) -> {ok, <<>>, Req}; read_body(Req=#{has_read_body := true}, _) -> @@ -439,7 +447,7 @@ set_body_length(Req=#{headers := Headers}, BodyLength) -> read_urlencoded_body(Req) -> read_urlencoded_body(Req, #{length => 64000, period => 5000}). --spec read_urlencoded_body(Req, body_opts()) -> {ok, [{binary(), binary() | true}], Req} when Req::req(). +-spec read_urlencoded_body(Req, read_body_opts()) -> {ok, [{binary(), binary() | true}], Req} when Req::req(). read_urlencoded_body(Req0, Opts) -> {ok, Body, Req} = read_body(Req0, Opts), {ok, cow_qs:parse_qs(Body), Req}. @@ -452,7 +460,7 @@ read_urlencoded_body(Req0, Opts) -> read_part(Req) -> read_part(Req, #{length => 64000, period => 5000}). --spec read_part(Req, body_opts()) +-spec read_part(Req, read_body_opts()) -> {ok, cow_multipart:headers(), Req} | {done, Req} when Req::req(). read_part(Req, Opts) -> @@ -487,7 +495,7 @@ read_part(Buffer, Opts, Req=#{multipart := {Boundary, _}}) -> read_part_body(Req) -> read_part_body(Req, #{}). --spec read_part_body(Req, body_opts()) +-spec read_part_body(Req, read_body_opts()) -> {ok, binary(), Req} | {more, binary(), Req} when Req::req(). read_part_body(Req, Opts) -> @@ -662,7 +670,7 @@ push(Path, Headers, Req) -> %% @todo Optimization: don't send anything at all for HTTP/1.0 and HTTP/1.1. %% @todo Path, Headers, Opts, everything should be in proper binary, %% or normalized when creating the Req object. --spec push(binary(), cowboy:http_headers(), req(), push_opts()) -> ok. +-spec push(iodata(), cowboy:http_headers(), req(), push_opts()) -> ok. push(Path, Headers, #{pid := Pid, streamid := StreamID, scheme := Scheme0, host := Host0, port := Port0}, Opts) -> Method = maps:get(method, Opts, <<"GET">>), diff --git a/src/cowboy_rest.erl b/src/cowboy_rest.erl index 33ef1d7..3f6e55b 100644 --- a/src/cowboy_rest.erl +++ b/src/cowboy_rest.erl @@ -205,7 +205,7 @@ handler_state :: any(), %% Allowed methods. Only used for OPTIONS requests. - allowed_methods :: [binary()], + allowed_methods :: [binary()] | undefined, %% Media type. content_types_p = [] :: diff --git a/src/cowboy_static.erl b/src/cowboy_static.erl index d13db62..e7b2127 100644 --- a/src/cowboy_static.erl +++ b/src/cowboy_static.erl @@ -285,10 +285,9 @@ last_modified(Req, State={_, {ok, #file_info{mtime=Modified}}, _}) -> {Modified, Req, State}. %% Stream the file. -%% @todo Export cowboy_req:resp_body_fun()? -spec get_file(Req, State) - -> {{stream, non_neg_integer(), fun()}, Req, State} + -> {{sendfile, 0, non_neg_integer(), binary()}, Req, State} when State::state(). get_file(Req, State={Path, {ok, #file_info{size=Size}}, _}) -> {{sendfile, 0, Size, Path}, Req, State}. diff --git a/src/cowboy_stream_h.erl b/src/cowboy_stream_h.erl index a7ce721..70772c8 100644 --- a/src/cowboy_stream_h.erl +++ b/src/cowboy_stream_h.erl @@ -28,10 +28,10 @@ -record(state, { ref = undefined :: ranch:ref(), pid = undefined :: pid(), - read_body_ref = undefined :: reference(), - read_body_timer_ref = undefined :: reference(), + read_body_ref = undefined :: reference() | undefined, + read_body_timer_ref = undefined :: reference() | undefined, read_body_length = 0 :: non_neg_integer() | infinity, - read_body_is_fin = nofin :: nofin | fin, + read_body_is_fin = nofin :: nofin | {fin, non_neg_integer()}, read_body_buffer = <<>> :: binary() }). diff --git a/src/cowboy_tls.erl b/src/cowboy_tls.erl index c9999e3..eed7562 100644 --- a/src/cowboy_tls.erl +++ b/src/cowboy_tls.erl @@ -18,12 +18,12 @@ -export([start_link/4]). -export([proc_lib_hack/5]). --spec start_link(ranch:ref(), inet:socket(), module(), cowboy:opts()) -> {ok, pid()}. +-spec start_link(ranch:ref(), ssl:sslsocket(), module(), cowboy:opts()) -> {ok, pid()}. start_link(Ref, Socket, Transport, Opts) -> Pid = proc_lib:spawn_link(?MODULE, proc_lib_hack, [self(), Ref, Socket, Transport, Opts]), {ok, Pid}. --spec proc_lib_hack(pid(), ranch:ref(), inet:socket(), module(), cowboy:opts()) -> ok. +-spec proc_lib_hack(pid(), ranch:ref(), ssl:sslsocket(), module(), cowboy:opts()) -> ok. proc_lib_hack(Parent, Ref, Socket, Transport, Opts) -> try init(Parent, Ref, Socket, Transport, Opts) @@ -34,7 +34,7 @@ proc_lib_hack(Parent, Ref, Socket, Transport, Opts) -> _:Reason -> exit({Reason, erlang:get_stacktrace()}) end. --spec init(pid(), ranch:ref(), inet:socket(), module(), cowboy:opts()) -> ok. +-spec init(pid(), ranch:ref(), ssl:sslsocket(), module(), cowboy:opts()) -> ok. init(Parent, Ref, Socket, Transport, Opts) -> ok = ranch:accept_ack(Ref), case ssl:negotiated_protocol(Socket) of diff --git a/src/cowboy_websocket.erl b/src/cowboy_websocket.erl index c8a6dd0..459d2e7 100644 --- a/src/cowboy_websocket.erl +++ b/src/cowboy_websocket.erl @@ -54,7 +54,7 @@ -optional_callbacks([terminate/3]). -record(state, { - socket = undefined :: inet:socket(), + socket = undefined :: inet:socket() | undefined, transport = undefined :: module(), handler :: module(), key = undefined :: undefined | binary(), @@ -309,8 +309,7 @@ websocket_dispatch(State=#state{socket=Socket, transport=Transport, frag_state=F handler_call(State, HandlerState, RemainingData, websocket_handle, Frame, fun websocket_data/3) end. --spec handler_call(#state{}, any(), binary(), atom(), any(), fun()) - -> {ok, cowboy_middleware:env()}. +-spec handler_call(#state{}, any(), binary(), atom(), any(), fun()) -> no_return(). handler_call(State=#state{handler=Handler}, HandlerState, RemainingData, Callback, Message, NextState) -> try case Callback of @@ -375,8 +374,7 @@ is_close_frame({close, _}) -> true; is_close_frame({close, _, _}) -> true; is_close_frame(_) -> false. --spec websocket_close(#state{}, any(), terminate_reason()) - -> {ok, cowboy_middleware:env()}. +-spec websocket_close(#state{}, any(), terminate_reason()) -> no_return(). websocket_close(State=#state{socket=Socket, transport=Transport, extensions=Extensions}, HandlerState, Reason) -> case Reason of @@ -395,8 +393,7 @@ websocket_close(State=#state{socket=Socket, transport=Transport, extensions=Exte end, handler_terminate(State, HandlerState, Reason). --spec handler_terminate(#state{}, any(), terminate_reason()) - -> {ok, cowboy_middleware:env()}. +-spec handler_terminate(#state{}, any(), terminate_reason()) -> no_return(). handler_terminate(#state{handler=Handler}, HandlerState, Reason) -> cowboy_handler:terminate(Reason, undefined, HandlerState, Handler), -- cgit v1.2.3