fielding 97/04/05 23:43:51
Modified: src CHANGES http_main.c http_protocol.c http_core.c
mod_asis.c mod_cgi.c mod_dir.c mod_imap.c
mod_include.c mod_info.c mod_status.c
src/modules/proxy proxy_cache.c proxy_ftp.c proxy_http.c
proxy_util.c
Log:
Using a single handler for both timeouts and SIGPIPEs is a really bad idea,
but I didn't change that part. Calling shutdown is unreliable, so we avoid
it when possible. Using soft_timeout requires that the sender check for an
aborted connection rather than continuing after an EINTR, which was almost
never the case. Timeouts that used to be initiated before send_http_header
(and never killed) are now initiated only within or around the routines that
actually do the sending, and not allowed to propagate above the caller.
Reviewed by: Chuck Murcko, Jim Jagielski
Revision Changes Path
1.221 +6 -1 apache/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache/src/CHANGES,v
retrieving revision 1.220
retrieving revision 1.221
diff -C3 -r1.220 -r1.221
*** CHANGES 1997/04/05 06:09:51 1.220
--- CHANGES 1997/04/06 07:43:38 1.221
***************
*** 47,53 ****
*) Added missing timeouts for sending header fields, error responses,
and the last chunk of chunked encoding, each of which could have
! resulted in a process being stuck in write forever. [Roy Fielding]
*) mod_auth_anon required an @ or a . in the email address, not both.
[Dirk vanGulik]
--- 47,58 ----
*) Added missing timeouts for sending header fields, error responses,
and the last chunk of chunked encoding, each of which could have
! resulted in a process being stuck in write forever. Using soft_timeout
! requires that the sender check for an aborted connection rather than
! continuing after an EINTR. Timeouts that used to be initiated before
! send_http_header (and never killed) are now initiated only within or
! around the routines that actually do the sending, and not allowed to
! propagate above the caller. [Roy Fielding]
*) mod_auth_anon required an @ or a . in the email address, not both.
[Dirk vanGulik]
1.134 +8 -17 apache/src/http_main.c
Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_main.c,v
retrieving revision 1.133
retrieving revision 1.134
diff -C3 -r1.133 -r1.134
*** http_main.c 1997/03/22 23:51:02 1.133
--- http_main.c 1997/04/06 07:43:39 1.134
***************
*** 420,427 ****
static int alarms_blocked = 0;
static int alarm_pending = 0;
- void abort_connection (conn_rec *);
-
void timeout(sig) /* Also called on SIGPIPE */
int sig;
{
--- 420,425 ----
***************
*** 473,478 ****
--- 471,478 ----
if (!current_conn->keptalive)
log_transaction(log_req);
+ if (sig == SIGPIPE)
+ bsetflag(timeout_req->connection->client, B_EOUT, 1);
bclose(timeout_req->connection->client);
if (!standalone) exit(0);
***************
*** 482,489 ****
siglongjmp(jmpbuffer,1);
#endif
}
! else {
! abort_connection (current_conn);
}
}
--- 482,493 ----
siglongjmp(jmpbuffer,1);
#endif
}
! else { /* abort the connection */
! if (sig == SIGPIPE)
! bsetflag(current_conn->client, B_EOUT, 1);
! else
! bflush(current_conn->client);
! current_conn->aborted = 1;
}
}
***************
*** 1233,1239 ****
#else
kill(-pgrp,SIGKILL);
#endif
- shutdown(sd,2);
close(sd);
exit(1);
}
--- 1237,1242 ----
***************
*** 1521,1534 ****
}
}
- void abort_connection (conn_rec *c)
- {
- /* Make sure further I/O DOES NOT HAPPEN */
- shutdown (c->client->fd, 2);
- signal (SIGPIPE, SIG_IGN); /* Ignore further complaints */
- c->aborted = 1;
- }
-
conn_rec *new_connection (pool *p, server_rec *server, BUFF *inout,
const struct sockaddr_in *remaddr,
const struct sockaddr_in *saddr,
--- 1524,1529 ----
***************
*** 1809,1818 ****
lingering_close(r);
}
else {
- /* if the connection was aborted by a soft_timeout, it has
- * already been shutdown() so we don't need to go through
- * lingering_close
- */
bsetflag(conn_io, B_EOUT, 1);
bclose(conn_io);
}
--- 1804,1809 ----
1.111 +10 -8 apache/src/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.110
retrieving revision 1.111
diff -C3 -r1.110 -r1.111
*** http_protocol.c 1997/03/20 23:30:50 1.110
--- http_protocol.c 1997/04/06 07:43:39 1.111
***************
*** 1079,1085 ****
/* Get the original request */
while (r->prev) r = r->prev;
! soft_timeout ("send TRACE", r);
r->content_type = "message/http";
send_http_header(r);
--- 1079,1085 ----
/* Get the original request */
while (r->prev) r = r->prev;
! hard_timeout("send TRACE", r);
r->content_type = "message/http";
send_http_header(r);
***************
*** 1102,1108 ****
if (r->assbackwards) return DECLINED;
! soft_timeout("send OPTIONS", r);
basic_http_header(r);
--- 1102,1108 ----
if (r->assbackwards) return DECLINED;
! hard_timeout("send OPTIONS", r);
basic_http_header(r);
***************
*** 1156,1162 ****
*/
r->headers_out=overlay_tables(r->pool, r->err_headers_out,
r->headers_out);
! soft_timeout("send headers", r);
basic_http_header(r);
--- 1156,1162 ----
*/
r->headers_out=overlay_tables(r->pool, r->err_headers_out,
r->headers_out);
! hard_timeout("send headers", r);
basic_http_header(r);
***************
*** 1221,1227 ****
/* Turn off chunked encoding */
if (r->chunked) {
! soft_timeout("send ending chunk", r);
bsetflag(r->connection->client, B_CHUNK, 0);
bputs("0\015\012", r->connection->client);
/* If we had footer "headers", we'd send them now */
--- 1221,1227 ----
/* Turn off chunked encoding */
if (r->chunked) {
! hard_timeout("send ending chunk", r);
bsetflag(r->connection->client, B_CHUNK, 0);
bputs("0\015\012", r->connection->client);
/* If we had footer "headers", we'd send them now */
***************
*** 1485,1497 ****
long send_fd_length(FILE *f, request_rec *r, long length)
{
char buf[IOBUFSIZE];
! long total_bytes_sent;
register int n, w, o, len;
conn_rec *c = r->connection;
if (length == 0) return 0;
! total_bytes_sent = 0;
while (!r->connection->aborted) {
if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
len = length - total_bytes_sent;
--- 1485,1498 ----
long send_fd_length(FILE *f, request_rec *r, long length)
{
char buf[IOBUFSIZE];
! long total_bytes_sent = 0;
register int n, w, o, len;
conn_rec *c = r->connection;
if (length == 0) return 0;
! soft_timeout("send body", r);
!
while (!r->connection->aborted) {
if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
len = length - total_bytes_sent;
***************
*** 1517,1522 ****
--- 1518,1524 ----
}
}
+ kill_timeout(r);
SET_BYTES_SENT(r);
return total_bytes_sent;
}
***************
*** 1609,1615 ****
if (status == HTTP_NOT_MODIFIED) {
r->headers_out = overlay_tables(r->pool, r->err_headers_out,
r->headers_out);
! soft_timeout("send 304", r);
basic_http_header(r);
set_keepalive(r);
--- 1611,1617 ----
if (status == HTTP_NOT_MODIFIED) {
r->headers_out = overlay_tables(r->pool, r->err_headers_out,
r->headers_out);
! hard_timeout("send 304", r);
basic_http_header(r);
set_keepalive(r);
***************
*** 1647,1653 ****
}
}
! soft_timeout("send error body", r);
if ((custom_response = response_code_string (r, idx))) {
/*
--- 1649,1655 ----
}
}
! hard_timeout("send error body", r);
if ((custom_response = response_code_string (r, idx))) {
/*
1.76 +0 -2 apache/src/http_core.c
Index: http_core.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.c,v
retrieving revision 1.75
retrieving revision 1.76
diff -C3 -r1.75 -r1.76
*** http_core.c 1997/04/01 05:00:19 1.75
--- http_core.c 1997/04/06 07:43:40 1.76
***************
*** 1333,1340 ****
table_set (r->headers_out, "Content-MD5", md5digest(r->pool, f));
}
- soft_timeout ("send", r);
-
rangestatus = set_byterange(r);
send_http_header (r);
--- 1333,1338 ----
1.13 +0 -1 apache/src/mod_asis.c
Index: mod_asis.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_asis.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -C3 -r1.12 -r1.13
*** mod_asis.c 1997/03/07 14:15:37 1.12
--- mod_asis.c 1997/04/06 07:43:40 1.13
***************
*** 97,103 ****
return OK;
}
- soft_timeout ("send", r);
send_http_header (r);
if (!r->header_only) send_fd (f, r);
--- 97,102 ----
1.37 +9 -5 apache/src/mod_cgi.c
Index: mod_cgi.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -C3 -r1.36 -r1.37
*** mod_cgi.c 1997/04/01 06:17:52 1.36
--- mod_cgi.c 1997/04/06 07:43:40 1.37
***************
*** 518,530 ****
return REDIRECT;
}
- hard_timeout ("send script output", r);
send_http_header(r);
! if(!r->header_only) send_fd (script_in, r);
/* Soak up stderr */
! while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err) != NULL)
! continue;
! kill_timeout (r);
pfclose (r->main ? r->main->pool : r->pool, script_in);
pfclose (r->main ? r->main->pool : r->pool, script_err);
}
--- 518,534 ----
return REDIRECT;
}
send_http_header(r);
! if (!r->header_only)
! send_fd(script_in, r);
!
/* Soak up stderr */
! soft_timeout("soaking script stderr", r);
! while ((fgets(argsbuffer, HUGE_STRING_LEN-1, script_err) != NULL) &&
! !r->connection->aborted)
! continue;
! kill_timeout(r);
!
pfclose (r->main ? r->main->pool : r->pool, script_in);
pfclose (r->main ? r->main->pool : r->pool, script_err);
}
1.24 +3 -1 apache/src/mod_dir.c
Index: mod_dir.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_dir.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -C3 -r1.23 -r1.24
*** mod_dir.c 1997/03/07 14:15:39 1.23
--- mod_dir.c 1997/04/06 07:43:41 1.24
***************
*** 700,712 ****
r->content_type = "text/html";
- soft_timeout ("send directory", r);
send_http_header(r);
if (r->header_only) {
closedir (d);
return 0;
}
/* Spew HTML preamble */
--- 700,712 ----
r->content_type = "text/html";
send_http_header(r);
if (r->header_only) {
closedir (d);
return 0;
}
+ hard_timeout("send directory", r);
/* Spew HTML preamble */
***************
*** 766,771 ****
--- 766,773 ----
}
rputs ("</BODY></HTML>\n", r);
+
+ kill_timeout(r);
return 0;
}
1.20 +11 -24 apache/src/mod_imap.c
Index: mod_imap.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_imap.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -C3 -r1.19 -r1.20
*** mod_imap.c 1997/03/07 14:15:41 1.19
--- mod_imap.c 1997/04/06 07:43:41 1.20
***************
*** 500,509 ****
return SERVER_ERROR; /* they actually requested an error! */
}
if ( ! strcasecmp(redirect, "nocontent") ) {
! r->status_line = pstrdup(r->pool, "204 No Content");
! soft_timeout ("send no content", r);
! send_http_header(r);
! return OK; /* tell the client to keep the page it has */
}
if (redirect && *redirect ) {
table_set(r->headers_out, "Location", redirect);
--- 500,506 ----
return SERVER_ERROR; /* they actually requested an error! */
}
if ( ! strcasecmp(redirect, "nocontent") ) {
! return HTTP_NO_CONTENT; /* tell the client to keep the page it has */
}
if (redirect && *redirect ) {
table_set(r->headers_out, "Location", redirect);
***************
*** 514,541 ****
void menu_header(request_rec *r, char *menu)
{
! if (! strcasecmp(menu, "formatted")) {
! r->content_type = "text/html";
! soft_timeout ("send menu", r);
! send_http_header(r);
! rvputs(r, "<html>\n<head><title>Menu for ", r->uri,
! "</title></head>\n\n<body>\n", NULL);
rvputs(r, "<h1>Menu for ", r->uri, "</h1>\n<hr>\n\n", NULL);
}
! if (! strcasecmp(menu, "semiformatted")) {
! r->content_type = "text/html";
! soft_timeout ("send menu", r);
! send_http_header(r);
! rvputs(r, "<html>\n<head><title>Menu for ", r->uri,
! "</title></head>\n\n<body>\n", NULL);
! }
! if (! strcasecmp(menu, "unformatted")) {
! r->content_type = "text/html";
! soft_timeout ("send menu", r);
! send_http_header(r);
! rvputs(r, "<html>\n<head><title>Menu for ", r->uri,
! "</title></head>\n\n<body>\n", NULL);
! }
return;
}
--- 511,527 ----
void menu_header(request_rec *r, char *menu)
{
! r->content_type = "text/html";
! send_http_header(r);
! hard_timeout("send menu", r); /* killed in menu_footer */
!
! rvputs(r, "<html><head>\n<title>Menu for ", r->uri,
! "</title>\n</head><body>\n", NULL);
!
! if (!strcasecmp(menu, "formatted")) {
rvputs(r, "<h1>Menu for ", r->uri, "</h1>\n<hr>\n\n", NULL);
}
!
return;
}
***************
*** 608,613 ****
--- 594,600 ----
void menu_footer(request_rec *r)
{
rputs("\n\n</body>\n</html>\n", r); /* finish the menu */
+ kill_timeout(r);
}
int imap_handler(request_rec *r)
1.28 +2 -3 apache/src/mod_include.c
Index: mod_include.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_include.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -C3 -r1.27 -r1.28
*** mod_include.c 1997/03/07 14:15:41 1.27
--- mod_include.c 1997/04/06 07:43:41 1.28
***************
*** 1752,1762 ****
return FORBIDDEN;
}
- hard_timeout ("send", r);
send_http_header(r);
if (r->header_only) {
- kill_timeout (r);
pfclose (r->pool, f);
return OK;
}
--- 1752,1760 ----
***************
*** 1775,1781 ****
add_cgi_vars(r);
add_include_vars (r, DEFAULT_TIME_FORMAT);
}
!
send_parsed_content (f, r);
kill_timeout (r);
--- 1773,1780 ----
add_cgi_vars(r);
add_include_vars (r, DEFAULT_TIME_FORMAT);
}
! hard_timeout("send SSI", r);
!
send_parsed_content (f, r);
kill_timeout (r);
1.15 +2 -2 apache/src/mod_info.c
Index: mod_info.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_info.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -C3 -r1.14 -r1.15
*** mod_info.c 1997/03/07 14:15:41 1.14
--- mod_info.c 1997/04/06 07:43:42 1.15
***************
*** 277,289 ****
extern char server_root[MAX_STRING_LEN];
extern char server_confname[MAX_STRING_LEN];
- /* Init timeout */
- soft_timeout ("send server info", r);
r->content_type = "text/html";
send_http_header(r);
if(r->header_only) {
return 0;
}
rputs("<html><head><title>Server Information</title></head>\n",r);
rputs("<body><h1 align=center>Apache Server Information</h1>\n",r);
--- 277,288 ----
extern char server_root[MAX_STRING_LEN];
extern char server_confname[MAX_STRING_LEN];
r->content_type = "text/html";
send_http_header(r);
if(r->header_only) {
return 0;
}
+ hard_timeout("send server info", r);
rputs("<html><head><title>Server Information</title></head>\n",r);
rputs("<body><h1 align=center>Apache Server Information</h1>\n",r);
***************
*** 418,423 ****
--- 417,423 ----
}
rputs("</dl></body></html>\n",r);
/* Done, turn off timeout, close file and return */
+ kill_timeout(r);
return 0;
}
1.45 +4 -1 apache/src/mod_status.c
Index: mod_status.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_status.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -C3 -r1.44 -r1.45
*** mod_status.c 1997/03/07 14:15:43 1.44
--- mod_status.c 1997/04/06 07:43:42 1.45
***************
*** 264,270 ****
}
}
- soft_timeout ("send status info", r);
send_http_header(r);
if (r->header_only)
--- 264,269 ----
***************
*** 304,309 ****
--- 303,310 ----
up_time=nowtime-restart_time;
+ hard_timeout("send status info", r);
+
if (!short_report)
{
rputs("<HTML><HEAD>\n<TITLE>Apache
Status</TITLE>\n</HEAD><BODY>\n",r);
***************
*** 586,591 ****
--- 587,594 ----
if (!short_report)
rputs("</BODY></HTML>\n",r);
+
+ kill_timeout(r);
return 0;
}
1.12 +8 -4 apache/src/modules/proxy/proxy_cache.c
Index: proxy_cache.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_cache.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C3 -r1.11 -r1.12
*** proxy_cache.c 1997/04/05 06:08:23 1.11
--- proxy_cache.c 1997/04/06 07:43:48 1.12
***************
*** 526,534 ****
Explain0("Local copy modified, send it");
r->status_line = strchr(c->resp_line, ' ') + 1;
r->status = c->status;
! soft_timeout ("send", r);
! if (!r->assbackwards)
proxy_send_headers(r->connection->client, c->resp_line, c->hdrs);
bsetopt(r->connection->client, BO_BYTECT, &zero);
r->sent_bodyct = 1;
if (!r->header_only) proxy_send_fb (cachefp, r, NULL, NULL);
--- 526,536 ----
Explain0("Local copy modified, send it");
r->status_line = strchr(c->resp_line, ' ') + 1;
r->status = c->status;
! if (!r->assbackwards) {
! soft_timeout("proxy send headers", r);
proxy_send_headers(r->connection->client, c->resp_line, c->hdrs);
+ kill_timeout(r);
+ }
bsetopt(r->connection->client, BO_BYTECT, &zero);
r->sent_bodyct = 1;
if (!r->header_only) proxy_send_fb (cachefp, r, NULL, NULL);
***************
*** 754,763 ****
Explain0("Remote document updated, sending");
r->status_line = strchr(c->resp_line, ' ') + 1;
r->status = c->status;
! soft_timeout ("send", r);
! if (!r->assbackwards)
proxy_send_headers(r->connection->client, c->resp_line,
c->hdrs);
bsetopt(r->connection->client, BO_BYTECT, &zero);
r->sent_bodyct = 1;
if (!r->header_only) proxy_send_fb (c->fp, r, NULL, NULL);
--- 756,767 ----
Explain0("Remote document updated, sending");
r->status_line = strchr(c->resp_line, ' ') + 1;
r->status = c->status;
! if (!r->assbackwards) {
! soft_timeout("proxy send headers", r);
proxy_send_headers(r->connection->client, c->resp_line,
c->hdrs);
+ kill_timeout(r);
+ }
bsetopt(r->connection->client, BO_BYTECT, &zero);
r->sent_bodyct = 1;
if (!r->header_only) proxy_send_fb (c->fp, r, NULL, NULL);
1.13 +97 -26 apache/src/modules/proxy/proxy_ftp.c
Index: proxy_ftp.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_ftp.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -C3 -r1.12 -r1.13
*** proxy_ftp.c 1997/03/20 18:40:15 1.12
--- proxy_ftp.c 1997/04/06 07:43:48 1.13
***************
*** 470,477 ****
hard_timeout ("proxy ftp", r);
i = ftp_getrc(f);
Explain1("FTP: returned status %d", i);
! if (i == -1) return proxyerror(r, "Error reading from remote server");
! if (i != 220) return BAD_GATEWAY;
Explain0("FTP: connected.");
--- 470,483 ----
hard_timeout ("proxy ftp", r);
i = ftp_getrc(f);
Explain1("FTP: returned status %d", i);
! if (i == -1) {
! kill_timeout(r);
! return proxyerror(r, "Error reading from remote server");
! }
! if (i != 220) {
! kill_timeout(r);
! return BAD_GATEWAY;
! }
Explain0("FTP: connected.");
***************
*** 485,493 ****
/* states: 1 - error, 2 - success; 3 - send password, 4,5 fail */
i = ftp_getrc(f);
Explain1("FTP: returned status %d",i);
! if (i == -1) return proxyerror(r, "Error sending to remote server");
! if (i == 530) return proxyerror(r, "Not logged in");
! else if (i != 230 && i != 331) return BAD_GATEWAY;
if (i == 331) /* send password */
{
--- 491,508 ----
/* states: 1 - error, 2 - success; 3 - send password, 4,5 fail */
i = ftp_getrc(f);
Explain1("FTP: returned status %d",i);
! if (i == -1) {
! kill_timeout(r);
! return proxyerror(r, "Error sending to remote server");
! }
! if (i == 530) {
! kill_timeout(r);
! return proxyerror(r, "Not logged in");
! }
! if (i != 230 && i != 331) {
! kill_timeout(r);
! return BAD_GATEWAY;
! }
if (i == 331) /* send password */
{
***************
*** 500,509 ****
/* possible results 202, 230, 332, 421, 500, 501, 503, 530 */
i = ftp_getrc(f);
Explain1("FTP: returned status %d",i);
! if (i == -1) return proxyerror(r, "Error sending to remote server");
! if (i == 332) return proxyerror(r, "Need account for login");
! else if (i == 530) return proxyerror(r, "Not logged in");
! else if (i != 230 && i != 202) return BAD_GATEWAY;
}
/* set the directory */
--- 515,536 ----
/* possible results 202, 230, 332, 421, 500, 501, 503, 530 */
i = ftp_getrc(f);
Explain1("FTP: returned status %d",i);
! if (i == -1) {
! kill_timeout(r);
! return proxyerror(r, "Error sending to remote server");
! }
! if (i == 332) {
! kill_timeout(r);
! return proxyerror(r, "Need account for login");
! }
! if (i == 530) {
! kill_timeout(r);
! return proxyerror(r, "Not logged in");
! }
! if (i != 230 && i != 202) {
! kill_timeout(r);
! return BAD_GATEWAY;
! }
}
/* set the directory */
***************
*** 526,534 ****
/* 1,3 error, 2 success, 4,5 failure */
i = ftp_getrc(f);
Explain1("FTP: returned status %d",i);
! if (i == -1) return proxyerror(r, "Error sending to remote server");
! else if (i == 550) return NOT_FOUND;
! else if (i != 250) return BAD_GATEWAY;
path = p + 1;
}
--- 553,570 ----
/* 1,3 error, 2 success, 4,5 failure */
i = ftp_getrc(f);
Explain1("FTP: returned status %d",i);
! if (i == -1) {
! kill_timeout(r);
! return proxyerror(r, "Error sending to remote server");
! }
! if (i == 550) {
! kill_timeout(r);
! return NOT_FOUND;
! }
! if (i != 250) {
! kill_timeout(r);
! return BAD_GATEWAY;
! }
path = p + 1;
}
***************
*** 554,563 ****
/* responses: 200, 421, 500, 501, 504, 530 */
i = ftp_getrc(f);
Explain1("FTP: returned status %d",i);
! if (i == -1) return proxyerror(r, "Error sending to remote server");
! else if (i != 200 && i != 504) return BAD_GATEWAY;
/* Allow not implemented */
! else if (i == 504) parms[0] = '\0';
}
/* try to set up PASV data connection first */
--- 590,606 ----
/* responses: 200, 421, 500, 501, 504, 530 */
i = ftp_getrc(f);
Explain1("FTP: returned status %d",i);
! if (i == -1) {
! kill_timeout(r);
! return proxyerror(r, "Error sending to remote server");
! }
! if (i != 200 && i != 504) {
! kill_timeout(r);
! return BAD_GATEWAY;
! }
/* Allow not implemented */
! if (i == 504)
! parms[0] = '\0';
}
/* try to set up PASV data connection first */
***************
*** 567,572 ****
--- 610,616 ----
proxy_log_uerror("socket", NULL, "proxy: error creating PASV socket",
r->server);
pclosef(pool, sock);
+ kill_timeout(r);
return SERVER_ERROR;
}
note_cleanups_for_fd(pool, dsock);
***************
*** 583,588 ****
--- 627,633 ----
r->server);
pclosef(pool, dsock);
pclosef(pool, sock);
+ kill_timeout(r);
return SERVER_ERROR;
} else
{
***************
*** 613,622 ****
data_addr.sin_port = htons(pport);
i = proxy_doconnect(dsock, &data_addr, r);
! if (i == -1)
return proxyerror(r, "Could not connect to remote machine");
! else
! {
data = bcreate(pool, B_RDWR);
bpushfd(data, dsock, dsock);
pasvmode = 1;
--- 658,668 ----
data_addr.sin_port = htons(pport);
i = proxy_doconnect(dsock, &data_addr, r);
! if (i == -1) {
! kill_timeout(r);
return proxyerror(r, "Could not connect to remote machine");
! }
! else {
data = bcreate(pool, B_RDWR);
bpushfd(data, dsock, dsock);
pasvmode = 1;
***************
*** 633,638 ****
--- 679,685 ----
proxy_log_uerror("getsockname", NULL,
"proxy: error getting socket address", r->server);
pclosef(pool, sock);
+ kill_timeout(r);
return SERVER_ERROR;
}
***************
*** 642,647 ****
--- 689,695 ----
proxy_log_uerror("socket", NULL, "proxy: error creating socket",
r->server);
pclosef(pool, sock);
+ kill_timeout(r);
return SERVER_ERROR;
}
note_cleanups_for_fd(pool, dsock);
***************
*** 653,658 ****
--- 701,707 ----
"proxy: error setting reuseaddr option", r->server);
pclosef(pool, dsock);
pclosef(pool, sock);
+ kill_timeout(r);
return SERVER_ERROR;
}
***************
*** 700,708 ****
Explain1("FTP: CWD %s",path);
i = ftp_getrc(f);
Explain1("FTP: returned status %d", i);
! if (i == -1) return proxyerror(r, "Error sending to remote
server");
! else if (i == 550) return NOT_FOUND;
! else if (i != 250) return BAD_GATEWAY;
path=""; len=0;
}
}
--- 749,766 ----
Explain1("FTP: CWD %s",path);
i = ftp_getrc(f);
Explain1("FTP: returned status %d", i);
! if (i == -1) {
! kill_timeout(r);
! return proxyerror(r, "Error sending to remote server");
! }
! if (i == 550) {
! kill_timeout(r);
! return NOT_FOUND;
! }
! if (i != 250) {
! kill_timeout(r);
! return BAD_GATEWAY;
! }
path=""; len=0;
}
}
***************
*** 726,732 ****
NLST: 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 502, 530 */
rc = ftp_getrc(f);
Explain1("FTP: returned status %d",rc);
! if (rc == -1) return proxyerror(r, "Error sending to remote server");
if (rc == 550)
{
Explain0("FTP: RETR failed, trying LIST instead");
--- 784,793 ----
NLST: 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 502, 530 */
rc = ftp_getrc(f);
Explain1("FTP: returned status %d",rc);
! if (rc == -1) {
! kill_timeout(r);
! return proxyerror(r, "Error sending to remote server");
! }
if (rc == 550)
{
Explain0("FTP: RETR failed, trying LIST instead");
***************
*** 738,746 ****
Explain1("FTP: CWD %s", path);
rc = ftp_getrc(f);
Explain1("FTP: returned status %d", rc);
! if (rc == -1) return proxyerror(r, "Error sending to remote server");
! if (rc == 550) return NOT_FOUND;
! if (rc != 250) return BAD_GATEWAY;
bputs("LIST -lag\015\012", f);
bflush(f);
--- 799,816 ----
Explain1("FTP: CWD %s", path);
rc = ftp_getrc(f);
Explain1("FTP: returned status %d", rc);
! if (rc == -1) {
! kill_timeout(r);
! return proxyerror(r, "Error sending to remote server");
! }
! if (rc == 550) {
! kill_timeout(r);
! return NOT_FOUND;
! }
! if (rc != 250) {
! kill_timeout(r);
! return BAD_GATEWAY;
! }
bputs("LIST -lag\015\012", f);
bflush(f);
***************
*** 749,756 ****
Explain1("FTP: returned status %d", rc);
if (rc == -1) return proxyerror(r, "Error sending to remote server");
}
- if (rc != 125 && rc != 150 && rc != 226 && rc != 250) return
BAD_GATEWAY;
kill_timeout(r);
r->status = 200;
r->status_line = "200 OK";
--- 819,826 ----
Explain1("FTP: returned status %d", rc);
if (rc == -1) return proxyerror(r, "Error sending to remote server");
}
kill_timeout(r);
+ if (rc != 125 && rc != 150 && rc != 226 && rc != 250) return
BAD_GATEWAY;
r->status = 200;
r->status_line = "200 OK";
***************
*** 802,807 ****
--- 872,878 ----
"proxy: failed to accept data connection", r->server);
pclosef(pool, dsock);
pclosef(pool, sock);
+ kill_timeout(r);
proxy_cache_error(c);
return BAD_GATEWAY;
}
1.16 +3 -0 apache/src/modules/proxy/proxy_http.c
Index: proxy_http.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_http.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -C3 -r1.15 -r1.16
*** proxy_http.c 1997/03/20 18:40:15 1.15
--- proxy_http.c 1997/04/06 07:43:49 1.16
***************
*** 272,277 ****
--- 272,278 ----
if (len == -1 || len == 0)
{
pclosef(pool, sock);
+ kill_timeout(r);
return proxyerror(r, "Error reading from remote server");
}
***************
*** 282,287 ****
--- 283,289 ----
if (buffer[5] != '1' || buffer[len-1] != '\n')
{
pclosef(pool, sock);
+ kill_timeout(r);
return BAD_GATEWAY;
}
buffer[--len] = '\0';
***************
*** 385,390 ****
--- 387,393 ----
if (cache != NULL)
if (bwrite(f, buffer, len) != len) cache = proxy_cache_error(c);
}
+ kill_timeout(r);
/* send body */
/* if header only, then cache will be NULL */
1.9 +14 -5 apache/src/modules/proxy/proxy_util.c
Index: proxy_util.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_util.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -C3 -r1.8 -r1.9
*** proxy_util.c 1997/03/20 18:40:16 1.8
--- proxy_util.c 1997/04/06 07:43:49 1.9
***************
*** 303,309 ****
}
/*
! * Reads headers from a connection and returns an array of headers.
* Returns NULL on file error
*/
array_header *
--- 303,309 ----
}
/*
! * Reads headers from a buffer and returns an array of headers.
* Returns NULL on file error
*/
array_header *
***************
*** 392,397 ****
--- 392,399 ----
conn_rec *con = r->connection;
total_bytes_sent = 0;
+ soft_timeout("proxy send body", r);
+
while (!con->aborted) {
n = bread(f, buf, IOBUFSIZE);
if (n == -1) /* input error */
***************
*** 406,412 ****
if (f2 != NULL)
if (bwrite(f2, buf, n) != n) f2 = proxy_cache_error(c);
! while(n && !r->connection->aborted) {
w = bwrite(con->client, &buf[o], n);
if (w <= 0) {
if (f2 != NULL) {
--- 408,414 ----
if (f2 != NULL)
if (bwrite(f2, buf, n) != n) f2 = proxy_cache_error(c);
! while(n && !con->aborted) {
w = bwrite(con->client, &buf[o], n);
if (w <= 0) {
if (f2 != NULL) {
***************
*** 416,428 ****
}
break;
}
! reset_timeout(r); /* reset timeout after successfule write */
n-=w;
o+=w;
}
}
! bflush(con->client);
return total_bytes_sent;
}
--- 418,432 ----
}
break;
}
! reset_timeout(r); /* reset timeout after successful write */
n-=w;
o+=w;
}
}
! if (!con->aborted)
! bflush(con->client);
+ kill_timeout(r);
return total_bytes_sent;
}
***************
*** 486,491 ****
--- 490,496 ----
/*
* Sends response line and headers
+ * A timeout should be set before calling this routine.
*/
void
proxy_send_headers(BUFF *fp, const char *respline, array_header *hdrs_arr)
***************
*** 669,679 ****
--- 674,688 ----
r->content_type = "text/html";
send_http_header(r);
+ soft_timeout("proxy error", r);
+
rvputs(r, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\015\012\
<html><head><title>Proxy Error</title><head>\015\012<body><h1>Proxy Error\
</h1>\015\012The proxy server could not handle this request.\
\015\012<p>\015\012Reason: <b>", message,
"</b>\015\012</body><html>\015\012",
NULL);
+
+ kill_timeout(r);
return OK;
}
***************
*** 711,717 ****
{
int i;
! hard_timeout ("proxy connect", r);
do i = connect(sock, (struct sockaddr *)addr, sizeof(struct
sockaddr_in));
while (i == -1 && errno == EINTR);
if (i == -1) proxy_log_uerror("connect", NULL, NULL, r->server);
--- 720,726 ----
{
int i;
! hard_timeout("proxy connect", r);
do i = connect(sock, (struct sockaddr *)addr, sizeof(struct
sockaddr_in));
while (i == -1 && errno == EINTR);
if (i == -1) proxy_log_uerror("connect", NULL, NULL, r->server);