2828
2929module AP_MODULE_DECLARE_DATA reqtimeout_module ;
3030
31+ #define UNSET -1
32+ #define MRT_DEFAULT_HEADER_TIMEOUT 20
33+ #define MRT_DEFAULT_HEADER_MAX_TIMEOUT 40
34+ #define MRT_DEFAULT_HEADER_MIN_RATE 500
35+ #define MRT_DEFAULT_BODY_TIMEOUT 20
36+ #define MRT_DEFAULT_BODY_MAX_TIMEOUT 0
37+ #define MRT_DEFAULT_BODY_MIN_RATE 500
38+
3139typedef struct
3240{
3341 int header_timeout ; /* timeout for reading the req hdrs in secs */
@@ -56,6 +64,8 @@ typedef struct
5664} reqtimeout_con_cfg ;
5765
5866static const char * const reqtimeout_filter_name = "reqtimeout" ;
67+ static int default_header_rate_factor ;
68+ static int default_body_rate_factor ;
5969
6070static void extend_timeout (reqtimeout_con_cfg * ccfg , apr_bucket_brigade * bb )
6171{
@@ -161,7 +171,7 @@ static apr_status_t reqtimeout_filter(ap_filter_t *f,
161171 apr_time_t time_left ;
162172 apr_time_t now ;
163173 apr_status_t rv ;
164- apr_interval_time_t saved_sock_timeout = -1 ;
174+ apr_interval_time_t saved_sock_timeout = UNSET ;
165175 reqtimeout_con_cfg * ccfg = f -> ctx ;
166176
167177 if (ccfg -> in_keep_alive ) {
@@ -325,17 +335,25 @@ static int reqtimeout_init(conn_rec *c)
325335 cfg = ap_get_module_config (c -> base_server -> module_config ,
326336 & reqtimeout_module );
327337 AP_DEBUG_ASSERT (cfg != NULL );
328- if (cfg -> header_timeout <= 0 && cfg -> body_timeout < = 0 ) {
329- /* not configured for this vhost */
338+ if (cfg -> header_timeout == 0 && cfg -> body_timeout = = 0 ) {
339+ /* disabled for this vhost */
330340 return DECLINED ;
331341 }
332342
333343 ccfg = apr_pcalloc (c -> pool , sizeof (reqtimeout_con_cfg ));
334- ccfg -> new_timeout = cfg -> header_timeout ;
335- ccfg -> new_max_timeout = cfg -> header_max_timeout ;
336344 ccfg -> type = "header" ;
337- ccfg -> min_rate = cfg -> header_min_rate ;
338- ccfg -> rate_factor = cfg -> header_rate_factor ;
345+ if (cfg -> header_timeout != UNSET ) {
346+ ccfg -> new_timeout = cfg -> header_timeout ;
347+ ccfg -> new_max_timeout = cfg -> header_max_timeout ;
348+ ccfg -> min_rate = cfg -> header_min_rate ;
349+ ccfg -> rate_factor = cfg -> header_rate_factor ;
350+ }
351+ else {
352+ ccfg -> new_timeout = MRT_DEFAULT_HEADER_TIMEOUT ;
353+ ccfg -> new_max_timeout = MRT_DEFAULT_HEADER_MAX_TIMEOUT ;
354+ ccfg -> min_rate = MRT_DEFAULT_HEADER_MIN_RATE ;
355+ ccfg -> rate_factor = default_header_rate_factor ;
356+ }
339357 ap_set_module_config (c -> conn_config , & reqtimeout_module , ccfg );
340358
341359 ap_add_input_filter ("reqtimeout" , ccfg , NULL , c );
@@ -349,25 +367,29 @@ static int reqtimeout_after_headers(request_rec *r)
349367 reqtimeout_con_cfg * ccfg =
350368 ap_get_module_config (r -> connection -> conn_config , & reqtimeout_module );
351369
352- if (ccfg == NULL ) {
353- /* not configured for this connection */
370+ if (ccfg == NULL || r -> method_number == M_CONNECT ) {
371+ /* either disabled for this connection or a CONNECT request */
354372 return OK ;
355373 }
356-
357374 cfg = ap_get_module_config (r -> connection -> base_server -> module_config ,
358375 & reqtimeout_module );
359376 AP_DEBUG_ASSERT (cfg != NULL );
360377
361378 ccfg -> timeout_at = 0 ;
362379 ccfg -> max_timeout_at = 0 ;
363- if (r -> method_number != M_CONNECT ) {
364- ccfg -> new_timeout = cfg -> body_timeout ;
380+ ccfg -> type = "body" ;
381+ if (cfg -> body_timeout != UNSET ) {
382+ ccfg -> new_timeout = cfg -> body_timeout ;
365383 ccfg -> new_max_timeout = cfg -> body_max_timeout ;
366- ccfg -> min_rate = cfg -> body_min_rate ;
367- ccfg -> rate_factor = cfg -> body_rate_factor ;
368- ccfg -> type = "body" ;
384+ ccfg -> min_rate = cfg -> body_min_rate ;
385+ ccfg -> rate_factor = cfg -> body_rate_factor ;
386+ }
387+ else {
388+ ccfg -> new_timeout = MRT_DEFAULT_BODY_TIMEOUT ;
389+ ccfg -> new_max_timeout = MRT_DEFAULT_BODY_MAX_TIMEOUT ;
390+ ccfg -> min_rate = MRT_DEFAULT_BODY_MIN_RATE ;
391+ ccfg -> rate_factor = default_body_rate_factor ;
369392 }
370-
371393 return OK ;
372394}
373395
@@ -389,12 +411,19 @@ static int reqtimeout_after_body(request_rec *r)
389411 ccfg -> timeout_at = 0 ;
390412 ccfg -> max_timeout_at = 0 ;
391413 ccfg -> in_keep_alive = 1 ;
392- ccfg -> new_timeout = cfg -> header_timeout ;
393- ccfg -> new_max_timeout = cfg -> header_max_timeout ;
394- ccfg -> min_rate = cfg -> header_min_rate ;
395- ccfg -> rate_factor = cfg -> header_rate_factor ;
396-
397414 ccfg -> type = "header" ;
415+ if (ccfg -> new_timeout != UNSET ) {
416+ ccfg -> new_timeout = cfg -> header_timeout ;
417+ ccfg -> new_max_timeout = cfg -> header_max_timeout ;
418+ ccfg -> min_rate = cfg -> header_min_rate ;
419+ ccfg -> rate_factor = cfg -> header_rate_factor ;
420+ }
421+ else {
422+ ccfg -> new_timeout = MRT_DEFAULT_HEADER_TIMEOUT ;
423+ ccfg -> new_max_timeout = MRT_DEFAULT_HEADER_MAX_TIMEOUT ;
424+ ccfg -> min_rate = MRT_DEFAULT_HEADER_MIN_RATE ;
425+ ccfg -> rate_factor = default_header_rate_factor ;
426+ }
398427
399428 return OK ;
400429}
@@ -403,17 +432,17 @@ static void *reqtimeout_create_srv_config(apr_pool_t *p, server_rec *s)
403432{
404433 reqtimeout_srv_cfg * cfg = apr_pcalloc (p , sizeof (reqtimeout_srv_cfg ));
405434
406- cfg -> header_timeout = -1 ;
407- cfg -> header_max_timeout = -1 ;
408- cfg -> header_min_rate = -1 ;
409- cfg -> body_timeout = -1 ;
410- cfg -> body_max_timeout = -1 ;
411- cfg -> body_min_rate = -1 ;
435+ cfg -> header_timeout = UNSET ;
436+ cfg -> header_max_timeout = UNSET ;
437+ cfg -> header_min_rate = UNSET ;
438+ cfg -> body_timeout = UNSET ;
439+ cfg -> body_max_timeout = UNSET ;
440+ cfg -> body_min_rate = UNSET ;
412441
413442 return cfg ;
414443}
415444
416- #define MERGE_INT (cfg , b , a , val ) cfg->val = (a->val == -1 ) ? b->val : a->val;
445+ #define MERGE_INT (cfg , b , a , val ) cfg->val = (a->val == UNSET ) ? b->val : a->val;
417446static void * reqtimeout_merge_srv_config (apr_pool_t * p , void * base_ , void * add_ )
418447{
419448 reqtimeout_srv_cfg * base = base_ ;
@@ -427,11 +456,10 @@ static void *reqtimeout_merge_srv_config(apr_pool_t *p, void *base_, void *add_)
427456 MERGE_INT (cfg , base , add , body_max_timeout );
428457 MERGE_INT (cfg , base , add , body_min_rate );
429458
430- cfg -> header_rate_factor = (cfg -> header_min_rate == -1 ) ? base -> header_rate_factor :
431- add -> header_rate_factor ;
432- cfg -> body_rate_factor = (cfg -> body_min_rate == -1 ) ? base -> body_rate_factor :
433- add -> body_rate_factor ;
434-
459+ cfg -> header_rate_factor = (cfg -> header_min_rate == UNSET ) ?
460+ base -> header_rate_factor : add -> header_rate_factor ;
461+ cfg -> body_rate_factor = (cfg -> body_min_rate == UNSET ) ?
462+ base -> body_rate_factor : add -> body_rate_factor ;
435463 return cfg ;
436464}
437465
@@ -574,6 +602,13 @@ static void reqtimeout_hooks(apr_pool_t *pool)
574602 APR_HOOK_MIDDLE );
575603 ap_hook_log_transaction (reqtimeout_after_body , NULL , NULL ,
576604 APR_HOOK_MIDDLE );
605+
606+ #if MRT_DEFAULT_HEADER_MIN_RATE > 0
607+ default_header_rate_factor = apr_time_from_sec (1 ) / MRT_DEFAULT_HEADER_MIN_RATE ;
608+ #endif
609+ #if MRT_DEFAULT_BODY_MIN_RATE > 0
610+ default_body_rate_factor = apr_time_from_sec (1 ) / MRT_DEFAULT_BODY_MIN_RATE ;
611+ #endif
577612}
578613
579614static const command_rec reqtimeout_cmds [] = {
0 commit comments