25#define APR_WANT_STRFUNC
29module AP_MODULE_DECLARE_DATA reqtimeout_module;
32#define MRT_DEFAULT_handshake_TIMEOUT 0
33#define MRT_DEFAULT_handshake_MAX_TIMEOUT 0
34#define MRT_DEFAULT_handshake_MIN_RATE 0
35#define MRT_DEFAULT_header_TIMEOUT 20
36#define MRT_DEFAULT_header_MAX_TIMEOUT 40
37#define MRT_DEFAULT_header_MIN_RATE 500
38#define MRT_DEFAULT_body_TIMEOUT 20
39#define MRT_DEFAULT_body_MAX_TIMEOUT 0
40#define MRT_DEFAULT_body_MIN_RATE 500
84 ccfg->timeout_at =
ccfg->max_timeout_at;
171#define MIN(x,y) ((x) < (y) ? (x) : (y))
184 if (
ccfg->in_keep_alive) {
189 ccfg->in_keep_alive = 0;
197 if (
ccfg->cur_stage.timeout > 0) {
201 ccfg->cur_stage.timeout = 0;
202 if (
ccfg->cur_stage.max_timeout > 0) {
204 ccfg->cur_stage.max_timeout = 0;
207 else if (
ccfg->timeout_at == 0) {
245#if APR_MAJOR_VERSION < 2
257 if (
ccfg->cur_stage.rate_factor) {
271 if (remaining <= 0) {
285#if APR_MAJOR_VERSION < 2
329 "Request %s read timeout",
ccfg->type);
352 ccfg->timeout_at = 0;
357#define INIT_STAGE(cfg, ccfg, stage) do { \
358 if (cfg->stage.timeout != UNSET) { \
359 ccfg->cur_stage.timeout = cfg->stage.timeout; \
360 ccfg->cur_stage.max_timeout = cfg->stage.max_timeout; \
361 ccfg->cur_stage.rate_factor = cfg->stage.rate_factor; \
364 ccfg->cur_stage.timeout = MRT_DEFAULT_##stage##_TIMEOUT; \
365 ccfg->cur_stage.max_timeout = MRT_DEFAULT_##stage##_MAX_TIMEOUT; \
366 ccfg->cur_stage.rate_factor = default_##stage##_rate_factor; \
394 ccfg->type =
"handshake";
422 ccfg->type =
"header";
423 ccfg->timeout_at = 0;
424 ccfg->max_timeout_at = 0;
425 ccfg->in_keep_alive = (
c->keepalives > 0);
444 ccfg->timeout_at = 0;
445 ccfg->max_timeout_at = 0;
448 ccfg->cur_stage.timeout = 0;
456#define UNSET_STAGE(cfg, stage) do { \
457 cfg->stage.timeout = UNSET; \
458 cfg->stage.max_timeout = UNSET; \
459 cfg->stage.min_rate = UNSET; \
473#define MERGE_INT(cfg, base, add, val) \
474 cfg->val = (add->val == UNSET) ? base->val : add->val
475#define MERGE_STAGE(cfg, base, add, stage) do { \
476 MERGE_INT(cfg, base, add, stage.timeout); \
477 MERGE_INT(cfg, base, add, stage.max_timeout); \
478 MERGE_INT(cfg, base, add, stage.min_rate); \
479 cfg->stage.rate_factor = (cfg->stage.min_rate == UNSET) \
480 ? base->stage.rate_factor \
481 : add->stage.rate_factor; \
509 return "Value must be non-negative";
533 return "Unknown RequestReadTimeout parameter";
545 if (
stage->min_rate == 0)
546 return "Minimum data rate must be larger than 0";
559 return "Must set MinRate option if using timeout range";
566 return "Maximum timeout must be larger than initial timeout";
569 if (
stage->min_rate) {
590 return "Invalid RequestReadTimeout parameter. Parameter must be "
591 "in the form 'key=value'";
641#if MRT_DEFAULT_handshake_MIN_RATE
645#if MRT_DEFAULT_header_MIN_RATE
649#if MRT_DEFAULT_body_MIN_RATE
657 "Set various timeout parameters for TLS handshake and/or "
658 "reading request headers and body"),
const char apr_size_t len
APR Versioning Interface.
void ap_hook_process_connection(ap_HOOK_process_connection_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
#define ap_get_module_config(v, m)
#define AP_DECLARE_MODULE(foo)
#define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help)
#define ap_set_module_config(v, m, val)
apr_status_t ap_pass_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket)
ap_filter_t * ap_add_input_filter(const char *name, void *ctx, request_rec *r, conn_rec *c)
ap_filter_rec_t * ap_register_output_filter(const char *name, ap_out_filter_func filter_func, ap_init_filter_func filter_init, ap_filter_type ftype)
ap_filter_t * ap_add_output_filter(const char *name, void *ctx, request_rec *r, conn_rec *c)
apr_status_t ap_filter_rec_t * ap_register_input_filter(const char *name, ap_in_filter_func filter_func, ap_init_filter_func filter_init, ap_filter_type ftype)
apr_status_t ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
apr_socket_t * ap_get_conn_socket(conn_rec *c)
void ap_hook_pre_read_request(ap_HOOK_pre_read_request_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
void ap_hook_post_read_request(ap_HOOK_post_read_request_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
#define AP_BUCKET_IS_EOR(e)
#define APR_STATUS_IS_TIMEUP(s)
#define APR_STATUS_IS_EAGAIN(s)
#define APR_BUCKET_REMOVE(e)
#define APR_BRIGADE_LAST(b)
#define APR_BUCKET_IS_METADATA(e)
#define APR_BRIGADE_PREPEND(a, b)
#define APR_BRIGADE_INSERT_TAIL(b, e)
#define APR_BUCKET_BUFF_SIZE
#define APR_BRIGADE_EMPTY(b)
#define APR_BRIGADE_SENTINEL(b)
#define APR_BUCKET_IS_EOS(e)
#define APR_BRIGADE_FIRST(b)
#define apr_bucket_read(e, str, len, block)
#define APR_BUCKET_PREV(e)
apr_bucket_brigade * bbIn
#define apr_bucket_destroy(e)
apr_dbd_transaction_t int mode
#define STANDARD20_MODULE_STUFF
char * ap_strcasestr(const char *s1, const char *s2)
#define ap_strchr_c(s, c)
#define AP_DEBUG_ASSERT(exp)
char * ap_getword_conf(apr_pool_t *p, const char **line)
const char int apr_pool_t * pool
int strcasecmp(const char *a, const char *b)
apr_vformatter_buff_t * c
apr_int32_t apr_int32_t * nsds
#define apr_pcalloc(p, size)
apr_int32_t apr_int32_t apr_int32_t err
apr_int64_t apr_interval_time_t
#define apr_time_from_sec(sec)
Apache connection library.
static apr_status_t have_lf_or_eos(apr_bucket_brigade *bb)
static int reqtimeout_init(conn_rec *c)
static int default_handshake_rate_factor
static int default_header_rate_factor
#define MRT_DEFAULT_body_MIN_RATE
#define UNSET_STAGE(cfg, stage)
static const command_rec reqtimeout_cmds[]
static void * reqtimeout_create_srv_config(apr_pool_t *p, server_rec *s)
static const char * set_reqtimeouts(cmd_parms *cmd, void *mconfig, const char *arg)
#define MRT_DEFAULT_handshake_MIN_RATE
static void extend_timeout(reqtimeout_con_cfg *ccfg, apr_bucket_brigade *bb)
#define MRT_DEFAULT_header_MIN_RATE
static apr_status_t check_time_left(reqtimeout_con_cfg *ccfg, apr_time_t *time_left_p, apr_time_t now)
static void reqtimeout_hooks(apr_pool_t *pool)
static int default_body_rate_factor
static const char * set_reqtimeout_param(reqtimeout_srv_cfg *conf, apr_pool_t *p, const char *key, const char *val)
static int reqtimeout_before_body(request_rec *r)
static apr_status_t reqtimeout_filter(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
static apr_status_t reqtimeout_eor(ap_filter_t *f, apr_bucket_brigade *bb)
static const char *const reqtimeout_filter_name
static void reqtimeout_before_header(request_rec *r, conn_rec *c)
static void * reqtimeout_merge_srv_config(apr_pool_t *p, void *base_, void *add_)
#define MERGE_STAGE(cfg, base, add, stage)
static apr_status_t brigade_append(apr_bucket_brigade *bbOut, apr_bucket_brigade *bbIn)
#define INIT_STAGE(cfg, ccfg, stage)
static const char * parse_int(apr_pool_t *p, const char *arg, int *val)
The representation of a filter chain.
apr_pollset_private_t * p
Structure to store things which are per connection.
struct ap_conf_vector_t * conn_config
reqtimeout_stage_t cur_stage
apr_bucket_brigade * tmpbb
apr_time_t max_timeout_at
reqtimeout_stage_t header
reqtimeout_stage_t handshake
A structure that represents the current request.
A structure to store information for each virtual server.
struct ap_conf_vector_t * module_config
static apr_pollset_t * pollset
apr_status_t apr_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
apr_status_t apr_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t)
ap_input_mode_t
input filtering modes