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);