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