You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Ed Korthof <ed...@organic.com> on 1997/01/20 13:07:40 UTC
Patch for new Timeouts
This is a bit more complete than the previous patch I sent; it
incorporates the features discussed on the list (at least, those I could
find). I'll send a patch for the documentation tomorrow -- but basically
this allows for timeout for reading the headers, for reading a
(presumably, POSTed) message body, and a per-chunk timeout. All are
configured through 'Timeout [type] #'.
All of the new timeouts default to zero, which disables them, so this will
behave exactly like the current version unless configured otherwise.
This could be usefully generalized by forming a table of Timeouts by name
and value, and looking up against that; but I was worried about
efficiency. Still, if others here would prefer such a system, it'd be
easy to rewrite this (now that I've got a handle on the TAKE12 method).
Also, there's one timeout which is currently unused -- Timeout Read # --
I'd like to write code to have a static counter for the entire time spent
reading the request, so as to provide for an absolute maximum to the time
spent reading the request.
While looking this over, I believe I found a bug in the RLimit* code -- it
doesn't appear to notice a second argument (basically, the set_rlimit &
etc. functions need to be given another argument for another char *
(possibly NULL)). Anyway, I'll post a patch to that tomorrow (too tired
right now).
-- Ed Korthof | Web Server Engineer --
-- ed@organic.com | Organic Online, Inc --
-- (415) 278-5676 | Fax: (415) 284-6891 --
*** /usr/local/src/apache/apache_1.2b2/src/http_main.c Sat Jan 18 15:07:44 1997
--- http_main.c Mon Jan 20 03:41:02 1997
***************
*** 461,466 ****
--- 461,474 ----
signal(SIGALRM,(void (*)())timeout);
if (r->connection->keptalive)
alarm (r->server->keep_alive_timeout);
+ else if (r->server->timeout_read && !strcmp(name, "Read"))
+ alarm (r->server->timeout_read);
+ else if (r->server->timeout_read_per_chunk && !strcmp(name, "ReadPerChunk"))
+ alarm (r->server->timeout_read_per_chunk);
+ else if (r->server->timeout_read_header && !strcmp(name, "ReadHeader"))
+ alarm (r->server->timeout_read_header);
+ else if (r->server->timeout_read_content && !strcmp(name, "ReadContent"))
+ alarm (r->server->timeout_read_content);
else
alarm (r->server->timeout);
}
*** /usr/local/src/apache/apache_1.2b2/src/http_core.c Sat Jan 18 15:07:43 1997
--- http_core.c Mon Jan 20 03:26:15 1997
***************
*** 879,886 ****
return NULL;
}
! const char *set_timeout (cmd_parms *cmd, void *dummy, char *arg) {
! cmd->server->timeout = atoi (arg);
return NULL;
}
--- 879,916 ----
return NULL;
}
! const char *set_timeout (cmd_parms *cmd, void *dummy, const char *arg, const char *arg2) {
! int * target = 0;
! char * str;
! if ((str = getword_conf(cmd->pool, &arg))) {
! if (!strncmp(str,"Read",4)) {
! if (!strcmp(str, "Read")) {
! target = & cmd->server->timeout_read;
! } else if (!strcmp(str, "ReadPerChunk")) {
! target = & cmd->server->timeout_read_per_chunk;
! } else if (!strcmp(str, "ReadHeader")) {
! target = & cmd->server->timeout_read_header;
! } else if (!strcmp(str, "ReadContent")) {
! target = & cmd->server->timeout_read_content;
! } else {
! log_printf(cmd->server, "Invalid parameters for %s", cmd->cmd->name);
! return NULL;
! }
! }
! else {
! cmd->server->timeout = atoi(str);
! }
! }
! else {
! log_printf(cmd->server, "Invalid parameters for %s", cmd->cmd->name);
! return NULL;
! }
!
! if (target && (str = getword_conf(cmd->pool, &arg2))) {
! *target = atoi(str);
! } else if (target) {
! log_printf(cmd->server, "Invalid parameters for %s", cmd->cmd->name);
! }
return NULL;
}
***************
*** 1160,1166 ****
"A name or names alternately used to access the server" },
{ "ServerPath", set_serverpath, NULL, RSRC_CONF, TAKE1,
"The pathname the server can be reached at" },
! { "Timeout", set_timeout, NULL, RSRC_CONF, TAKE1, "Timeout duration (sec)"},
{ "KeepAliveTimeout", set_keep_alive_timeout, NULL, RSRC_CONF, TAKE1, "Keep-Alive timeout duration (sec)"},
{ "KeepAlive", set_keep_alive, NULL, RSRC_CONF, TAKE1, "Maximum Keep-Alive requests per connection (0 to disable)" },
{ "IdentityCheck", set_idcheck, NULL, RSRC_CONF|ACCESS_CONF, FLAG, "Enable identd (RFC931) user lookups - SLOW" },
--- 1190,1196 ----
"A name or names alternately used to access the server" },
{ "ServerPath", set_serverpath, NULL, RSRC_CONF, TAKE1,
"The pathname the server can be reached at" },
! { "Timeout", set_timeout, (void *)NULL, OR_ALL, TAKE12, "Timeout duration (sec), takes one or two arguments: with 1, sets default timeout; with 2, 1st is name of the timeout to set. Options are: Read, ReadPerChunk, ReadHeader, ReadContent"},
{ "KeepAliveTimeout", set_keep_alive_timeout, NULL, RSRC_CONF, TAKE1, "Keep-Alive timeout duration (sec)"},
{ "KeepAlive", set_keep_alive, NULL, RSRC_CONF, TAKE1, "Maximum Keep-Alive requests per connection (0 to disable)" },
{ "IdentityCheck", set_idcheck, NULL, RSRC_CONF|ACCESS_CONF, FLAG, "Enable identd (RFC931) user lookups - SLOW" },
*** /usr/local/src/apache/apache_1.2b2/src/http_config.c Sat Jan 18 15:07:43 1997
--- http_config.c Mon Jan 20 03:24:12 1997
***************
*** 914,919 ****
--- 914,923 ----
s->srm_confname = NULL;
s->access_confname = NULL;
s->timeout = 0;
+ s->timeout_read = 0;
+ s->timeout_read_per_chunk = 0;
+ s->timeout_read_header = 0;
+ s->timeout_read_content = 0;
s->keep_alive_timeout = 0;
s->keep_alive = -1;
/* start the list of addreses */
***************
*** 1019,1024 ****
--- 1023,1032 ----
s->srm_confname = RESOURCE_CONFIG_FILE;
s->access_confname = ACCESS_CONFIG_FILE;
s->timeout = DEFAULT_TIMEOUT;
+ s->timeout_read = DEFAULT_TIMEOUT_READ;
+ s->timeout_read_per_chunk = DEFAULT_TIMEOUT_READ_PER_CHUNK;
+ s->timeout_read_header = DEFAULT_TIMEOUT_READ_HEADER;
+ s->timeout_read_content = DEFAULT_TIMEOUT_READ_CONTENT;
s->keep_alive_timeout = DEFAULT_KEEPALIVE_TIMEOUT;
s->keep_alive = DEFAULT_KEEPALIVE;
s->next = NULL;
*** /usr/local/src/apache/apache_1.2b2/src/httpd.h Sat Jan 18 15:07:43 1997
--- httpd.h Mon Jan 20 03:28:13 1997
***************
*** 183,188 ****
--- 183,197 ----
/* The timeout for waiting for messages */
#define DEFAULT_TIMEOUT 1200
+ /* The timeout to read a request */
+ #define DEFAULT_TIMEOUT_READ 180
+
+ /* Timeouts per chunk, and to apply after we realize that incoming message
+ has a message body. Defaults are set to 0 to disable. */
+ #define DEFAULT_TIMEOUT_READ_PER_CHUNK 0
+ #define DEFAULT_TIMEOUT_READ_HEADER 0
+ #define DEFAULT_TIMEOUT_READ_CONTENT 0
+
/* The timeout for waiting for keepalive timeout until next request */
#define DEFAULT_KEEPALIVE_TIMEOUT 15
***************
*** 585,590 ****
--- 594,604 ----
server_addr_rec *addrs;
int timeout; /* Timeout, in seconds, before we give up */
+ int timeout_read; /* Timeout, in seconds, to read request */
+ int timeout_read_per_chunk; /* Timeout, in seconds, between reads */
+ int timeout_read_header; /* Timeout, in seconds, for reading the header*/
+ int timeout_read_content; /* Timeout, in seconds, to read a request */
+ /* w/ content -- eg. a POST */
int keep_alive_timeout; /* Seconds we'll wait for another request */
int keep_alive; /* Maximum requests per connection */
int send_buffer_size; /* size of TCP send buffer (in bytes) */
*** /usr/local/src/apache/apache_1.2b2/src/http_protocol.c Mon Jan 6 18:17:53 1997
--- http_protocol.c Mon Jan 20 02:14:11 1997
***************
*** 652,661 ****
/* Get the request... */
! hard_timeout ("read", r);
if (!read_request_line (r)) return NULL;
if (!r->assbackwards) get_mime_headers (r);
/* handle Host header here, to get virtual server */
if (r->hostname || (r->hostname = table_get(r->headers_in, "Host")))
--- 652,664 ----
/* Get the request... */
! hard_timeout ("ReadHeader", r);
!
if (!read_request_line (r)) return NULL;
if (!r->assbackwards) get_mime_headers (r);
+ kill_timeout (r);
+
/* handle Host header here, to get virtual server */
if (r->hostname || (r->hostname = table_get(r->headers_in, "Host")))
***************
*** 663,669 ****
else
check_serverpath(r);
- kill_timeout (r);
conn->keptalive = 0; /* We now have a request - so no more short timeouts */
if(!strcmp(r->method, "HEAD")) {
--- 666,671 ----
***************
*** 1227,1233 ****
if (bufsiz <= 0)
return -1; /* Cannot read chunked with a small buffer */
! if (r->remaining == 0) { /* Start of new chunk */
chunk_start = getline(buffer, bufsiz, r->connection->client, 0);
if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1))
--- 1229,1236 ----
if (bufsiz <= 0)
return -1; /* Cannot read chunked with a small buffer */
! if (r->remaining == 0) { /* Start of new chunk */
! hard_timeout("ReadPerChunk", r); /* Timeout for reading a chunk */
chunk_start = getline(buffer, bufsiz, r->connection->client, 0);
if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1))
*** /usr/local/src/apache/apache_1.2b2/src/mod_cgi.c Sun Dec 1 12:28:55 1996
--- mod_cgi.c Mon Jan 20 03:56:19 1997
***************
*** 419,425 ****
dbpos = 0;
}
! hard_timeout ("copy script args", r);
handler = signal (SIGPIPE, SIG_IGN);
while ((len_read =
--- 419,425 ----
dbpos = 0;
}
! hard_timeout ("ReadContent", r);
handler = signal (SIGPIPE, SIG_IGN);
while ((len_read =