diff options
-rw-r--r-- | src/gun_http.erl | 20 | ||||
-rw-r--r-- | src/gun_spdy.erl | 14 | ||||
-rw-r--r-- | test/spdy_SUITE.erl | 17 |
3 files changed, 34 insertions, 17 deletions
diff --git a/src/gun_http.erl b/src/gun_http.erl index 67c235f..1090e6b 100644 --- a/src/gun_http.erl +++ b/src/gun_http.erl @@ -241,11 +241,11 @@ request(State=#http_state{socket=Socket, transport=Transport, version=Version, new_stream(State#http_state{connection=Conn}, StreamRef). %% We are expecting a new stream. -data(State=#http_state{out=head}, _, _, _) -> - error_stream_closed(State); +data(State=#http_state{out=head}, StreamRef, _, _) -> + error_stream_closed(State, StreamRef); %% There are no active streams. -data(State=#http_state{streams=[]}, _, _, _) -> - error_stream_not_found(State); +data(State=#http_state{streams=[]}, StreamRef, _, _) -> + error_stream_not_found(State, StreamRef); %% We can only send data on the last created stream. data(State=#http_state{socket=Socket, transport=Transport, version=Version, out=Out, streams=Streams}, StreamRef, IsFin, Data) -> @@ -280,7 +280,7 @@ data(State=#http_state{socket=Socket, transport=Transport, version=Version, State end; {_, _} -> - error_stream_not_found(State) + error_stream_not_found(State, StreamRef) end. %% We can't cancel anything, we can just stop forwarding messages to the owner. @@ -289,7 +289,7 @@ cancel(State, StreamRef) -> true -> cancel_stream(State, StreamRef); false -> - error_stream_not_found(State) + error_stream_not_found(State, StreamRef) end. %% HTTP does not provide any way to figure out what streams are unprocessed. @@ -300,13 +300,13 @@ down(#http_state{streams=Streams}) -> end || {Ref, _} <- Streams], {KilledStreams, []}. -error_stream_closed(State=#http_state{owner=Owner}) -> - Owner ! {gun_error, self(), {badstate, +error_stream_closed(State=#http_state{owner=Owner}, StreamRef) -> + Owner ! {gun_error, self(), StreamRef, {badstate, "The stream has already been closed."}}, State. -error_stream_not_found(State=#http_state{owner=Owner}) -> - Owner ! {gun_error, self(), {badstate, +error_stream_not_found(State=#http_state{owner=Owner}, StreamRef) -> + Owner ! {gun_error, self(), StreamRef, {badstate, "The stream cannot be found."}}, State. diff --git a/src/gun_spdy.erl b/src/gun_spdy.erl index 9a7d493..ef5d0cb 100644 --- a/src/gun_spdy.erl +++ b/src/gun_spdy.erl @@ -246,7 +246,7 @@ data(State=#spdy_state{socket=Socket, transport=Transport}, StreamRef, IsFin, Data) -> case get_stream_by_ref(StreamRef, State) of #stream{out=false} -> - error_stream_closed(State); + error_stream_closed(State, StreamRef); S = #stream{} -> IsFin2 = IsFin =:= fin, Transport:send(Socket, cow_spdy:data(S#stream.id, IsFin2, Data)), @@ -256,7 +256,7 @@ data(State=#spdy_state{socket=Socket, transport=Transport}, State end; false -> - error_stream_not_found(State) + error_stream_not_found(State, StreamRef) end. cancel(State=#spdy_state{socket=Socket, transport=Transport}, @@ -266,7 +266,7 @@ cancel(State=#spdy_state{socket=Socket, transport=Transport}, Transport:send(Socket, cow_spdy:rst_stream(StreamID, cancel)), delete_stream(StreamID, State); false -> - error_stream_not_found(State) + error_stream_not_found(State, StreamRef) end. %% @todo Add unprocessed streams when GOAWAY handling is done. @@ -274,13 +274,13 @@ down(#spdy_state{streams=Streams}) -> KilledStreams = [Ref || #stream{ref=Ref} <- Streams], {KilledStreams, []}. -error_stream_closed(State=#spdy_state{owner=Owner}) -> - Owner ! {gun_error, self(), {badstate, +error_stream_closed(State=#spdy_state{owner=Owner}, StreamRef) -> + Owner ! {gun_error, self(), StreamRef, {badstate, "The stream has already been closed."}}, State. -error_stream_not_found(State=#spdy_state{owner=Owner}) -> - Owner ! {gun_error, self(), {badstate, +error_stream_not_found(State=#spdy_state{owner=Owner}, StreamRef) -> + Owner ! {gun_error, self(), StreamRef, {badstate, "The stream cannot be found."}}, State. diff --git a/test/spdy_SUITE.erl b/test/spdy_SUITE.erl index 645d13c..c1ae1ba 100644 --- a/test/spdy_SUITE.erl +++ b/test/spdy_SUITE.erl @@ -186,3 +186,20 @@ stream_duplicate_streamid(_) -> ]), wait(), [_, {goaway, 1, protocol_error}] = spdy_server:stop(ServerPid). + +no_sending_frames_after_flag_fin(_) -> + doc("Do not send frames after sending FLAG_FIN. (spdy-protocol-draft3-1 2.3.6)"), + {ok, ServerPid, Port} = spdy_server:start_link(), + {ok, ConnPid} = gun:open("localhost", Port, #{transport=>ssl}), + {ok, spdy} = gun:await_up(ConnPid), + %% Send a POST frame with no content header so that Gun sets FLAG_FIN, + %% then try sending data. Gun should reject this second call. + StreamRef = gun:post(ConnPid, "/", []), + gun:data(ConnPid, StreamRef, false, <<"Hello world!">>), + receive {gun_error, ConnPid, StreamRef, _} -> + ok + after 5000 -> + exit(timeout) + end, + wait(), + [{syn_stream, _, _, _, _, _, _, _, _, _, _, _}] = spdy_server:stop(ServerPid). |