Apache HTTPD
mod_reqtimeout.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "httpd.h"
18#include "http_config.h"
19#include "http_request.h"
20#include "http_connection.h"
21#include "http_protocol.h"
22#include "http_log.h"
23#include "http_core.h"
24#include "util_filter.h"
25#define APR_WANT_STRFUNC
26#include "apr_strings.h"
27#include "apr_version.h"
28
29module AP_MODULE_DECLARE_DATA reqtimeout_module;
30
31#define UNSET -1
32#define MRT_DEFAULT_handshake_TIMEOUT 0 /* disabled */
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
41
42typedef struct
43{
44 int timeout; /* timeout in secs */
45 int max_timeout; /* max timeout in secs */
46 int min_rate; /* min rate in bytes/s */
47 apr_time_t rate_factor; /* scale factor (#usecs per min_rate) */
49
50typedef struct
51{
52 reqtimeout_stage_t handshake; /* Handshaking (TLS) */
53 reqtimeout_stage_t header; /* Reading the HTTP header */
54 reqtimeout_stage_t body; /* Reading the HTTP body */
56
57/* this struct is used both as conn_config and as filter context */
68
69static const char *const reqtimeout_filter_name = "reqtimeout";
73
75{
78
79 if (apr_brigade_length(bb, 0, &len) != APR_SUCCESS || len <= 0)
80 return;
81
82 new_timeout_at = ccfg->timeout_at + len * ccfg->cur_stage.rate_factor;
83 if (ccfg->max_timeout_at > 0 && new_timeout_at > ccfg->max_timeout_at) {
84 ccfg->timeout_at = ccfg->max_timeout_at;
85 }
86 else {
87 ccfg->timeout_at = new_timeout_at;
88 }
89}
90
94{
95 if (!now)
96 now = apr_time_now();
97 *time_left_p = ccfg->timeout_at - now;
98 if (*time_left_p <= 0)
99 return APR_TIMEUP;
100
101 if (*time_left_p < apr_time_from_sec(1)) {
103 }
104 return APR_SUCCESS;
105}
106
108{
110
111 for ( ; b != APR_BRIGADE_SENTINEL(bb) ; b = APR_BUCKET_PREV(b) ) {
112 const char *str;
114 apr_status_t rv;
115
116 if (APR_BUCKET_IS_EOS(b))
117 return APR_SUCCESS;
118
120 continue;
121
123 if (rv != APR_SUCCESS)
124 return rv;
125
126 if (len == 0)
127 continue;
128
129 if (str[len-1] == APR_ASCII_LF)
130 return APR_SUCCESS;
131 }
132 return APR_INCOMPLETE;
133}
134
135/*
136 * Append bbIn to bbOut and merge small buckets, to avoid DoS by high memory
137 * usage
138 */
140{
141 while (!APR_BRIGADE_EMPTY(bbIn)) {
143 const char *str;
145 apr_status_t rv;
146
148 if (rv != APR_SUCCESS) {
149 return rv;
150 }
151
155 }
156 else {
157 if (len > 0) {
159 if (rv != APR_SUCCESS) {
161 return rv;
162 }
163 }
165 }
166 }
167 return APR_SUCCESS;
168}
169
170
171#define MIN(x,y) ((x) < (y) ? (x) : (y))
177{
179 apr_time_t now = 0;
180 apr_status_t rv;
182 reqtimeout_con_cfg *ccfg = f->ctx;
183
184 if (ccfg->in_keep_alive) {
185 /* For this read[_request line()], wait for the first byte using the
186 * normal keep-alive timeout (hence don't take this expected idle time
187 * into account to setup the connection expiry below).
188 */
189 ccfg->in_keep_alive = 0;
190 rv = ap_get_brigade(f->next, bb, AP_MODE_SPECULATIVE, block, 1);
191 if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
192 return rv;
193 }
195 }
196
197 if (ccfg->cur_stage.timeout > 0) {
198 /* set new timeout */
199 now = apr_time_now();
200 ccfg->timeout_at = now + apr_time_from_sec(ccfg->cur_stage.timeout);
201 ccfg->cur_stage.timeout = 0;
202 if (ccfg->cur_stage.max_timeout > 0) {
203 ccfg->max_timeout_at = now + apr_time_from_sec(ccfg->cur_stage.max_timeout);
204 ccfg->cur_stage.max_timeout = 0;
205 }
206 }
207 else if (ccfg->timeout_at == 0) {
208 /* no timeout set, or in between requests */
209 return ap_get_brigade(f->next, bb, mode, block, readbytes);
210 }
211
212 if (!ccfg->socket) {
213 ccfg->socket = ap_get_conn_socket(f->c);
214 }
215
217 if (rv != APR_SUCCESS)
218 goto out;
219
221 || mode == AP_MODE_EATCRLF) {
222 rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
223 if (ccfg->cur_stage.rate_factor && rv == APR_SUCCESS) {
224 extend_timeout(ccfg, bb);
225 }
226 return rv;
227 }
228
231
234
235 if (mode == AP_MODE_GETLINE) {
236 /*
237 * For a blocking AP_MODE_GETLINE read, apr_brigade_split_line()
238 * would loop until a whole line has been read. As this would make it
239 * impossible to enforce a total timeout, we only do non-blocking
240 * reads.
241 */
242 apr_off_t remaining = HUGE_STRING_LEN;
243 do {
244 apr_off_t bblen;
245#if APR_MAJOR_VERSION < 2
249#endif
250
251 rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, APR_NONBLOCK_READ, remaining);
252 if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
253 break;
254 }
255
256 if (!APR_BRIGADE_EMPTY(bb)) {
257 if (ccfg->cur_stage.rate_factor) {
258 extend_timeout(ccfg, bb);
259 }
260
261 rv = have_lf_or_eos(bb);
262 if (rv != APR_INCOMPLETE) {
263 break;
264 }
265
266 rv = apr_brigade_length(bb, 1, &bblen);
267 if (rv != APR_SUCCESS) {
268 break;
269 }
270 remaining -= bblen;
271 if (remaining <= 0) {
272 break;
273 }
274
275 /* Haven't got a whole line yet, save what we have ... */
276 if (!ccfg->tmpbb) {
277 ccfg->tmpbb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
278 }
279 rv = brigade_append(ccfg->tmpbb, bb);
280 if (rv != APR_SUCCESS)
281 break;
282 }
283
284 /* ... and wait for more */
285#if APR_MAJOR_VERSION < 2
286 pollset.p = f->c->pool;
287 pollset.desc_type = APR_POLL_SOCKET;
288 pollset.reqevents = APR_POLLIN|APR_POLLHUP;
289 pollset.desc.s = ccfg->socket;
291 rv = apr_poll(&pollset, 1, &nsds, poll_timeout);
292#else
293 rv = apr_socket_wait(ccfg->socket, APR_WAIT_READ);
294#endif
295 if (rv != APR_SUCCESS)
296 break;
297
298 rv = check_time_left(ccfg, &time_left, 0);
299 if (rv != APR_SUCCESS)
300 break;
301
302 rv = apr_socket_timeout_set(ccfg->socket,
305
306 } while (1);
307
308 if (ccfg->tmpbb)
309 APR_BRIGADE_PREPEND(bb, ccfg->tmpbb);
310
311 }
312 else { /* mode != AP_MODE_GETLINE */
313 rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
314 /* Don't extend the timeout in speculative mode, wait for
315 * the real (relevant) bytes to be asked later, within the
316 * currently allotted time.
317 */
318 if (ccfg->cur_stage.rate_factor && rv == APR_SUCCESS
320 extend_timeout(ccfg, bb);
321 }
322 }
323
325
326out:
327 if (APR_STATUS_IS_TIMEUP(rv)) {
329 "Request %s read timeout", ccfg->type);
330 /*
331 * If we allow a normal lingering close, the client may keep this
332 * process/thread busy for another 30s (MAX_SECS_TO_LINGER).
333 * Therefore we tell ap_lingering_close() to shorten this period to
334 * 2s (SECONDS_TO_LINGER).
335 */
336 apr_table_setn(f->c->notes, "short-lingering-close", "1");
337
338 /*
339 * Also, we must not allow keep-alive requests, as
340 * ap_finalize_protocol() may ignore our error status (if the timeout
341 * happened on a request body that is discarded).
342 */
343 f->c->keepalive = AP_CONN_CLOSE;
344 }
345 return rv;
346}
347
349{
351 reqtimeout_con_cfg *ccfg = f->ctx;
352 ccfg->timeout_at = 0;
353 }
354 return ap_pass_brigade(f->next, bb);
355}
356
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; \
362 } \
363 else { \
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; \
367 } \
368} while (0)
369
371{
374
375 cfg = ap_get_module_config(c->base_server->module_config,
376 &reqtimeout_module);
377 AP_DEBUG_ASSERT(cfg != NULL);
378
379 /* For compatibility, handshake timeout is disabled when UNSET (< 0) */
380 if (cfg->handshake.timeout <= 0
381 && cfg->header.timeout == 0
382 && cfg->body.timeout == 0) {
383 /* disabled for this vhost */
384 return DECLINED;
385 }
386
387 ccfg = ap_get_module_config(c->conn_config, &reqtimeout_module);
388 if (ccfg == NULL) {
389 ccfg = apr_pcalloc(c->pool, sizeof(reqtimeout_con_cfg));
390 ap_set_module_config(c->conn_config, &reqtimeout_module, ccfg);
393
394 ccfg->type = "handshake";
395 if (cfg->handshake.timeout > 0) {
396 INIT_STAGE(cfg, ccfg, handshake);
397 }
398 }
399
400 /* we are not handling the connection, we just do initialization */
401 return DECLINED;
402}
403
405{
408 ap_get_module_config(c->conn_config, &reqtimeout_module);
409
410 if (ccfg == NULL) {
411 /* not configured for this connection */
412 return;
413 }
414
415 cfg = ap_get_module_config(c->base_server->module_config,
416 &reqtimeout_module);
417 AP_DEBUG_ASSERT(cfg != NULL);
418
419 /* (Re)set the state for this new request, but ccfg->socket and
420 * ccfg->tmpbb which have the lifetime of the connection.
421 */
422 ccfg->type = "header";
423 ccfg->timeout_at = 0;
424 ccfg->max_timeout_at = 0;
425 ccfg->in_keep_alive = (c->keepalives > 0);
426 INIT_STAGE(cfg, ccfg, header);
427}
428
430{
433 ap_get_module_config(r->connection->conn_config, &reqtimeout_module);
434
435 if (ccfg == NULL) {
436 /* not configured for this connection */
437 return OK;
438 }
440 &reqtimeout_module);
441 AP_DEBUG_ASSERT(cfg != NULL);
442
443 ccfg->type = "body";
444 ccfg->timeout_at = 0;
445 ccfg->max_timeout_at = 0;
446 if (r->method_number == M_CONNECT) {
447 /* disabled for a CONNECT request */
448 ccfg->cur_stage.timeout = 0;
449 }
450 else {
451 INIT_STAGE(cfg, ccfg, body);
452 }
453 return OK;
454}
455
456#define UNSET_STAGE(cfg, stage) do { \
457 cfg->stage.timeout = UNSET; \
458 cfg->stage.max_timeout = UNSET; \
459 cfg->stage.min_rate = UNSET; \
460} while (0)
461
463{
465
466 UNSET_STAGE(cfg, handshake);
467 UNSET_STAGE(cfg, header);
468 UNSET_STAGE(cfg, body);
469
470 return cfg;
471}
472
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; \
482} while (0)
483
485{
489
490 MERGE_STAGE(cfg, base, add, handshake);
491 MERGE_STAGE(cfg, base, add, header);
492 MERGE_STAGE(cfg, base, add, body);
493
494 return cfg;
495}
496
497static const char *parse_int(apr_pool_t *p, const char *arg, int *val)
498{
499 char *endptr;
500 *val = strtol(arg, &endptr, 10);
501
502 if (arg == endptr) {
503 return apr_psprintf(p, "Value '%s' not numerical", endptr);
504 }
505 if (*endptr != '\0') {
506 return apr_psprintf(p, "Cannot parse '%s'", endptr);
507 }
508 if (*val < 0) {
509 return "Value must be non-negative";
510 }
511 return NULL;
512}
513
515 apr_pool_t *p,
516 const char *key,
517 const char *val)
518{
519 const char *ret = NULL;
520 char *rate_str = NULL, *initial_str, *max_str = NULL;
522
523 if (!strcasecmp(key, "handshake")) {
524 stage = &conf->handshake;
525 }
526 else if (!strcasecmp(key, "header")) {
527 stage = &conf->header;
528 }
529 else if (!strcasecmp(key, "body")) {
530 stage = &conf->body;
531 }
532 else {
533 return "Unknown RequestReadTimeout parameter";
534 }
535
536 memset(stage, 0, sizeof(*stage));
537
538 if ((rate_str = ap_strcasestr(val, ",minrate="))) {
540 rate_str += strlen(",minrate=");
541 ret = parse_int(p, rate_str, &stage->min_rate);
542 if (ret)
543 return ret;
544
545 if (stage->min_rate == 0)
546 return "Minimum data rate must be larger than 0";
547
548 if ((max_str = strchr(initial_str, '-'))) {
549 *max_str++ = '\0';
550 ret = parse_int(p, max_str, &stage->max_timeout);
551 if (ret)
552 return ret;
553 }
554
555 ret = parse_int(p, initial_str, &stage->timeout);
556 }
557 else {
558 if (ap_strchr_c(val, '-'))
559 return "Must set MinRate option if using timeout range";
560 ret = parse_int(p, val, &stage->timeout);
561 }
562 if (ret)
563 return ret;
564
565 if (stage->max_timeout && stage->timeout >= stage->max_timeout) {
566 return "Maximum timeout must be larger than initial timeout";
567 }
568
569 if (stage->min_rate) {
570 stage->rate_factor = apr_time_from_sec(1) / stage->min_rate;
571 }
572
573 return NULL;
574}
575
576static const char *set_reqtimeouts(cmd_parms *cmd, void *mconfig,
577 const char *arg)
578{
579 reqtimeout_srv_cfg *conf =
580 ap_get_module_config(cmd->server->module_config,
581 &reqtimeout_module);
582
583 while (*arg) {
584 char *word, *val;
585 const char *err;
586
587 word = ap_getword_conf(cmd->temp_pool, &arg);
588 val = strchr(word, '=');
589 if (!val) {
590 return "Invalid RequestReadTimeout parameter. Parameter must be "
591 "in the form 'key=value'";
592 }
593 else
594 *val++ = '\0';
595
596 err = set_reqtimeout_param(conf, cmd->pool, word, val);
597
598 if (err)
599 return apr_psprintf(cmd->temp_pool, "RequestReadTimeout: %s=%s: %s",
600 word, val, err);
601 }
602
603 return NULL;
604
605}
606
608{
609 /*
610 * mod_ssl is AP_FTYPE_CONNECTION + 5 and mod_reqtimeout needs to
611 * be called before mod_ssl for the handshake stage to catch SSL traffic.
612 */
615
616 /*
617 * We need to pause timeout detection in between requests, for
618 * speculative and non-blocking reads, so between each outgoing EOR
619 * and the next pre_read_request call.
620 */
623
624 /*
625 * mod_reqtimeout needs to be called before ap_process_http_request (which
626 * is run at APR_HOOK_REALLY_LAST) but after all other protocol modules.
627 * This ensures that it only influences normal http connections and not
628 * e.g. mod_ftp. We still process it first though, for the handshake stage
629 * to work with/before mod_ssl, but since it's disabled by default it won't
630 * influence non-HTTP modules unless configured explicitly. Also, if
631 * mod_reqtimeout used the pre_connection hook, it would be inserted on
632 * mod_proxy's backend connections, and we don't want this.
633 */
635
640
641#if MRT_DEFAULT_handshake_MIN_RATE
644#endif
645#if MRT_DEFAULT_header_MIN_RATE
648#endif
649#if MRT_DEFAULT_body_MIN_RATE
652#endif
653}
654
655static const command_rec reqtimeout_cmds[] = {
656 AP_INIT_RAW_ARGS("RequestReadTimeout", set_reqtimeouts, NULL, RSRC_CONF,
657 "Set various timeout parameters for TLS handshake and/or "
658 "reading request headers and body"),
659 {NULL}
660};
661
664 NULL, /* create per-dir config structures */
665 NULL, /* merge per-dir config structures */
666 reqtimeout_create_srv_config, /* create per-server config structures */
667 reqtimeout_merge_srv_config, /* merge per-server config structures */
668 reqtimeout_cmds, /* table of config file commands */
670};
const char apr_size_t len
Definition ap_regex.h:187
APR Strings library.
APR Versioning Interface.
void ap_hook_process_connection(ap_HOOK_process_connection_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition connection.c:42
#define ap_get_module_config(v, m)
#define AP_DECLARE_MODULE(foo)
ap_conf_vector_t * base
#define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help)
#define ap_set_module_config(v, m, val)
request_rec * r
#define HUGE_STRING_LEN
Definition httpd.h:303
#define DECLINED
Definition httpd.h:457
#define OK
Definition httpd.h:456
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)
@ AP_FTYPE_CONNECTION
apr_socket_t * ap_get_conn_socket(conn_rec *c)
Definition core.c:5202
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_INFO
Definition http_log.h:70
#define ap_log_cerror
Definition http_log.h:498
#define APLOG_MARK
Definition http_log.h:283
void ap_hook_pre_read_request(ap_HOOK_pre_read_request_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition protocol.c:2583
void ap_hook_post_read_request(ap_HOOK_post_read_request_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition protocol.c:2585
#define AP_BUCKET_IS_EOR(e)
void const char * arg
Definition http_vhost.h:63
#define APR_INCOMPLETE
Definition apr_errno.h:452
#define APR_TIMEUP
Definition apr_errno.h:450
#define APR_STATUS_IS_TIMEUP(s)
Definition apr_errno.h:534
#define APR_STATUS_IS_EAGAIN(s)
Definition apr_errno.h:1272
apr_file_t * f
#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)
apr_read_type_e
Definition apr_buckets.h:57
apr_bucket * e
#define APR_BUCKET_BUFF_SIZE
Definition apr_buckets.h:54
#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_BLOCK_READ
Definition apr_buckets.h:58
@ APR_NONBLOCK_READ
Definition apr_buckets.h:59
apr_dbd_transaction_t int mode
Definition apr_dbd.h:261
#define APR_HOOK_FIRST
Definition apr_hooks.h:301
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
#define RSRC_CONF
#define M_CONNECT
Definition httpd.h:596
#define STANDARD20_MODULE_STUFF
char * ap_strcasestr(const char *s1, const char *s2)
Definition util.c:289
#define ap_strchr_c(s, c)
Definition httpd.h:2353
#define AP_DEBUG_ASSERT(exp)
Definition httpd.h:2283
char * ap_getword_conf(apr_pool_t *p, const char **line)
Definition util.c:833
@ AP_CONN_CLOSE
Definition httpd.h:1145
apr_size_t size
apr_uint32_t val
Definition apr_atomic.h:66
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
const char * key
int strcasecmp(const char *a, const char *b)
#define APR_ASCII_LF
Definition apr_general.h:63
apr_vformatter_buff_t * c
Definition apr_lib.h:175
apr_int32_t apr_int32_t * nsds
Definition apr_poll.h:301
@ APR_POLL_SOCKET
Definition apr_poll.h:93
apr_pool_t * b
Definition apr_pools.h:529
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * s
Definition apr_strings.h:95
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
apr_int64_t apr_interval_time_t
Definition apr_time.h:55
apr_int64_t apr_time_t
Definition apr_time.h:45
#define apr_time_from_sec(sec)
Definition apr_time.h:78
#define APR_POLLIN
Definition apr_poll.h:49
#define APR_POLLHUP
Definition apr_poll.h:53
Apache Configuration.
Apache connection library.
CORE HTTP Daemon.
Apache Logging library.
HTTP protocol handling.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
static apr_file_t * out
Definition mod_info.c:85
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
#define MIN(x, y)
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)
#define UNSET
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)
return NULL
Definition mod_so.c:359
The representation of a filter chain.
apr_pool_t * pool
apr_pollset_private_t * p
Structure to store things which are per connection.
Definition httpd.h:1152
struct ap_conf_vector_t * conn_config
Definition httpd.h:1190
reqtimeout_stage_t cur_stage
apr_socket_t * socket
apr_bucket_brigade * tmpbb
apr_time_t max_timeout_at
reqtimeout_stage_t header
reqtimeout_stage_t body
reqtimeout_stage_t handshake
A structure that represents the current request.
Definition httpd.h:845
int method_number
Definition httpd.h:898
conn_rec * connection
Definition httpd.h:849
server_rec * server
Definition httpd.h:851
A structure to store information for each virtual server.
Definition httpd.h:1322
struct ap_conf_vector_t * module_config
Definition httpd.h:1341
static apr_pollset_t * pollset
Definition testpoll.c:41
static apr_time_t now
Definition testtime.c:33
apr_status_t apr_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
Definition sockopt.c:75
apr_status_t apr_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t)
Definition sockopt.c:355
#define str
Apache filter library.
ap_input_mode_t
input filtering modes
Definition util_filter.h:41
@ AP_MODE_SPECULATIVE
Definition util_filter.h:53
@ AP_MODE_INIT
Definition util_filter.h:62
@ AP_MODE_GETLINE
Definition util_filter.h:48
@ AP_MODE_EATCRLF
Definition util_filter.h:50