From b2df11804e874b8dc91bbc4577f1f77acdf2c25f Mon Sep 17 00:00:00 2001
From: Stefan Fritsch
Date: Sat, 23 Jan 2010 16:21:52 +0000
Subject: [PATCH] Rename RequestTimeout into RequestReadTimeout and change the
configuration syntax again. Hopefully this makes it easier to understand.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@902434 13f79535-47bb-0310-9956-ffa450edef68
---
docs/manual/mod/mod_reqtimeout.xml | 91 +++++++++++++-------------
modules/filters/mod_reqtimeout.c | 100 ++++++++++++++++++-----------
2 files changed, 108 insertions(+), 83 deletions(-)
diff --git a/docs/manual/mod/mod_reqtimeout.xml b/docs/manual/mod/mod_reqtimeout.xml
index 251826cfcf..dd84c8697a 100644
--- a/docs/manual/mod/mod_reqtimeout.xml
+++ b/docs/manual/mod/mod_reqtimeout.xml
@@ -38,30 +38,30 @@
30 seconds for receiving the request body:
- RequestTimeout headerinit=10 bodyinit=30
+ RequestReadTimeout header=10 body=30
- Allow at least 10 seconds to receive the request including the headers.
+ Allow at least 10 seconds to receive the request body.
If the client sends data, increase the timeout by 1 second for every
- 500 bytes received. But do not allow more than 30 seconds for the
- request including the headers:
+ 1000 bytes received, with no upper limit for the timeout (exept for
+ the limit given indirectly by
+ LimitRequestBody):
- RequestTimeout headerinit=10 headerminrate=500 headermax=30
+ RequestReadTimeout body=10,MinRate=1000
- Allow at least 10 seconds to receive the request body.
+ Allow at least 10 seconds to receive the request including the headers.
If the client sends data, increase the timeout by 1 second for every
- 1000 bytes received, with no upper limit for the timeout (exept for
- the limit given indirectly by
- LimitRequestBody):
+ 500 bytes received. But do not allow more than 30 seconds for the
+ request including the headers:
- RequestTimeout bodyinit=10 bodyminrate=1000
+ RequestReadTimeout header=10-30,MinRate=500
@@ -69,16 +69,14 @@
-RequestTimeout
+RequestReadTimeout
Set timeout values for receiving request headers and body from client.
-RequestTimeout
-[headerinit=time
-[headerminrate=rate [headermax=time]]]
-[bodyinit=time
-[bodyminrate=rate [bodymax=time]]]
+RequestReadTimeout
+[header=timeout[[-maxtimeout],MinRate=rate]
+[body=timeout[[-maxtimeout],MinRate=rate]
-Unset; all values 0
+Unset; no limit
server configvirtual host
@@ -96,46 +94,45 @@
(usually the case on Linux and FreeBSD), the socket is not sent to the
server process before at least one byte (or the whole request for
httpready
) is received. The header timeout configured with
- RequestTimeout
is only effective after the server process has
+ RequestReadTimeout
is only effective after the server process has
received the socket.
- For the timeout parameters, the value 0 means no limit.
+ For each of the two timeout types (header or body), there are three ways
+ to specify the timeout:
+
+
+
-
+
- Fixed timeout value:
- headerinit
- - The initial timeout for receiving the request headers in seconds.
- Also the timeout for receiving the first byte of the request. If
-
headerminrate
is not set, the request line and all headers
- must be received within this time.
+ type=timeout
- headerminrate
- - The minimum data rate for receiving the request headers in
- bytes/second. Whenever data is received, the timeout is increased
- according to this data rate.
+ The time in seconds allowed for reading all of the request headers or
+ body, respectively. A value of 0 means no limit.
+
- headermax
- - The maximum timeout for receiving the request headers in seconds.
- The timeout cannot be increased above this value by
-
headerminrate
.
+ - Timeout value that is increased when data is
+ received:
+
+ type=timeout,MinRate=data_rate
+
- bodyinit
- - The initial timeout for receiving the request body in seconds.
- Also the timeout for receiving the first byte of the request body. If
-
bodyminrate
is not set, the complete request body must be
- received within this time.
+ Same as above, but whenever data is received, the timeout value is
+ increased according to the specified minimum data rate (in bytes per
+ second).
+
- bodyminrate
- - The minimum data rate for receiving the request body in
- bytes/second. Whenever data is received, the timeout is increased
- according to this data rate.
+ - Timeout value that is increased when data is received, with an
+ upper bound:
+
+ type=timeout-maxtimeout,MinRate=data_rate
+
- bodymax
- - The maximum timeout for receiving the request body in seconds.
- The timeout cannot be increased above this value by
-
bodyminrate
+ Same as above, but the timeout will not be increased above the second
+ value of the specified timeout range.
+
-
+
diff --git a/modules/filters/mod_reqtimeout.c b/modules/filters/mod_reqtimeout.c
index 206c1aad04..c0faba6a53 100644
--- a/modules/filters/mod_reqtimeout.c
+++ b/modules/filters/mod_reqtimeout.c
@@ -281,12 +281,15 @@ static void *reqtimeout_merge_srv_config(apr_pool_t *p, void *base_, void *add_)
return cfg;
}
-static const char *parse_int(const char *arg, int *val) {
+static const char *parse_int(apr_pool_t *p, const char *arg, int *val) {
char *endptr;
*val = strtol(arg, &endptr, 10);
-
- if ((arg == endptr) || (*endptr != '\0')) {
- return "Value not numerical";
+
+ if (arg == endptr) {
+ return apr_psprintf(p, "Value '%s' not numerical", endptr);
+ }
+ if (*endptr != '\0') {
+ return apr_psprintf(p, "Cannot parse '%s'", endptr);
}
if (*val < 0) {
return "Value must be non-negative";
@@ -300,43 +303,67 @@ static const char *set_reqtimeout_param(reqtimeout_srv_cfg *conf,
const char *val)
{
const char *ret = NULL;
- if (!strcasecmp(key, "headerinit")) {
- ret = parse_int(val, &conf->header_timeout);
+ char *rate_str = NULL, *initial_str, *max_str = NULL;
+ int rate = 0, initial = 0, max = 0;
+ enum { PARAM_HEADER, PARAM_BODY } type;
+
+ if (!strcasecmp(key, "header")) {
+ type = PARAM_HEADER;
}
- else if (!strcasecmp(key, "headermax")) {
- ret = parse_int(val, &conf->header_max_timeout);
- if (!ret && conf->header_max_timeout > 0 &&
- conf->header_max_timeout <= conf->header_timeout) {
- ret = "Max timeout must be larger than initial timeout";
- }
+ else if (!strcasecmp(key, "body")) {
+ type = PARAM_BODY;
}
- else if (!strcasecmp(key, "bodyinit")) {
- ret = parse_int(val, &conf->body_timeout);
+ else {
+ return "Unknown RequestReadTimeout parameter";
}
- else if (!strcasecmp(key, "bodymax")) {
- ret = parse_int(val, &conf->body_max_timeout);
- if (!ret && conf->body_max_timeout > 0 &&
- conf->body_max_timeout <= conf->body_timeout) {
- ret = "Max timeout must be larger than initial timeout";
+
+ if ((rate_str = strcasestr(val, ",minrate="))) {
+ initial_str = apr_pstrndup(p, val, rate_str - val);
+ rate_str += strlen(",minrate=");
+ ret = parse_int(p, rate_str, &rate);
+ if (ret)
+ return ret;
+
+ if (rate == 0)
+ return "Minimum data rate must be larger than 0";
+
+ if ((max_str = strchr(initial_str, '-'))) {
+ *max_str++ = '\0';
+ ret = parse_int(p, max_str, &max);
+ if (ret)
+ return ret;
}
+
+ ret = parse_int(p, initial_str, &initial);
}
- else if (!strcasecmp(key, "headerminrate")) {
- ret = parse_int(val, &conf->header_min_rate);
- if (!ret && conf->header_min_rate > 0) {
- conf->header_rate_factor = apr_time_from_sec(1) / conf->header_min_rate;
- }
+ else {
+ if (ap_strchr_c(val, '-'))
+ return "Must set MinRate option if using timeout range";
+ ret = parse_int(p, val, &initial);
}
- else if (!strcasecmp(key, "bodyminrate")) {
- ret = parse_int(val, &conf->body_min_rate);
- if (!ret && conf->body_min_rate > 0) {
- conf->body_rate_factor = apr_time_from_sec(1) / conf->body_min_rate;
- }
+
+ if (ret)
+ return ret;
+
+ if (max && initial >= max) {
+ return "Maximum timeout must be larger than initial timeout";
+ }
+
+ if (type == PARAM_HEADER) {
+ conf->header_timeout = initial;
+ conf->header_max_timeout = max;
+ conf->header_min_rate = rate;
+ if (rate)
+ conf->header_rate_factor = apr_time_from_sec(1) / rate;
}
else {
- ret = "unknown RequestTimeout parameter";
+ conf->body_timeout = initial;
+ conf->body_max_timeout = max;
+ conf->body_min_rate = rate;
+ if (rate)
+ conf->body_rate_factor = apr_time_from_sec(1) / rate;
}
return ret;
-
}
static const char *set_reqtimeouts(cmd_parms *cmd, void *mconfig,
@@ -353,7 +380,7 @@ static const char *set_reqtimeouts(cmd_parms *cmd, void *mconfig,
word = ap_getword_conf(cmd->pool, &arg);
val = strchr(word, '=');
if (!val) {
- return "Invalid RequestTimeout parameter. Parameter must be "
+ return "Invalid RequestReadTimeout parameter. Parameter must be "
"in the form 'key=value'";
}
else
@@ -362,8 +389,8 @@ static const char *set_reqtimeouts(cmd_parms *cmd, void *mconfig,
err = set_reqtimeout_param(conf, cmd->pool, word, val);
if (err)
- return apr_pstrcat(cmd->temp_pool, "RequestTimeout: ", err, " ",
- word, "=", val, "; ", NULL);
+ return apr_psprintf(cmd->temp_pool, "RequestReadTimeout: %s=%s: %s",
+ word, val, err);
}
return NULL;
@@ -387,8 +414,9 @@ static void reqtimeout_hooks(apr_pool_t *pool)
}
static const command_rec reqtimeout_cmds[] = {
- AP_INIT_RAW_ARGS("RequestTimeout", set_reqtimeouts, NULL, RSRC_CONF,
- "Adjust various Request Timeout parameters"),
+ AP_INIT_RAW_ARGS("RequestReadTimeout", set_reqtimeouts, NULL, RSRC_CONF,
+ "Set various timeout parameters for reading request "
+ "headers and body"),
{NULL}
};
--
2.40.0