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 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 Directory 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
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
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/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)) { ap_log_rerror(APLOG_MARK, APLOG_INFO, r,