cvs commit: apache-2.0/src/main http_protocol.c http_request.c
rbb 00/01/12 10:20:45 Modified:src/main http_protocol.c http_request.c Log: Fix some remaining problems with SSI's and Windows. Basically, the sendfile stuff doesn't work properly with chuncked data. Submitted by: Allan Edwards Reviewed by: Ryan Bloom Revision ChangesPath 1.47 +14 -9 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.46 retrieving revision 1.47 diff -u -r1.46 -r1.47 --- http_protocol.c 2000/01/09 05:18:23 1.46 +++ http_protocol.c 2000/01/12 18:20:43 1.47 @@ -2016,16 +2016,21 @@ { long len; #ifdef HAVE_SENDFILE -ap_bflush(r->connection->client); -if (ap_get_filesize(&len, fd) != APR_SUCCESS) { -ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, - "ap_send_fd: ap_get_filesize failed."); -return 0; +if (!r->chunked) { +ap_bflush(r->connection->client); +if (ap_get_filesize(&len, fd) != APR_SUCCESS) { +ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, + "ap_send_fd: ap_get_filesize failed."); +return 0; +} +if (iol_sendfile(r->connection->client->iol, fd, len, + NULL, 0, 0) != APR_SUCCESS) { +ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, + "ap_send_fd: iol_sendfile failed."); +} } -if (iol_sendfile(r->connection->client->iol, fd, len, - NULL, 0, 0) != APR_SUCCESS) { -ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, - "ap_send_fd: iol_sendfile failed."); +else { +len = ap_send_fd_length(fd, r, -1); } #else len = ap_send_fd_length(fd, r, -1); 1.16 +1 -0 apache-2.0/src/main/http_request.c Index: http_request.c === RCS file: /home/cvs/apache-2.0/src/main/http_request.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- http_request.c2000/01/10 15:35:49 1.15 +++ http_request.c2000/01/12 18:20:43 1.16 @@ -845,6 +845,7 @@ rnew->server = r->server; rnew->request_config = ap_create_request_config(rnew->pool); rnew->htaccess = r->htaccess; +rnew->chunked= r->chunked; ap_set_sub_req_protocol(rnew, r); fdir = ap_make_dirstr_parent(rnew->pool, r->filename);
cvs commit: apache-2.0/src/main http_protocol.c
rbb 99/12/21 08:21:44 Modified:src/lib/apr/include apr_time.h src/lib/apr/time/unix timestr.c src/main http_protocol.c Log: Change ap_gm_timestr_822 to ap_timestr. Now, one function can be used to get a timestr for GMT and Localtimes. Revision ChangesPath 1.5 +1 -1 apache-2.0/src/lib/apr/include/apr_time.h Index: apr_time.h === RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_time.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- apr_time.h1999/12/20 16:10:11 1.4 +++ apr_time.h1999/12/21 16:21:41 1.5 @@ -76,7 +76,7 @@ ap_status_t ap_explode_time(ap_time_t *, ap_timetype_e); ap_status_t ap_implode_time(ap_time_t *); -ap_status_t ap_gm_timestr_822(char **date_str, struct atime_t *t, ap_context_t *p); +ap_status_t ap_timestr(char **date_str, struct atime_t *t, ap_timetype_e type, ap_context_t *p); ap_status_t ap_strftime(char *s, ap_size_t max, const char *format, ap_time_t *tm); /* accessor functions */ 1.2 +8 -8 apache-2.0/src/lib/apr/time/unix/timestr.c Index: timestr.c === RCS file: /home/cvs/apache-2.0/src/lib/apr/time/unix/timestr.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- timestr.c 1999/12/20 16:10:16 1.1 +++ timestr.c 1999/12/21 16:21:43 1.2 @@ -65,7 +65,7 @@ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; -ap_status_t ap_gm_timestr_822(char **date_str, struct atime_t *t, ap_context_t *p) +ap_status_t ap_timestr(char **date_str, struct atime_t *t, ap_timetype_e type, ap_context_t *p) { struct tm *tms; char *date_str_ptr; @@ -74,9 +74,7 @@ (*date_str) = ap_palloc(p, 48 * sizeof(char)); date_str_ptr = (*date_str); -if (t->time_ex == 0) { -ap_explode_time(t, APR_UTCTIME); -} +ap_explode_time(t, type); /* Assumption: this is always 3 */ /* i = strlen(ap_day_snames[tms->tm_wday]); */ @@ -107,10 +105,12 @@ *date_str_ptr++ = ':'; *date_str_ptr++ = t->explodedtime->tm_sec / 10 + '0'; *date_str_ptr++ = t->explodedtime->tm_sec % 10 + '0'; -*date_str_ptr++ = ' '; -*date_str_ptr++ = 'G'; -*date_str_ptr++ = 'M'; -*date_str_ptr++ = 'T'; +if (type == APR_UTCTIME) { +*date_str_ptr++ = ' '; +*date_str_ptr++ = 'G'; +*date_str_ptr++ = 'M'; +*date_str_ptr++ = 'T'; +} *date_str_ptr = '\0'; return APR_SUCCESS; /* RFC date format; as strftime '%a, %d %b %Y %T GMT' */ 1.44 +3 -3 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.43 retrieving revision 1.44 diff -u -r1.43 -r1.44 --- http_protocol.c 1999/12/21 11:33:22 1.43 +++ http_protocol.c 1999/12/21 16:21:44 1.44 @@ -605,7 +605,7 @@ { ap_time_t *mod_time = ap_rationalize_mtime(r, r->mtime); char *datestr; -ap_gm_timestr_822(&datestr, mod_time, r->pool); +ap_timestr(&datestr, mod_time, APR_UTCTIME, r->pool); ap_table_setn(r->headers_out, "Last-Modified", datestr); } @@ -1362,7 +1362,7 @@ ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL); -ap_gm_timestr_822(&date, r->request_time, r->pool); +ap_timestr(&date, r->request_time, APR_UTCTIME, r->pool); ap_send_header_field(r, "Date", date); ap_send_header_field(r, "Server", ap_get_server_version()); @@ -1645,7 +1645,7 @@ * some other part of the server configuration. */ if (r->no_cache && !ap_table_get(r->headers_out, "Expires")) { -ap_gm_timestr_822(&date, r->request_time, r->pool); +ap_timestr(&date, r->request_time, APR_UTCTIME, r->pool); ap_table_addn(r->headers_out, "Expires", date); }
cvs commit: apache-2.0/src/main http_protocol.c http_vhost.c
fanf99/12/21 03:33:23 Modified:src CHANGES src/main http_protocol.c http_vhost.c Log: Fix the mass vhosting security problem spotted by Lars, as in 1.3 Submitted by: Ben Hyde Reviewed by: Tony Finch Revision ChangesPath 1.19 +5 -0 apache-2.0/src/CHANGES Index: CHANGES === RCS file: /home/cvs/apache-2.0/src/CHANGES,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- CHANGES 1999/12/21 07:54:07 1.18 +++ CHANGES 1999/12/21 11:33:21 1.19 @@ -1,4 +1,9 @@ Changes with Apache 2.0-dev + + *) More rigorous checking of Host: headers to fix security problems + with mass name-based virtual hosting (whether using mod_rewrite + or mod_vhost_alias). + [Ben Hyde, Tony Finch] *) Add back support for UseCanonicalName in containers. [Manoj Kasichainula] 1.43 +3 -1 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- http_protocol.c 1999/12/20 16:38:34 1.42 +++ http_protocol.c 1999/12/21 11:33:22 1.43 @@ -1033,7 +1033,7 @@ r->status = HTTP_OK; /* Until further notice. */ /* update what we think the virtual host is based on the headers we've - * now read + * now read. may update status. */ ap_update_vhost_from_headers(r); @@ -1056,6 +1056,8 @@ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, "client sent HTTP/1.1 request without hostname " "(see RFC2068 section 9, and 14.23): %s", r->uri); +} +if (r->status != HTTP_OK) { ap_send_error_response(r, 0); ap_run_log_transaction(r); return r; 1.10 +41 -10apache-2.0/src/main/http_vhost.c Index: http_vhost.c === RCS file: /home/cvs/apache-2.0/src/main/http_vhost.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- http_vhost.c 1999/12/15 00:59:56 1.9 +++ http_vhost.c 1999/12/21 11:33:23 1.10 @@ -658,22 +658,51 @@ * run-time vhost matching functions */ -/* Remove :port and optionally a single trailing . from the hostname, this - * canonicalizes it somewhat. +/* Lowercase and remove any trailing dot and/or :port from the hostname, + * and check that it is sane. */ static void fix_hostname(request_rec *r) { -const char *hostname = r->hostname; -char *host = ap_getword(r->pool, &hostname, ':');/* get rid of port */ -size_t l; - -/* trim a trailing . */ -l = strlen(host); -if (l > 0 && host[l-1] == '.') { -host[l-1] = '\0'; +char *host = ap_palloc(r->pool, strlen(r->hostname) + 1); +const char *src; +char *dst; + +/* check and copy the host part */ +src = r->hostname; +dst = host; +while (*src) { + if (!isalnum(*src) && *src != '.' && *src != '-') { + if (*src == ':') + break; + else + goto bad; + } else { + *dst++ = *src++; + } +} +/* check the port part */ +if (*src++ == ':') { + while (*src) { + if (!isdigit(*src++)) { + goto bad; + } + } +} +/* strip trailing gubbins */ +if (dst > host && dst[-1] == '.') { + dst[-1] = '\0'; +} else { + dst[0] = '\0'; } r->hostname = host; +return; + +bad: +r->status = HTTP_BAD_REQUEST; +ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, + "Client sent malformed Host header"); +return; } @@ -876,6 +905,8 @@ /* must set this for HTTP/1.1 support */ if (r->hostname || (r->hostname = ap_table_get(r->headers_in, "Host"))) { fix_hostname(r); + if (r->status != HTTP_OK) + return; } /* check if we tucked away a name_chain */ if (r->connection->vhost_lookup_data) {
cvs commit: apache-2.0/src/main http_protocol.c
stoddard99/12/09 13:47:50 Modified:src/main http_protocol.c Log: Fix Windows build break Revision ChangesPath 1.40 +3 -0 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.39 retrieving revision 1.40 diff -u -r1.39 -r1.40 --- http_protocol.c 1999/11/30 03:36:33 1.39 +++ http_protocol.c 1999/12/09 21:47:45 1.40 @@ -2155,6 +2155,8 @@ return total_bytes_sent; } +#ifdef USE_MMAP_FILES + /* The code writes MMAP_SEGMENT_SIZE bytes at a time. This is due to Apache's * timeout model, which is a timeout per-write rather than a time for the * entire transaction to complete. Essentially this should be small enough @@ -2218,6 +2220,7 @@ SET_BYTES_SENT(r); return total_bytes_sent; } +#endif /* USE_MMAP_FILES */ API_EXPORT(int) ap_rputc(int c, request_rec *r) {
cvs commit: apache-2.0/src/main http_protocol.c
manoj 99/11/29 19:36:35 Modified:src/main http_protocol.c Log: The extra (n < 1) check is redundant, leftover from pre-APR code. Revision ChangesPath 1.39 +1 -2 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.38 retrieving revision 1.39 diff -u -d -u -r1.38 -r1.39 --- http_protocol.c 1999/11/20 11:56:13 1.38 +++ http_protocol.c 1999/11/30 03:36:33 1.39 @@ -2045,8 +2045,7 @@ n = o; do { rv = ap_read(fd, buf, &n); -} while (rv == APR_EINTR && !ap_is_aborted(r->connection) && - (n < 1)); +} while (rv == APR_EINTR && !ap_is_aborted(r->connection)); if (n < 1) { break;
cvs commit: apache-2.0/src/main http_protocol.c
bjh 99/11/03 04:47:24 Modified:src/lib/apr/file_io/os2 readwrite.c src/main http_protocol.c Log: OS/2: Don't return APR_EOF from ap_read(). EOF is indicated by a APR_SUCCESS status with nbytes set to 0. Revision ChangesPath 1.6 +10 -15apache-2.0/src/lib/apr/file_io/os2/readwrite.c Index: readwrite.c === RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/readwrite.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- readwrite.c 1999/10/19 15:24:19 1.5 +++ readwrite.c 1999/11/03 12:47:22 1.6 @@ -85,8 +85,11 @@ while (rc == 0 && size > 0) { if (thefile->bufpos >= thefile->dataRead) { rc = DosRead(thefile->filedes, thefile->buffer, APR_FILE_BUFSIZE, &thefile->dataRead ); -if (thefile->dataRead == 0) +if (thefile->dataRead == 0) { +if (rc == 0) +thefile->eof_hit = TRUE; break; +} thefile->filePtr += thefile->dataRead; thefile->bufpos = 0; } @@ -99,15 +102,6 @@ } *nbytes = rc == 0 ? pos - (char *)buf : 0; - -// if an error occurred report it -// if we read some data but hit EOF before reading 'size' bytes, return Ok (0) -// if we hit EOF with no data read, return -1 -if (size && rc == 0 && pos == (char *)buf) { -thefile->eof_hit = TRUE; -*_errno() = APR_EOF; -return APR_EOF; -} return os2errno(rc); } else { rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread); @@ -307,15 +301,16 @@ ap_status_t ap_fgets(char *str, int len, ap_file_t *thefile) { ssize_t readlen; -ap_status_t rv; +ap_status_t rv = APR_SUCCESS; int i; for (i = 0; i < len-1; i++) { readlen = 1; rv = ap_read(thefile, str+i, &readlen); - -if (rv != APR_SUCCESS) { -return rv; + +if (readlen != 1) { +rv = APR_EOF; +break; } if (str[i] == '\r') @@ -324,7 +319,7 @@ break; } str[i] = 0; -return APR_SUCCESS; +return rv; } 1.35 +1 -1 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- http_protocol.c 1999/11/02 14:34:32 1.34 +++ http_protocol.c 1999/11/03 12:47:23 1.35 @@ -2111,7 +2111,7 @@ while (!ap_is_aborted(r->connection)) { rv = ap_bread(fb, buf, sizeof(buf), &n); if (n == 0) { -if (rv == APR_SUCCESS || rv == APR_EOF) {/* eof */ +if (rv == APR_SUCCESS) {/* eof */ (void) ap_rflush(r); break; }
cvs commit: apache-2.0/src/main http_protocol.c
stoddard99/11/02 06:34:36 Modified:src/main http_protocol.c Log: Delete useless code... Revision ChangesPath 1.34 +1 -1 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.33 retrieving revision 1.34 diff -u -r1.33 -r1.34 --- http_protocol.c 1999/11/02 14:30:19 1.33 +++ http_protocol.c 1999/11/02 14:34:32 1.34 @@ -2008,7 +2008,7 @@ */ API_EXPORT(long) ap_send_fd(ap_file_t *fd, request_rec *r) { -ap_ssize_t len = r->finfo.st_size; +long len; #ifdef HAVE_SENDFILE ap_bflush(r->connection->client); if (ap_get_filesize(&len, fd) != APR_SUCCESS) {
cvs commit: apache-2.0/src/main http_protocol.c
bjh 99/11/01 02:50:48 Modified:src/main http_protocol.c Log: In ap_send_fb_length() don't treat APR_EOF as a fatal error. Revision ChangesPath 1.32 +1 -1 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.31 retrieving revision 1.32 diff -u -r1.31 -r1.32 --- http_protocol.c 1999/10/31 09:13:22 1.31 +++ http_protocol.c 1999/11/01 10:50:47 1.32 @@ -2095,7 +2095,7 @@ while (!ap_is_aborted(r->connection)) { rv = ap_bread(fb, buf, sizeof(buf), &n); if (n == 0) { -if (rv == APR_SUCCESS) {/* eof */ +if (rv == APR_SUCCESS || rv == APR_EOF) {/* eof */ (void) ap_rflush(r); break; }
cvs commit: apache-2.0/src/main http_protocol.c
manoj 99/10/26 15:15:20 Modified:src/main http_protocol.c Log: One ap_bflush to the client wasn't checked. Now fixed. Revision ChangesPath 1.25 +4 -2 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -u -r1.24 -r1.25 --- http_protocol.c 1999/10/24 19:23:58 1.24 +++ http_protocol.c 1999/10/26 22:15:16 1.25 @@ -2072,7 +2072,7 @@ char buf[IOBUFSIZE]; long total_bytes_sent = 0; long zero_timeout = 0; -int n, w, rc, o; +int n, w, o; if (length == 0) { return 0; @@ -2096,7 +2096,9 @@ break; } /* next read will block, so flush the client now */ -rc = ap_bflush(r->connection->client); +if (ap_rflush(r) == EOF) { +break; +} ap_bsetopt(fb, BO_TIMEOUT, &r->server->timeout); n = ap_bread(fb, buf, sizeof(buf));
cvs commit: apache-2.0/src/main http_protocol.c
manoj 99/10/12 13:39:03 Modified:src/main http_protocol.c Log: Eliminate a warning. Revision ChangesPath 1.21 +1 -1 apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -u -r1.20 -r1.21 --- http_protocol.c 1999/10/12 20:36:56 1.20 +++ http_protocol.c 1999/10/12 20:38:58 1.21 @@ -2008,7 +2008,7 @@ { char buf[IOBUFSIZE]; long total_bytes_sent = 0; -register w, o; +register int w, o; int n; ap_status_t status;
cvs commit: apache-2.0/src/main http_protocol.c
manoj 99/10/12 13:37:05 Modified:src/main http_protocol.c Log: Attempt to make ap_send_fb work again. This is untested, but it works better than the old version because it compiles. Revision ChangesPath 1.20 +28 -71apache-2.0/src/main/http_protocol.c Index: http_protocol.c === RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -u -r1.19 -r1.20 --- http_protocol.c 1999/10/11 22:07:25 1.19 +++ http_protocol.c 1999/10/12 20:36:56 1.20 @@ -2056,9 +2056,6 @@ return total_bytes_sent; } - -/* TODO: reimplement ap_send_fb */ -#if 0 /* * Send the body of a response to the client. */ @@ -2071,82 +2068,46 @@ { char buf[IOBUFSIZE]; long total_bytes_sent = 0; -register int n, w, o, len, fd; -struct pollfd fds; +long zero_timeout = 0; +int n, w, rc, o; -if (length == 0) +if (length == 0) { return 0; - -/* Make fb unbuffered and non-blocking */ -ap_bsetflag(fb, B_RD, 0); -fd = ap_bfileno(fb, B_RD); -ap_bnonblock(fd); -#ifdef CHECK_FD_SETSIZE -if (fd >= FD_SETSIZE) { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, - "send body: filedescriptor (%u) larger than FD_SETSIZE (%u) " - "found, you probably need to rebuild Apache with a " - "larger FD_SETSIZE", fd, FD_SETSIZE); - return 0; } -#endif -fds.fd = fd; -fds.events = POLLIN; +/* This function tries to as much as possible through non-blocking + * reads so that it can do writes while waiting for the CGI to + * produce more data. This way, the CGI's output gets to the client + * as soon as possible */ +ap_bsetopt(fb, BO_TIMEOUT, &zero_timeout); while (!ap_is_aborted(r->connection)) { -#ifdef NDELAY_PIPE_RETURNS_ZERO - /* Contributed by [EMAIL PROTECTED] for UTS 2.1.2, where the fcntl */ - /* O_NDELAY flag causes read to return 0 when there's nothing */ - /* available when reading from a pipe. That makes it tricky */ - /* to detect end-of-file :-(. This stupid bug is even documented */ - /* in the read(2) man page where it says that everything but */ - /* pipes return -1 and EAGAIN. That makes it a feature, right? */ - int afterselect = 0; -#endif -if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length) -len = length - total_bytes_sent; -else -len = IOBUFSIZE; - -do { -n = ap_bread(fb, buf, len); -#ifdef NDELAY_PIPE_RETURNS_ZERO - if ((n > 0) || (n == 0 && afterselect)) - break; -#else -if (n >= 0) -break; -#endif -if (ap_is_aborted(r->connection)) +n = ap_bread(fb, buf, sizeof(buf)); +if (n <= 0) { +if (n == 0) { +(void) ap_rflush(r); break; -if (n < 0 && errno != EAGAIN /* ZZZ rethink for threaded impl */) +} +if (n == -1 && errno != EAGAIN) { +r->connection->aborted = 1; break; +} +/* next read will block, so flush the client now */ +rc = ap_bflush(r->connection->client); -/* we need to block, so flush the output first */ -if (ap_bflush(r->connection->client) < 0) { -ap_log_rerror(APLOG_MARK, APLOG_INFO, r, -"client stopped connection before send body completed"); -ap_bsetflag(r->connection->client, B_EOUT, 1); +ap_bsetopt(fb, BO_TIMEOUT, &r->server->timeout); +n = ap_bread(fb, buf, sizeof(buf)); +if (n <= 0) { +if (n == 0) { +(void) ap_rflush(r); +} r->connection->aborted = 1; break; } -/* - * we don't care what poll says, we might as well loop back - * around and try another read - */ - /* use AP funcs */ -poll(&fds, 1, -1); -#ifdef NDELAY_PIPE_RETURNS_ZERO - afterselect = 1; -#endif -} while (!ap_is_aborted(r->connection)); - -if (n < 1 || ap_is_aborted(r->connection)) { -break; +ap_bsetopt(fb, BO_TIMEOUT, &zero_timeout); } + o = 0; - while (n && !ap_is_aborted(r->connection)) { w = ap_bwrite(r->connection->client, &buf[o], n); if (w > 0) { @@ -2157,7 +2118,7 @@ else if (w < 0) { if (!ap_is_aborted(r->connection)) {