mod_reqtimeout.c revision 3231873d0ba8064a1c90307d810a83ec01a88675
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_connection.h"
#include "http_protocol.h"
#include "http_log.h"
#include "util_filter.h"
#define APR_WANT_STRFUNC
#include "apr_strings.h"
typedef struct
{
int header_timeout; /* timeout for reading the req hdrs in secs */
int header_max_timeout; /* max timeout for req hdrs in secs */
int header_min_rate; /* min rate for reading req hdrs in bytes/s */
int body_timeout; /* timeout for reading the req body in secs */
int body_max_timeout; /* max timeout for req body in secs */
int body_min_rate; /* timeout for reading the req body in secs */
typedef struct
{
int min_rate;
int new_timeout;
int new_max_timeout;
int in_keep_alive;
char *type;
typedef struct
{
static const char *const reqtimeout_filter_name = "reqtimeout";
{
return;
}
else {
}
}
{
if (ccfg->in_keep_alive) {
/* For this read, the normal keep-alive timeout must be used */
ccfg->in_keep_alive = 0;
}
now = apr_time_now();
if (ccfg->new_timeout > 0) {
/* set new timeout */
ccfg->new_timeout = 0;
if (ccfg->new_max_timeout > 0) {
ccfg->new_max_timeout = 0;
}
}
else if (ccfg->timeout_at == 0) {
/* no timeout set */
}
if (time_left <= 0) {
return APR_TIMEUP;
}
|| mode == AP_MODE_EATCRLF) {
}
return rv;
}
}
if (saved_sock_timeout >= time_left) {
}
else {
saved_sock_timeout = -1;
}
if (saved_sock_timeout != -1) {
}
}
if (rv == APR_TIMEUP) {
}
return rv;
}
{
/* not configured for this vhost */
return OK;
}
return OK;
}
static int reqtimeout_after_headers(request_rec *r)
{
/* not configured for this vhost */
return OK;
}
ccfg->timeout_at = 0;
ccfg->max_timeout_at = 0;
return OK;
}
static int reqtimeout_after_body(request_rec *r)
{
/* not configured for this vhost */
return OK;
}
ccfg->timeout_at = 0;
ccfg->max_timeout_at = 0;
return OK;
}
{
return cfg;
}
{
return cfg;
}
char *endptr;
return "Value not numerical";
}
if (*val < 0) {
return "Value must be non-negative";
}
return NULL;
}
apr_pool_t *p,
const char *key,
const char *val)
{
}
ret = "Max timeout must be larger than initial timeout";
}
}
}
ret = "Max timeout must be larger than initial timeout";
}
}
}
}
else {
ret = "unknown ReqTimeout parameter";
}
return ret;
}
const char *arg)
{
while (*arg) {
const char *err;
if (!val) {
return "Invalid ReqTimeout parameter. Parameter must be "
"in the form 'key=value'";
}
else
*val++ = '\0';
if (err)
}
return NULL;
}
{
/*
* mod_ssl is AP_FTYPE_CONNECTION + 5 and mod_reqtimeout needs to
* be called before mod_ssl. Otherwise repeated reads during the ssl
* handshake can prevent the timeout from triggering.
*/
AP_FTYPE_CONNECTION + 8);
}
static const command_rec reqtimeout_cmds[] = {
"Adjust various Request Timeout parameters"),
{NULL}
};
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
reqtimeout_create_srv_config, /* create per-server config structures */
reqtimeout_merge_srv_config, /* merge per-server config structures */
reqtimeout_cmds, /* table of config file commands */
};