You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Nathan Schrenk <ns...@neog.com> on 1996/01/03 18:28:39 UTC
Timeout code revisited
Hello all,
After sitting down and looking at the timeout code and the send_fd()
procedure I've come up with a quick fix that seems to correct the
problems my site was exhibiting.
The symptom that was showing up was that web users with modems were
getting their downloads of large files interrupted. The problem turned
out to be that the default_handler() procedure sets a timeout and then
starts sending the file with send_fd(). send_fd() never updates the
timer, so that the timeout kicks in and the transfer is aborted no matter
what after the default timeout number of seconds. Apache ships with a
Timeout value of 400 seconds in httpd.conf and so anything that takes
longer than that to transfer will be interrupted.
The correct thing to do, in my opinion, is to use the timeout mechanism
to abort a connection after Timeout seconds of inactivity, not after
Timeout seconds of sending. I have modified send_fd() in http_protocol.c
and had to make one change in http_main.c to get this to compile.
In http_main.c I changed the declaration of timeout_name from
static char *timeout_name;
to
char *timeout_name;
This is because gcc wouldn't let me put
extern char *timeout_name;
in send_fd() while the 'static' was still on the declaration in http_main.c.
In http_protocol.c I changed send_fd() to the new version below:
long send_fd(FILE *f, request_rec *r)
{
char buf[IOBUFSIZE];
long total_bytes_sent;
register int n,o,w;
conn_rec *c = r->connection;
extern char *timeout_name;
total_bytes_sent = 0;
while (!r->connection->aborted) {
while ((n= fread(buf, sizeof(char), IOBUFSIZE, f)) < 1
&& ferror(f) && errno == EINTR)
continue;
if (n < 1) {
break;
}
o=0;
if (r->bytes_sent != -1) r->bytes_sent += n;
total_bytes_sent += n;
if (timeout_name) /* there is a timeout pending */
while(n && !r->connection->aborted) {
w=fwrite(&buf[o],sizeof(char),n,c->client);
if (w)
alarm(r->server->timeout); /* reset timeout timer */
n-=w;
o+=w;
}
else
while(n && !r->connection->aborted) {
w=fwrite(&buf[o],sizeof(char),n,c->client);
n-=w;
o+=w;
}
}
fflush(c->client);
return total_bytes_sent;
}
This send_fd() checks to see if there is an timeout active, and if so, it
resets the timeot counter every time there is a successful write to the
network.
This fixes the problems we were experiencing, and we haven't found that
it causes anything to break. Any thoughts on this and whether its a good
or bad thing? Perhaps it could be included in a future release?
Nathan
--
Nathan Schrenk nschrenk@neog.com
Neoglyphics Media Corp. http://www.neog.com/
Re: Timeout code revisited
Posted by Brian Behlendorf <br...@organic.com>.
On Wed, 3 Jan 1996, Nathan Schrenk wrote:
> After sitting down and looking at the timeout code and the send_fd()
> procedure I've come up with a quick fix that seems to correct the
> problems my site was exhibiting.
Woohoo!
Think you could formulate this into a patch file? Thanks.
I would classify this as a bug, so the fix could appear in 1.0.2.
Brian
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
brian@organic.com brian@hyperreal.com http://www.[hyperreal,organic].com/