mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 20:30:23 +00:00
Fix warnings
This commit is contained in:
parent
7bdd710849
commit
0193538dba
4 changed files with 18 additions and 164 deletions
|
@ -201,13 +201,13 @@ loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
|
||||||
terminate(State, {internal_error, timeout, 'No message or data received before timeout.'})
|
terminate(State, {internal_error, timeout, 'No message or data received before timeout.'})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
set_request_timeout(State0=#state{timer=TimerRef0, opts=Opts}) ->
|
set_request_timeout(State0=#state{opts=Opts}) ->
|
||||||
State = cancel_request_timeout(State0),
|
State = cancel_request_timeout(State0),
|
||||||
Timeout = maps:get(request_timeout, Opts, 5000),
|
Timeout = maps:get(request_timeout, Opts, 5000),
|
||||||
TimerRef = erlang:start_timer(Timeout, self(), request_timeout),
|
TimerRef = erlang:start_timer(Timeout, self(), request_timeout),
|
||||||
State#state{timer=TimerRef}.
|
State#state{timer=TimerRef}.
|
||||||
|
|
||||||
cancel_request_timeout(State=#state{timer=TimerRef, opts=Opts}) ->
|
cancel_request_timeout(State=#state{timer=TimerRef}) ->
|
||||||
ok = case TimerRef of
|
ok = case TimerRef of
|
||||||
undefined -> ok;
|
undefined -> ok;
|
||||||
_ -> erlang:cancel_timer(TimerRef, [{async, true}, {info, false}])
|
_ -> erlang:cancel_timer(TimerRef, [{async, true}, {info, false}])
|
||||||
|
@ -779,7 +779,7 @@ commands(State0=#state{socket=Socket, transport=Transport, streams=Streams}, Str
|
||||||
commands(State=#state{socket=Socket, transport=Transport, streams=Streams}, StreamID,
|
commands(State=#state{socket=Socket, transport=Transport, streams=Streams}, StreamID,
|
||||||
[{data, IsFin, Data}|Tail]) ->
|
[{data, IsFin, Data}|Tail]) ->
|
||||||
%% @todo Same as above.
|
%% @todo Same as above.
|
||||||
Headers1 = case lists:keyfind(StreamID, #stream.id, Streams) of
|
case lists:keyfind(StreamID, #stream.id, Streams) of
|
||||||
#stream{version='HTTP/1.1'} ->
|
#stream{version='HTTP/1.1'} ->
|
||||||
Size = iolist_size(Data),
|
Size = iolist_size(Data),
|
||||||
Transport:send(Socket, [integer_to_list(Size, 16), <<"\r\n">>, Data, <<"\r\n">>]);
|
Transport:send(Socket, [integer_to_list(Size, 16), <<"\r\n">>, Data, <<"\r\n">>]);
|
||||||
|
|
|
@ -121,45 +121,13 @@ timeout(State=#state{timeout=Timeout,
|
||||||
-spec loop(Req, #state{}, module(), any())
|
-spec loop(Req, #state{}, module(), any())
|
||||||
-> {ok, Req, cowboy_middleware:env()} | {suspend, module(), atom(), [any()]}
|
-> {ok, Req, cowboy_middleware:env()} | {suspend, module(), atom(), [any()]}
|
||||||
when Req::cowboy_req:req().
|
when Req::cowboy_req:req().
|
||||||
loop(Req, State=#state{buffer_size=NbBytes,
|
loop(Req, State=#state{timeout_ref=TRef}, Handler, HandlerState) ->
|
||||||
max_buffer=Threshold, timeout_ref=TRef,
|
|
||||||
resp_sent=RespSent}, Handler, HandlerState) ->
|
|
||||||
% [Socket, Transport] = cowboy_req:get([socket, transport], Req),
|
|
||||||
% {OK, Closed, Error} = Transport:messages(),
|
|
||||||
receive
|
receive
|
||||||
% {OK, Socket, Data} ->
|
|
||||||
% NbBytes2 = NbBytes + byte_size(Data),
|
|
||||||
% if NbBytes2 > Threshold ->
|
|
||||||
% _ = if RespSent -> ok; true ->
|
|
||||||
% cowboy_req:reply(500, Req)
|
|
||||||
% end,
|
|
||||||
% cowboy_handler:terminate({error, overflow}, Req, HandlerState, Handler),
|
|
||||||
% exit(normal);
|
|
||||||
% true ->
|
|
||||||
% Req2 = cowboy_req:append_buffer(Data, Req),
|
|
||||||
% State2 = timeout(State#state{buffer_size=NbBytes2}),
|
|
||||||
% before_loop(Req2, State2, Handler, HandlerState)
|
|
||||||
% end;
|
|
||||||
% {Closed, Socket} ->
|
|
||||||
% terminate(Req, State, Handler, HandlerState, {error, closed});
|
|
||||||
% {Error, Socket, Reason} ->
|
|
||||||
% terminate(Req, State, Handler, HandlerState, {error, Reason});
|
|
||||||
{timeout, TRef, ?MODULE} ->
|
{timeout, TRef, ?MODULE} ->
|
||||||
after_loop(Req, State, Handler, HandlerState, timeout);
|
after_loop(Req, State, Handler, HandlerState, timeout);
|
||||||
{timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) ->
|
{timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) ->
|
||||||
loop(Req, State, Handler, HandlerState);
|
loop(Req, State, Handler, HandlerState);
|
||||||
Message ->
|
Message ->
|
||||||
%% We set the socket back to {active, false} mode in case
|
|
||||||
%% the handler is going to call recv. We also flush any
|
|
||||||
%% data received after that and put it into the buffer.
|
|
||||||
%% We do not check the size here, if data keeps coming
|
|
||||||
%% we'll error out on the next packet received.
|
|
||||||
% Transport:setopts(Socket, [{active, false}]),
|
|
||||||
% Req2 = receive {OK, Socket, Data} ->
|
|
||||||
% cowboy_req:append_buffer(Data, Req)
|
|
||||||
% after 0 ->
|
|
||||||
% Req
|
|
||||||
% end,
|
|
||||||
call(Req, State, Handler, HandlerState, Message)
|
call(Req, State, Handler, HandlerState, Message)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -747,6 +747,7 @@ do_reply(Status, Headers, Body, Req=#{pid := Pid, streamid := StreamID}) ->
|
||||||
Pid ! {{Pid, StreamID}, {response, Status, response_headers(Headers, Req), Body}},
|
Pid ! {{Pid, StreamID}, {response, Status, response_headers(Headers, Req), Body}},
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec send_body(iodata(), fin | nofin, req()) -> ok.
|
||||||
send_body(Data, IsFin, #{pid := Pid, streamid := StreamID}) ->
|
send_body(Data, IsFin, #{pid := Pid, streamid := StreamID}) ->
|
||||||
Pid ! {{Pid, StreamID}, {data, IsFin, Data}},
|
Pid ! {{Pid, StreamID}, {data, IsFin, Data}},
|
||||||
ok.
|
ok.
|
||||||
|
@ -1017,129 +1018,6 @@ to_list(Req) ->
|
||||||
|
|
||||||
%% Internal.
|
%% Internal.
|
||||||
|
|
||||||
%-spec chunked_response(cowboy:http_status(), cowboy:http_headers(), Req) ->
|
|
||||||
% {normal | hook, Req} when Req::req().
|
|
||||||
%chunked_response(Status, Headers, Req=#http_req{
|
|
||||||
% version=Version, connection=Connection,
|
|
||||||
% resp_state=RespState, resp_headers=RespHeaders})
|
|
||||||
% when RespState =:= waiting; RespState =:= waiting_stream ->
|
|
||||||
% RespConn = response_connection(Headers, Connection),
|
|
||||||
% HTTP11Headers = if
|
|
||||||
% Version =:= 'HTTP/1.0', Connection =:= keepalive ->
|
|
||||||
% [{<<"connection">>, atom_to_connection(Connection)}];
|
|
||||||
% Version =:= 'HTTP/1.0' -> [];
|
|
||||||
% true ->
|
|
||||||
% MaybeTE = if
|
|
||||||
% RespState =:= waiting_stream -> [];
|
|
||||||
% true -> [{<<"transfer-encoding">>, <<"chunked">>}]
|
|
||||||
% end,
|
|
||||||
% if
|
|
||||||
% Connection =:= close ->
|
|
||||||
% [{<<"connection">>, atom_to_connection(Connection)}|MaybeTE];
|
|
||||||
% true ->
|
|
||||||
% MaybeTE
|
|
||||||
% end
|
|
||||||
% end,
|
|
||||||
% RespState2 = if
|
|
||||||
% Version =:= 'HTTP/1.1', RespState =:= 'waiting' -> chunks;
|
|
||||||
% true -> stream
|
|
||||||
% end,
|
|
||||||
% {RespType, Req2} = response(Status, Headers, RespHeaders, [
|
|
||||||
% {<<"date">>, cowboy_clock:rfc1123()},
|
|
||||||
% {<<"server">>, <<"Cowboy">>}
|
|
||||||
% |HTTP11Headers], <<>>, Req),
|
|
||||||
% {RespType, Req2#http_req{connection=RespConn, resp_state=RespState2,
|
|
||||||
% resp_headers=[], resp_body= <<>>}}.
|
|
||||||
%
|
|
||||||
-spec response(cowboy:http_status(), cowboy:http_headers(),
|
|
||||||
cowboy:http_headers(), cowboy:http_headers(), stream | iodata(), Req)
|
|
||||||
-> {normal | hook, Req} when Req::req().
|
|
||||||
response(Status, Headers, RespHeaders, DefaultHeaders, Body, Req=#http_req{
|
|
||||||
socket=Socket, transport=Transport, version=Version,
|
|
||||||
pid=ReqPid, onresponse=OnResponse}) ->
|
|
||||||
FullHeaders = case OnResponse of
|
|
||||||
already_called -> Headers;
|
|
||||||
_ -> response_merge_headers(Headers, RespHeaders, DefaultHeaders)
|
|
||||||
end,
|
|
||||||
Body2 = case Body of stream -> <<>>; _ -> Body end,
|
|
||||||
{Status2, FullHeaders2, Req2} = case OnResponse of
|
|
||||||
already_called -> {Status, FullHeaders, Req};
|
|
||||||
undefined -> {Status, FullHeaders, Req};
|
|
||||||
OnResponse ->
|
|
||||||
case OnResponse(Status, FullHeaders, Body2,
|
|
||||||
%% Don't call 'onresponse' from the hook itself.
|
|
||||||
Req#http_req{resp_headers=[], resp_body= <<>>,
|
|
||||||
onresponse=already_called}) of
|
|
||||||
StHdReq = {_, _, _} ->
|
|
||||||
StHdReq;
|
|
||||||
Req1 ->
|
|
||||||
{Status, FullHeaders, Req1}
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
ReplyType = case Req2#http_req.resp_state of
|
|
||||||
RespState when RespState =:= waiting; RespState =:= waiting_stream ->
|
|
||||||
HTTPVer = atom_to_binary(Version, latin1),
|
|
||||||
StatusLine = << HTTPVer/binary, " ",
|
|
||||||
(status(Status2))/binary, "\r\n" >>,
|
|
||||||
HeaderLines = [[Key, <<": ">>, Value, <<"\r\n">>]
|
|
||||||
|| {Key, Value} <- FullHeaders2],
|
|
||||||
ok = Transport:send(Socket, [StatusLine, HeaderLines, <<"\r\n">>, Body2]),
|
|
||||||
ReqPid ! {?MODULE, resp_sent},
|
|
||||||
normal;
|
|
||||||
_ ->
|
|
||||||
hook
|
|
||||||
end,
|
|
||||||
{ReplyType, Req2}.
|
|
||||||
%
|
|
||||||
%-spec response_connection(cowboy:http_headers(), keepalive | close)
|
|
||||||
% -> keepalive | close.
|
|
||||||
%response_connection([], Connection) ->
|
|
||||||
% Connection;
|
|
||||||
%response_connection([{Name, Value}|Tail], Connection) ->
|
|
||||||
% case Name of
|
|
||||||
% <<"connection">> ->
|
|
||||||
% Tokens = cow_http_hd:parse_connection(Value),
|
|
||||||
% connection_to_atom(Tokens);
|
|
||||||
% _ ->
|
|
||||||
% response_connection(Tail, Connection)
|
|
||||||
% end.
|
|
||||||
%
|
|
||||||
-spec response_merge_headers(cowboy:http_headers(), cowboy:http_headers(),
|
|
||||||
cowboy:http_headers()) -> cowboy:http_headers().
|
|
||||||
response_merge_headers(Headers, RespHeaders, DefaultHeaders) ->
|
|
||||||
Headers2 = [{Key, Value} || {Key, Value} <- Headers],
|
|
||||||
merge_headers(
|
|
||||||
merge_headers(Headers2, RespHeaders),
|
|
||||||
DefaultHeaders).
|
|
||||||
|
|
||||||
-spec merge_headers(cowboy:http_headers(), cowboy:http_headers())
|
|
||||||
-> cowboy:http_headers().
|
|
||||||
|
|
||||||
%% Merge headers by prepending the tuples in the second list to the
|
|
||||||
%% first list. It also handles Set-Cookie properly, which supports
|
|
||||||
%% duplicated entries. Notice that, while the RFC2109 does allow more
|
|
||||||
%% than one cookie to be set per Set-Cookie header, we are following
|
|
||||||
%% the implementation of common web servers and applications which
|
|
||||||
%% return many distinct headers per each Set-Cookie entry to avoid
|
|
||||||
%% issues with clients/browser which may not support it.
|
|
||||||
merge_headers(Headers, []) ->
|
|
||||||
Headers;
|
|
||||||
merge_headers(Headers, [{<<"set-cookie">>, Value}|Tail]) ->
|
|
||||||
merge_headers([{<<"set-cookie">>, Value}|Headers], Tail);
|
|
||||||
merge_headers(Headers, [{Name, Value}|Tail]) ->
|
|
||||||
Headers2 = case lists:keymember(Name, 1, Headers) of
|
|
||||||
true -> Headers;
|
|
||||||
false -> [{Name, Value}|Headers]
|
|
||||||
end,
|
|
||||||
merge_headers(Headers2, Tail).
|
|
||||||
%
|
|
||||||
%-spec atom_to_connection(keepalive) -> <<_:80>>;
|
|
||||||
% (close) -> <<_:40>>.
|
|
||||||
%atom_to_connection(keepalive) ->
|
|
||||||
% <<"keep-alive">>;
|
|
||||||
%atom_to_connection(close) ->
|
|
||||||
% <<"close">>.
|
|
||||||
|
|
||||||
%% We don't match on "keep-alive" since it is the default value.
|
%% We don't match on "keep-alive" since it is the default value.
|
||||||
-spec connection_to_atom([binary()]) -> keepalive | close.
|
-spec connection_to_atom([binary()]) -> keepalive | close.
|
||||||
connection_to_atom([]) ->
|
connection_to_atom([]) ->
|
||||||
|
|
|
@ -101,9 +101,13 @@ websocket_upgrade(State, Req) ->
|
||||||
-spec websocket_extensions(#state{}, Req)
|
-spec websocket_extensions(#state{}, Req)
|
||||||
-> {ok, #state{}, Req} when Req::cowboy_req:req().
|
-> {ok, #state{}, Req} when Req::cowboy_req:req().
|
||||||
websocket_extensions(State, Req) ->
|
websocket_extensions(State, Req) ->
|
||||||
%% @todo Proper options for this.
|
%% @todo We want different options for this. For example
|
||||||
% [Compress] = cowboy_req:get([resp_compress], Req),
|
%% * compress everything auto
|
||||||
Compress = false,
|
%% * compress only text auto
|
||||||
|
%% * compress only binary auto
|
||||||
|
%% * compress nothing auto (but still enabled it)
|
||||||
|
%% * disable compression
|
||||||
|
Compress = maps:get(websocket_compress, Req, false),
|
||||||
Req2 = Req#{websocket_compress => false},
|
Req2 = Req#{websocket_compress => false},
|
||||||
case {Compress, cowboy_req:parse_header(<<"sec-websocket-extensions">>, Req2)} of
|
case {Compress, cowboy_req:parse_header(<<"sec-websocket-extensions">>, Req2)} of
|
||||||
{true, Extensions} when Extensions =/= undefined ->
|
{true, Extensions} when Extensions =/= undefined ->
|
||||||
|
@ -144,7 +148,7 @@ websocket_extensions(State, Req, [_|Tail], RespHeader) ->
|
||||||
-spec websocket_handshake(#state{}, Req, any(), Env)
|
-spec websocket_handshake(#state{}, Req, any(), Env)
|
||||||
-> {ok, Req, Env}
|
-> {ok, Req, Env}
|
||||||
when Req::cowboy_req:req(), Env::cowboy_middleware:env().
|
when Req::cowboy_req:req(), Env::cowboy_middleware:env().
|
||||||
websocket_handshake(State=#state{transport=Transport, key=Key},
|
websocket_handshake(State=#state{key=Key},
|
||||||
Req=#{pid := Pid, streamid := StreamID}, HandlerState, Env) ->
|
Req=#{pid := Pid, streamid := StreamID}, HandlerState, Env) ->
|
||||||
Challenge = base64:encode(crypto:hash(sha,
|
Challenge = base64:encode(crypto:hash(sha,
|
||||||
<< Key/binary, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" >>)),
|
<< Key/binary, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" >>)),
|
||||||
|
@ -159,7 +163,11 @@ websocket_handshake(State=#state{transport=Transport, key=Key},
|
||||||
|
|
||||||
%% Connection process.
|
%% Connection process.
|
||||||
|
|
||||||
takeover(Parent, Ref, Socket, Transport, Opts, Buffer, {Req0, State=#state{handler=Handler}, HandlerState0}) ->
|
%% @todo Keep parent and handle system messages.
|
||||||
|
-spec takeover(pid(), ranch:ref(), inet:socket(), module(), any(), binary(),
|
||||||
|
{cowboy_req:req(), #state{}, any()}) -> ok.
|
||||||
|
takeover(_Parent, Ref, Socket, Transport, _Opts, Buffer,
|
||||||
|
{Req0, State=#state{handler=Handler}, HandlerState0}) ->
|
||||||
ranch:remove_connection(Ref),
|
ranch:remove_connection(Ref),
|
||||||
%% @todo Remove Req from Websocket callbacks.
|
%% @todo Remove Req from Websocket callbacks.
|
||||||
%% @todo Allow sending a reply from websocket_init.
|
%% @todo Allow sending a reply from websocket_init.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue