From 0193538dbafd275f543bfbce1065358ea6554641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Sun, 6 Mar 2016 18:09:43 +0100 Subject: Fix warnings --- src/cowboy_http.erl | 6 +-- src/cowboy_loop.erl | 34 +------------ src/cowboy_req.erl | 124 +---------------------------------------------- src/cowboy_websocket.erl | 18 +++++-- 4 files changed, 18 insertions(+), 164 deletions(-) (limited to 'src') diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index 3ec3c17..f9ee5ac 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -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.'}) end. -set_request_timeout(State0=#state{timer=TimerRef0, opts=Opts}) -> +set_request_timeout(State0=#state{opts=Opts}) -> State = cancel_request_timeout(State0), Timeout = maps:get(request_timeout, Opts, 5000), TimerRef = erlang:start_timer(Timeout, self(), request_timeout), State#state{timer=TimerRef}. -cancel_request_timeout(State=#state{timer=TimerRef, opts=Opts}) -> +cancel_request_timeout(State=#state{timer=TimerRef}) -> ok = case TimerRef of undefined -> ok; _ -> 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, [{data, IsFin, Data}|Tail]) -> %% @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'} -> Size = iolist_size(Data), Transport:send(Socket, [integer_to_list(Size, 16), <<"\r\n">>, Data, <<"\r\n">>]); diff --git a/src/cowboy_loop.erl b/src/cowboy_loop.erl index e162417..dc07e13 100644 --- a/src/cowboy_loop.erl +++ b/src/cowboy_loop.erl @@ -121,45 +121,13 @@ timeout(State=#state{timeout=Timeout, -spec loop(Req, #state{}, module(), any()) -> {ok, Req, cowboy_middleware:env()} | {suspend, module(), atom(), [any()]} when Req::cowboy_req:req(). -loop(Req, State=#state{buffer_size=NbBytes, - max_buffer=Threshold, timeout_ref=TRef, - resp_sent=RespSent}, Handler, HandlerState) -> -% [Socket, Transport] = cowboy_req:get([socket, transport], Req), -% {OK, Closed, Error} = Transport:messages(), +loop(Req, State=#state{timeout_ref=TRef}, Handler, HandlerState) -> 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} -> after_loop(Req, State, Handler, HandlerState, timeout); {timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) -> loop(Req, State, Handler, HandlerState); 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) end. diff --git a/src/cowboy_req.erl b/src/cowboy_req.erl index b01a70c..2ea0dde 100644 --- a/src/cowboy_req.erl +++ b/src/cowboy_req.erl @@ -747,6 +747,7 @@ do_reply(Status, Headers, Body, Req=#{pid := Pid, streamid := StreamID}) -> Pid ! {{Pid, StreamID}, {response, Status, response_headers(Headers, Req), Body}}, ok. +-spec send_body(iodata(), fin | nofin, req()) -> ok. send_body(Data, IsFin, #{pid := Pid, streamid := StreamID}) -> Pid ! {{Pid, StreamID}, {data, IsFin, Data}}, ok. @@ -1017,129 +1018,6 @@ to_list(Req) -> %% 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. -spec connection_to_atom([binary()]) -> keepalive | close. connection_to_atom([]) -> diff --git a/src/cowboy_websocket.erl b/src/cowboy_websocket.erl index 9a2862e..757f52c 100644 --- a/src/cowboy_websocket.erl +++ b/src/cowboy_websocket.erl @@ -101,9 +101,13 @@ websocket_upgrade(State, Req) -> -spec websocket_extensions(#state{}, Req) -> {ok, #state{}, Req} when Req::cowboy_req:req(). websocket_extensions(State, Req) -> - %% @todo Proper options for this. -% [Compress] = cowboy_req:get([resp_compress], Req), - Compress = false, + %% @todo We want different options for this. For example + %% * compress everything auto + %% * 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}, case {Compress, cowboy_req:parse_header(<<"sec-websocket-extensions">>, Req2)} of {true, Extensions} when Extensions =/= undefined -> @@ -144,7 +148,7 @@ websocket_extensions(State, Req, [_|Tail], RespHeader) -> -spec websocket_handshake(#state{}, Req, any(), Env) -> {ok, Req, 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) -> Challenge = base64:encode(crypto:hash(sha, << Key/binary, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" >>)), @@ -159,7 +163,11 @@ websocket_handshake(State=#state{transport=Transport, key=Key}, %% 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), %% @todo Remove Req from Websocket callbacks. %% @todo Allow sending a reply from websocket_init. -- cgit v1.2.3