mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-15 12:40:25 +00:00
Fix cowboy_spdy parse frame
This commit is contained in:
parent
73f65d5a75
commit
fec3355192
1 changed files with 20 additions and 16 deletions
|
@ -106,20 +106,24 @@ init(Parent, Ref, Socket, Transport, Opts) ->
|
||||||
middlewares=Middlewares, env=Env, onrequest=OnRequest,
|
middlewares=Middlewares, env=Env, onrequest=OnRequest,
|
||||||
onresponse=OnResponse, peer=Peer, zdef=Zdef, zinf=Zinf}).
|
onresponse=OnResponse, peer=Peer, zdef=Zdef, zinf=Zinf}).
|
||||||
|
|
||||||
|
parse_frame(State=#state{zinf=Zinf}, Data) ->
|
||||||
|
case cow_spdy:split(Data) of
|
||||||
|
{true, Frame, Rest} ->
|
||||||
|
P = cow_spdy:parse(Frame, Zinf),
|
||||||
|
State2 = handle_frame(State#state{buffer = Rest}, P),
|
||||||
|
parse_frame(State2, Rest);
|
||||||
|
false ->
|
||||||
|
loop(State#state{buffer=Data})
|
||||||
|
end.
|
||||||
|
|
||||||
loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
|
loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
|
||||||
buffer=Buffer, zinf=Zinf, children=Children}) ->
|
buffer=Buffer, children=Children}) ->
|
||||||
{OK, Closed, Error} = Transport:messages(),
|
{OK, Closed, Error} = Transport:messages(),
|
||||||
Transport:setopts(Socket, [{active, once}]),
|
Transport:setopts(Socket, [{active, once}]),
|
||||||
receive
|
receive
|
||||||
{OK, Socket, Data} ->
|
{OK, Socket, Data} ->
|
||||||
Data2 = << Buffer/binary, Data/binary >>,
|
Data2 = << Buffer/binary, Data/binary >>,
|
||||||
case cow_spdy:split(Data2) of
|
parse_frame(State, Data2);
|
||||||
{true, Frame, Rest} ->
|
|
||||||
P = cow_spdy:parse(Frame, Zinf),
|
|
||||||
handle_frame(State#state{buffer=Rest}, P);
|
|
||||||
false ->
|
|
||||||
loop(State#state{buffer=Data2})
|
|
||||||
end;
|
|
||||||
{Closed, Socket} ->
|
{Closed, Socket} ->
|
||||||
terminate(State);
|
terminate(State);
|
||||||
{Error, Socket, _Reason} ->
|
{Error, Socket, _Reason} ->
|
||||||
|
@ -239,12 +243,12 @@ system_code_change(Misc, _, _, _) ->
|
||||||
handle_frame(State, {syn_stream, StreamID, _, _, true,
|
handle_frame(State, {syn_stream, StreamID, _, _, true,
|
||||||
_, _, _, _, _, _, _}) ->
|
_, _, _, _, _, _, _}) ->
|
||||||
rst_stream(State, StreamID, protocol_error),
|
rst_stream(State, StreamID, protocol_error),
|
||||||
loop(State);
|
State;
|
||||||
%% We do not support Associated-To-Stream-ID.
|
%% We do not support Associated-To-Stream-ID.
|
||||||
handle_frame(State, {syn_stream, StreamID, AssocToStreamID,
|
handle_frame(State, {syn_stream, StreamID, AssocToStreamID,
|
||||||
_, _, _, _, _, _, _, _, _}) when AssocToStreamID =/= 0 ->
|
_, _, _, _, _, _, _, _, _}) when AssocToStreamID =/= 0 ->
|
||||||
rst_stream(State, StreamID, internal_error),
|
rst_stream(State, StreamID, internal_error),
|
||||||
loop(State);
|
State;
|
||||||
%% SYN_STREAM.
|
%% SYN_STREAM.
|
||||||
%%
|
%%
|
||||||
%% Erlang does not allow us to control the priority of processes
|
%% Erlang does not allow us to control the priority of processes
|
||||||
|
@ -257,22 +261,22 @@ handle_frame(State=#state{middlewares=Middlewares, env=Env,
|
||||||
{self(), StreamID}, Peer, OnRequest, OnResponse,
|
{self(), StreamID}, Peer, OnRequest, OnResponse,
|
||||||
Env, Middlewares, Method, Host, Path, Version, Headers
|
Env, Middlewares, Method, Host, Path, Version, Headers
|
||||||
]),
|
]),
|
||||||
loop(new_child(State, StreamID, Pid, IsFin));
|
new_child(State, StreamID, Pid, IsFin);
|
||||||
%% RST_STREAM.
|
%% RST_STREAM.
|
||||||
handle_frame(State, {rst_stream, StreamID, Status}) ->
|
handle_frame(State, {rst_stream, StreamID, Status}) ->
|
||||||
error_logger:error_msg("Received RST_STREAM frame ~p ~p",
|
error_logger:error_msg("Received RST_STREAM frame ~p ~p",
|
||||||
[StreamID, Status]),
|
[StreamID, Status]),
|
||||||
%% @todo Stop StreamID.
|
%% @todo Stop StreamID.
|
||||||
loop(State);
|
State;
|
||||||
%% PING initiated by the server; ignore, we don't send any.
|
%% PING initiated by the server; ignore, we don't send any.
|
||||||
handle_frame(State, {ping, PingID}) when PingID rem 2 =:= 0 ->
|
handle_frame(State, {ping, PingID}) when PingID rem 2 =:= 0 ->
|
||||||
error_logger:error_msg("Ignored PING control frame: ~p~n", [PingID]),
|
error_logger:error_msg("Ignored PING control frame: ~p~n", [PingID]),
|
||||||
loop(State);
|
State;
|
||||||
%% PING initiated by the client; send it back.
|
%% PING initiated by the client; send it back.
|
||||||
handle_frame(State=#state{socket=Socket, transport=Transport},
|
handle_frame(State=#state{socket=Socket, transport=Transport},
|
||||||
{ping, PingID}) ->
|
{ping, PingID}) ->
|
||||||
Transport:send(Socket, cow_spdy:ping(PingID)),
|
Transport:send(Socket, cow_spdy:ping(PingID)),
|
||||||
loop(State);
|
State;
|
||||||
%% Data received for a stream.
|
%% Data received for a stream.
|
||||||
handle_frame(State, {data, StreamID, IsFin, Data}) ->
|
handle_frame(State, {data, StreamID, IsFin, Data}) ->
|
||||||
Child = #child{input=nofin, in_buffer=Buffer, is_recv=IsRecv}
|
Child = #child{input=nofin, in_buffer=Buffer, is_recv=IsRecv}
|
||||||
|
@ -296,7 +300,7 @@ handle_frame(State, {data, StreamID, IsFin, Data}) ->
|
||||||
_ ->
|
_ ->
|
||||||
Child#child{input=IsFin2, in_buffer=Data2}
|
Child#child{input=IsFin2, in_buffer=Data2}
|
||||||
end,
|
end,
|
||||||
loop(replace_child(Child2, State));
|
replace_child(Child2, State);
|
||||||
%% General error, can't recover.
|
%% General error, can't recover.
|
||||||
handle_frame(State, {error, badprotocol}) ->
|
handle_frame(State, {error, badprotocol}) ->
|
||||||
goaway(State, protocol_error),
|
goaway(State, protocol_error),
|
||||||
|
@ -304,7 +308,7 @@ handle_frame(State, {error, badprotocol}) ->
|
||||||
%% Ignore all other frames for now.
|
%% Ignore all other frames for now.
|
||||||
handle_frame(State, Frame) ->
|
handle_frame(State, Frame) ->
|
||||||
error_logger:error_msg("Ignored frame ~p", [Frame]),
|
error_logger:error_msg("Ignored frame ~p", [Frame]),
|
||||||
loop(State).
|
State.
|
||||||
|
|
||||||
cancel_recv_timeout(StreamID, TRef) ->
|
cancel_recv_timeout(StreamID, TRef) ->
|
||||||
_ = erlang:cancel_timer(TRef),
|
_ = erlang:cancel_timer(TRef),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue