aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cowboy_handler.erl13
-rw-r--r--test/http_SUITE.erl3
-rw-r--r--test/http_handler_loop_recv.erl18
3 files changed, 33 insertions, 1 deletions
diff --git a/src/cowboy_handler.erl b/src/cowboy_handler.erl
index 7aaf9ae..7d00524 100644
--- a/src/cowboy_handler.erl
+++ b/src/cowboy_handler.erl
@@ -214,7 +214,18 @@ handler_loop(Req, State=#state{loop_buffer_size=NbBytes,
{timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) ->
handler_before_loop(Req, State, Handler, HandlerState);
Message ->
- handler_call(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,
+ handler_call(Req2, State, Handler, HandlerState, Message)
end.
-spec handler_call(Req, #state{}, module(), any(), any())
diff --git a/test/http_SUITE.erl b/test/http_SUITE.erl
index 14bba9c..34a7be1 100644
--- a/test/http_SUITE.erl
+++ b/test/http_SUITE.erl
@@ -367,6 +367,7 @@ init_dispatch(Config) ->
{"/patch", rest_patch_resource, []},
{"/resetags", rest_resource_etags, []},
{"/rest_expires", rest_expires, []},
+ {"/loop_recv", http_handler_loop_recv, []},
{"/loop_timeout", http_handler_loop_timeout, []},
{"/", http_handler, []}
]}
@@ -466,6 +467,8 @@ The document has moved
"Set-Cookie: ", HugeCookie, "\r\n\r\n"]},
{200, "\r\n\r\n\r\n\r\n\r\nGET / HTTP/1.1\r\nHost: localhost\r\n\r\n"},
{200, "GET http://proxy/ HTTP/1.1\r\nHost: localhost\r\n\r\n"},
+ {200, <<"POST /loop_recv HTTP/1.1\r\nHost: localhost\r\n"
+ "Content-Length: 100000\r\n\r\n", 0:100000/unit:8 >>},
{400, "\n"},
{400, "Garbage\r\n\r\n"},
{400, "\r\n\r\n\r\n\r\n\r\n\r\n"},
diff --git a/test/http_handler_loop_recv.erl b/test/http_handler_loop_recv.erl
new file mode 100644
index 0000000..4d0a321
--- /dev/null
+++ b/test/http_handler_loop_recv.erl
@@ -0,0 +1,18 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+-module(http_handler_loop_recv).
+-behaviour(cowboy_loop_handler).
+-export([init/3, info/3, terminate/3]).
+
+init({_, http}, Req, _) ->
+ self() ! recv_timeout,
+ {loop, Req, undefined, 500, hibernate}.
+
+info(recv_timeout, Req, State) ->
+ {ok, Body, Req1} = cowboy_req:body(Req),
+ 100000 = byte_size(Body),
+ {ok, Req2} = cowboy_req:reply(200, Req1),
+ {ok, Req2, State}.
+
+terminate({normal, shutdown}, _, _) ->
+ ok.