3636]).
3737
3838-define (FILE_CHUNK_LENGTH , 16#80000 ). % 512KB
39+ -define (DEFAULT_IDLE_TIMEOUT , 60000 ).
3940
4041% % @doc Returns server header.
4142-spec server_header () -> Result when
@@ -116,8 +117,6 @@ send_response_code(Code, Parts, Context) ->
116117 Parts :: cowmachine_req :parts (),
117118 Context :: cowmachine_req :context (),
118119 Result :: cowmachine_req :context ().
119- % send_response_bodyfun(undefined, Code, Parts, Context) ->
120- % send_response_bodyfun(<<>>, Code, Parts, Context);
121120send_response_bodyfun ({device , IO }, Code , Parts , Context ) ->
122121 Length = iodevice_size (IO ),
123122 send_response_bodyfun ({device , Length , IO }, Code , Parts , Context );
@@ -191,11 +190,14 @@ send_response_bodyfun(Body, Code, all, Context) ->
191190 Req1 = cowboy_req :reply (Code , Headers , Body , Req ),
192191 cowmachine_req :set_req (Req1 , Context );
193192send_response_bodyfun (Body , Code , Parts , Context ) ->
193+ set_idle_timeout (infinity , Context ),
194194 Headers = response_headers (Context ),
195195 Req = cowmachine_req :req (Context ),
196196 Req1 = cowboy_req :stream_reply (Code , Headers , Req ),
197197 Context1 = cowmachine_req :set_req (Req1 , Context ),
198- send_parts (Context1 , Parts , iolist_to_binary (Body )).
198+ Context2 = send_parts (Context1 , Parts , iolist_to_binary (Body )),
199+ set_idle_timeout (? DEFAULT_IDLE_TIMEOUT , Context2 ),
200+ Context2 .
199201
200202-spec start_response_stream (Code , Length , InitialStream , Parts , Context ) -> Result when
201203 Code :: integer (),
@@ -205,6 +207,7 @@ send_response_bodyfun(Body, Code, Parts, Context) ->
205207 Context :: cowmachine_req :context (),
206208 Result :: cowmachine_req :context ().
207209start_response_stream (Code , Length , InitialStream , Parts , Context ) ->
210+ set_idle_timeout (infinity , Context ),
208211 {Code1 , Context1 , Parts1 } = case is_streaming_range (InitialStream ) of
209212 false when Parts =/= all ->
210213 % Drop range response header
@@ -227,7 +230,9 @@ start_response_stream(Code, Length, InitialStream, Parts, Context) ->
227230 InitialFun ->
228231 stream_initial_fun (InitialFun , Parts1 )
229232 end ,
230- send_stream_body (FirstHunk , Context2 ).
233+ Context3 = send_stream_body (FirstHunk , Context2 ),
234+ set_idle_timeout (? DEFAULT_IDLE_TIMEOUT , Context3 ),
235+ Context3 .
231236
232237-spec stream_initial_fun (Fun , Parts ) -> Result when
233238 Fun :: function (),
@@ -240,6 +245,17 @@ stream_initial_fun(F, _Parts) when is_function(F) ->
240245stream_initial_fun (done , _Parts ) ->
241246 done .
242247
248+ % % @doc Set the idle timeout for the connection. This will reset the idle timeout
249+ % % timer for HTTP/1.x connections. During streaming we do not want a timeout.
250+ % % The default is 60 seconds.
251+ -spec set_idle_timeout (Timeout , Context ) -> ok when
252+ Timeout :: pos_integer () | infinity ,
253+ Context :: cowmachine_req :context ().
254+ set_idle_timeout (Timeout , Context ) ->
255+ Req = cowmachine_req :req (Context ),
256+ cowboy_req :cast ({set_options , #{
257+ idle_timeout => Timeout
258+ }}, Req ).
243259
244260% % @doc Check if we support ranges on the data stream (body or function)
245261-spec is_streaming_range (Stream ) -> Result when
0 commit comments