1 /* ====================================================================
2 * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the Apache Group
19 * for use in the Apache HTTP server project (http://www.apache.org/)."
21 * 4. The names "Apache Server" and "Apache Group" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
26 * 5. Products derived from this software may not be called "Apache"
27 * nor may "Apache" appear in their names without prior written
28 * permission of the Apache Group.
30 * 6. Redistributions of any form whatsoever must retain the following
32 * "This product includes software developed by the Apache Group
33 * for use in the Apache HTTP server project (http://www.apache.org/)."
35 * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Group and was originally based
51 * on public domain software written at the National Center for
52 * Supercomputing Applications, University of Illinois, Urbana-Champaign.
53 * For more information on the Apache Group and the Apache HTTP server
54 * project, please see <http://www.apache.org/>.
59 * http_protocol.c --- routines which directly communicate with the client.
61 * Code originally by Rob McCool; much redone by Robert S. Thau
62 * and the Apache Group.
67 #include "http_config.h"
68 #include "http_core.h"
69 #include "http_protocol.h"
70 #include "http_main.h"
71 #include "http_request.h"
72 #include "http_vhost.h"
73 #include "http_log.h" /* For errors detected in basic auth common
75 #include "util_date.h" /* For parseHTTPdate and BAD_DATE */
79 HOOK_LINK(post_read_request)
80 HOOK_LINK(log_transaction)
81 HOOK_LINK(http_method)
82 HOOK_LINK(default_port)
85 #define SET_BYTES_SENT(r) \
86 do { if (r->sent_bodyct) \
87 ap_bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \
91 static int parse_byterange(char *range, long clength, long *start, long *end)
93 char *dash = strchr(range, '-');
98 if ((dash == range)) {
99 /* In the form "-5" */
100 *start = clength - atol(dash + 1);
106 *start = atol(range);
122 return (*start > 0 || *end < clength - 1);
125 static int internal_byterange(int, long *, request_rec *, const char **, long *,
128 API_EXPORT(int) ap_set_byterange(request_rec *r)
130 const char *range, *if_range, *match;
131 long range_start, range_end;
133 if (!r->clength || r->assbackwards)
136 /* Check for Range request-header (HTTP/1.1) or Request-Range for
137 * backwards-compatibility with second-draft Luotonen/Franks
138 * byte-ranges (e.g. Netscape Navigator 2-3).
140 * We support this form, with Request-Range, and (farther down) we
141 * send multipart/x-byteranges instead of multipart/byteranges for
142 * Request-Range based requests to work around a bug in Netscape
143 * Navigator 2-3 and MSIE 3.
146 if (!(range = ap_table_get(r->headers_in, "Range")))
147 range = ap_table_get(r->headers_in, "Request-Range");
149 if (!range || strncasecmp(range, "bytes=", 6)) {
153 /* Check the If-Range header for Etag or Date.
154 * Note that this check will return false (as required) if either
155 * of the two etags are weak.
157 if ((if_range = ap_table_get(r->headers_in, "If-Range"))) {
158 if (if_range[0] == '"') {
159 if (!(match = ap_table_get(r->headers_out, "Etag")) ||
160 (strcmp(if_range, match) != 0))
163 else if (!(match = ap_table_get(r->headers_out, "Last-Modified")) ||
164 (strcmp(if_range, match) != 0))
168 if (!strchr(range, ',')) {
170 if (!parse_byterange(ap_pstrdup(r->pool, range + 6), r->clength,
171 &range_start, &range_end))
176 ap_table_setn(r->headers_out, "Content-Range",
177 ap_psprintf(r->pool, "bytes %ld-%ld/%ld",
178 range_start, range_end, r->clength));
179 ap_table_setn(r->headers_out, "Content-Length",
180 ap_psprintf(r->pool, "%ld", range_end - range_start + 1));
183 /* a multiple range */
184 const char *r_range = ap_pstrdup(r->pool, range + 6);
188 r->boundary = ap_psprintf(r->pool, "%lx%lx",
189 r->request_time, (long) getpid());
190 while (internal_byterange(0, &tlength, r, &r_range, NULL, NULL));
191 ap_table_setn(r->headers_out, "Content-Length",
192 ap_psprintf(r->pool, "%ld", tlength));
195 r->status = PARTIAL_CONTENT;
196 r->range = range + 6;
201 API_EXPORT(int) ap_each_byterange(request_rec *r, long *offset, long *length)
203 return internal_byterange(1, NULL, r, &r->range, offset, length);
206 /* If this function is called with realreq=1, it will spit out
207 * the correct headers for a byterange chunk, and set offset and
208 * length to the positions they should be.
210 * If it is called with realreq=0, it will add to tlength the length
211 * it *would* have used with realreq=1.
213 * Either case will return 1 if it should be called again, and 0
216 static int internal_byterange(int realreq, long *tlength, request_rec *r,
217 const char **r_range, long *offset, long *length)
219 long range_start, range_end;
223 if (r->byterange > 1) {
225 ap_rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL);
227 *tlength += 4 + strlen(r->boundary) + 4;
232 range = ap_getword(r->pool, r_range, ',');
233 if (!parse_byterange(range, r->clength, &range_start, &range_end))
235 return internal_byterange(realreq, tlength, r, r_range, offset,
238 if (r->byterange > 1) {
239 const char *ct = r->content_type ? r->content_type : ap_default_type(r);
240 char ts[MAX_STRING_LEN];
242 ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end,
245 ap_rvputs(r, "\015\012--", r->boundary, "\015\012Content-type: ",
246 ct, "\015\012Content-range: bytes ", ts, "\015\012\015\012",
249 *tlength += 4 + strlen(r->boundary) + 16 + strlen(ct) + 23 +
254 *offset = range_start;
255 *length = range_end - range_start + 1;
258 *tlength += range_end - range_start + 1;
263 API_EXPORT(int) ap_set_content_length(request_rec *r, long clength)
265 r->clength = clength;
266 ap_table_setn(r->headers_out, "Content-Length", ap_psprintf(r->pool, "%ld", clength));
270 API_EXPORT(int) ap_set_keepalive(request_rec *r)
273 int wimpy = ap_find_token(r->pool,
274 ap_table_get(r->headers_out, "Connection"), "close");
275 const char *conn = ap_table_get(r->headers_in, "Connection");
277 /* The following convoluted conditional determines whether or not
278 * the current connection should remain persistent after this response
279 * (a.k.a. HTTP Keep-Alive) and whether or not the output message
280 * body should use the HTTP/1.1 chunked transfer-coding. In English,
282 * IF we have not marked this connection as errored;
283 * and the response body has a defined length due to the status code
284 * being 304 or 204, the request method being HEAD, already
285 * having defined Content-Length or Transfer-Encoding: chunked, or
286 * the request version being HTTP/1.1 and thus capable of being set
287 * as chunked [we know the (r->chunked = 1) side-effect is ugly];
288 * and the server configuration enables keep-alive;
289 * and the server configuration has a reasonable inter-request timeout;
290 * and there is no maximum # requests or the max hasn't been reached;
291 * and the response status does not require a close;
292 * and the response generator has not already indicated close;
293 * and the client did not request non-persistence (Connection: close);
294 * and we haven't been configured to ignore the buggy twit
295 * or they're a buggy twit coming through a HTTP/1.1 proxy
296 * and the client is requesting an HTTP/1.0-style keep-alive
297 * or the client claims to be HTTP/1.1 compliant (perhaps a proxy);
298 * THEN we can be persistent, which requires more headers be output.
300 * Note that the condition evaluation order is extremely important.
302 if ((r->connection->keepalive != -1) &&
303 ((r->status == HTTP_NOT_MODIFIED) ||
304 (r->status == HTTP_NO_CONTENT) ||
306 ap_table_get(r->headers_out, "Content-Length") ||
307 ap_find_last_token(r->pool,
308 ap_table_get(r->headers_out, "Transfer-Encoding"),
310 ((r->proto_num >= HTTP_VERSION(1,1)) &&
311 (r->chunked = 1))) && /* THIS CODE IS CORRECT, see comment above. */
312 r->server->keep_alive &&
313 (r->server->keep_alive_timeout > 0) &&
314 ((r->server->keep_alive_max == 0) ||
315 (r->server->keep_alive_max > r->connection->keepalives)) &&
316 !ap_status_drops_connection(r->status) &&
318 !ap_find_token(r->pool, conn, "close") &&
319 (!ap_table_get(r->subprocess_env, "nokeepalive") ||
320 ap_table_get(r->headers_in, "Via")) &&
321 ((ka_sent = ap_find_token(r->pool, conn, "keep-alive")) ||
322 (r->proto_num >= HTTP_VERSION(1,1)))
324 int left = r->server->keep_alive_max - r->connection->keepalives;
326 r->connection->keepalive = 1;
327 r->connection->keepalives++;
329 /* If they sent a Keep-Alive token, send one back */
331 if (r->server->keep_alive_max)
332 ap_table_setn(r->headers_out, "Keep-Alive",
333 ap_psprintf(r->pool, "timeout=%d, max=%d",
334 r->server->keep_alive_timeout, left));
336 ap_table_setn(r->headers_out, "Keep-Alive",
337 ap_psprintf(r->pool, "timeout=%d",
338 r->server->keep_alive_timeout));
339 ap_table_mergen(r->headers_out, "Connection", "Keep-Alive");
345 /* Otherwise, we need to indicate that we will be closing this
346 * connection immediately after the current response.
348 * We only really need to send "close" to HTTP/1.1 clients, but we
349 * always send it anyway, because a broken proxy may identify itself
350 * as HTTP/1.0, but pass our request along with our HTTP/1.1 tag
351 * to a HTTP/1.1 client. Better safe than sorry.
354 ap_table_mergen(r->headers_out, "Connection", "close");
356 r->connection->keepalive = 0;
362 * Return the latest rational time from a request/mtime (modification time)
363 * pair. We return the mtime unless it's in the future, in which case we
364 * return the current time. We use the request time as a reference in order
365 * to limit the number of calls to time(). We don't check for futurosity
366 * unless the mtime is at least as new as the reference.
368 API_EXPORT(time_t) ap_rationalize_mtime(request_rec *r, time_t mtime)
372 /* For all static responses, it's almost certain that the file was
373 * last modified before the beginning of the request. So there's
374 * no reason to call time(NULL) again. But if the response has been
375 * created on demand, then it might be newer than the time the request
376 * started. In this event we really have to call time(NULL) again
377 * so that we can give the clients the most accurate Last-Modified. If we
378 * were given a time in the future, we return the current time - the
379 * Last-Modified can't be in the future.
381 now = (mtime < r->request_time) ? r->request_time : time(NULL);
382 return (mtime > now) ? now : mtime;
385 API_EXPORT(int) ap_meets_conditions(request_rec *r)
387 const char *etag = ap_table_get(r->headers_out, "ETag");
388 const char *if_match, *if_modified_since, *if_unmodified, *if_nonematch;
391 /* Check for conditional requests --- note that we only want to do
392 * this if we are successful so far and we are not processing a
393 * subrequest or an ErrorDocument.
395 * The order of the checks is important, since ETag checks are supposed
396 * to be more accurate than checks relative to the modification time.
397 * However, not all documents are guaranteed to *have* ETags, and some
398 * might have Last-Modified values w/o ETags, so this gets a little
402 if (!ap_is_HTTP_SUCCESS(r->status) || r->no_local_copy) {
406 mtime = (r->mtime != 0) ? r->mtime : time(NULL);
408 /* If an If-Match request-header field was given
409 * AND the field value is not "*" (meaning match anything)
410 * AND if our strong ETag does not match any entity tag in that field,
411 * respond with a status of 412 (Precondition Failed).
413 if ((if_match = ap_table_get(r->headers_in, "If-Match")) != NULL) {
414 if (if_match[0] != '*' &&
415 (etag == NULL || etag[0] == 'W' ||
416 !ap_find_list_item(r->pool, if_match, etag))) {
417 return HTTP_PRECONDITION_FAILED;
421 /* Else if a valid If-Unmodified-Since request-header field was given
422 * AND the requested resource has been modified since the time
423 * specified in this field, then the server MUST
424 * respond with a status of 412 (Precondition Failed).
426 if_unmodified = ap_table_get(r->headers_in, "If-Unmodified-Since");
427 if (if_unmodified != NULL) {
428 /* ZZZ we are changing time funcs to AP time thread funcs.
429 and we need to check return values of ap_parseHTTPdate. */
431 if (ap_parseHTTPdate(if_unmodified, &ius) == 1
433 return HTTP_PRECONDITION_FAILED;
438 /* If an If-None-Match request-header field was given
439 * AND the field value is "*" (meaning match anything)
440 * OR our ETag matches any of the entity tags in that field, fail.
442 * If the request method was GET or HEAD, failure means the server
443 * SHOULD respond with a 304 (Not Modified) response.
444 * For all other request methods, failure means the server MUST
445 * respond with a status of 412 (Precondition Failed).
447 * GET or HEAD allow weak etag comparison, all other methods require
448 * strong comparison. We can only use weak if it's not a range request.
450 if_nonematch = ap_table_get(r->headers_in, "If-None-Match");
451 if (if_nonematch != NULL) {
452 if (r->method_number == M_GET) {
453 if (if_nonematch[0] == '*')
454 return HTTP_NOT_MODIFIED;
456 if (ap_table_get(r->headers_in, "Range")) {
457 if (etag[0] != 'W' &&
458 ap_find_list_item(r->pool, if_nonematch, etag)) {
459 return HTTP_NOT_MODIFIED;
462 else if (strstr(if_nonematch, etag)) {
463 return HTTP_NOT_MODIFIED;
467 else if (if_nonematch[0] == '*' ||
469 ap_find_list_item(r->pool, if_nonematch, etag))) {
470 return HTTP_PRECONDITION_FAILED;
473 /* Else if a valid If-Modified-Since request-header field was given
474 * AND it is a GET or HEAD request
475 * AND the requested resource has not been modified since the time
476 * specified in this field, then the server MUST
477 * respond with a status of 304 (Not Modified).
478 * A date later than the server's current request time is invalid.
480 else if ((r->method_number == M_GET)
481 && ((if_modified_since =
482 ap_table_get(r->headers_in, "If-Modified-Since")) != NULL)) {
484 if (ap_parseHTTPdate(if_modified_since, &ims) != 1) {
485 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
486 r->server, "bogus if-modified-since-header");
488 else if ((ims >= mtime) && (ims <= r->request_time)) {
489 return HTTP_NOT_MODIFIED;
496 * Construct an entity tag (ETag) from resource information. If it's a real
497 * file, build in some of the file characteristics. If the modification time
498 * is newer than (request-time minus 1 second), mark the ETag as weak - it
499 * could be modified again in as short an interval. We rationalize the
500 * modification time we're given to keep it from being in the future.
502 API_EXPORT(char *) ap_make_etag(request_rec *r, int force_weak)
508 * Make an ETag header out of various pieces of information. We use
509 * the last-modified date and, if we have a real file, the
510 * length and inode number - note that this doesn't have to match
511 * the content-length (i.e. includes), it just has to be unique
514 * If the request was made within a second of the last-modified date,
515 * we send a weak tag instead of a strong one, since it could
516 * be modified again later in the second, and the validation
517 * would be incorrect.
520 weak = ((r->request_time - r->mtime > 1) && !force_weak) ? "" : "W/";
522 if (r->finfo.st_mode != 0) {
523 etag = ap_psprintf(r->pool,
524 "%s\"%lx-%lx-%lx\"", weak,
525 (unsigned long) r->finfo.st_ino,
526 (unsigned long) r->finfo.st_size,
527 (unsigned long) r->mtime);
530 etag = ap_psprintf(r->pool, "%s\"%lx\"", weak,
531 (unsigned long) r->mtime);
537 API_EXPORT(void) ap_set_etag(request_rec *r)
540 char *variant_etag, *vlv;
543 if (!r->vlist_validator) {
544 etag = ap_make_etag(r, 0);
547 /* If we have a variant list validator (vlv) due to the
548 * response being negotiated, then we create a structured
549 * entity tag which merges the variant etag with the variant
550 * list validator (vlv). This merging makes revalidation
551 * somewhat safer, ensures that caches which can deal with
552 * Vary will (eventually) be updated if the set of variants is
553 * changed, and is also a protocol requirement for transparent
554 * content negotiation.
557 /* if the variant list validator is weak, we make the whole
558 * structured etag weak. If we would not, then clients could
559 * have problems merging range responses if we have different
560 * variants with the same non-globally-unique strong etag.
563 vlv = r->vlist_validator;
564 vlv_weak = (vlv[0] == 'W');
566 variant_etag = ap_make_etag(r, vlv_weak);
568 /* merge variant_etag and vlv into a structured etag */
570 variant_etag[strlen(variant_etag) - 1] = '\0';
575 etag = ap_pstrcat(r->pool, variant_etag, ";", vlv, NULL);
578 ap_table_setn(r->headers_out, "ETag", etag);
582 * This function sets the Last-Modified output header field to the value
583 * of the mtime field in the request structure - rationalized to keep it from
584 * being in the future.
586 API_EXPORT(void) ap_set_last_modified(request_rec *r)
588 time_t mod_time = ap_rationalize_mtime(r, r->mtime);
590 ap_table_setn(r->headers_out, "Last-Modified",
591 ap_gm_timestr_822(r->pool, mod_time));
594 /* Get the method number associated with the given string, assumed to
595 * contain an HTTP method. Returns M_INVALID if not recognized.
597 * This is the first step toward placing method names in a configurable
598 * list. Hopefully it (and other routines) can eventually be moved to
599 * something like a mod_http_methods.c, complete with config stuff.
601 API_EXPORT(int) ap_method_number_of(const char *method)
605 if (strcmp(method, "HEAD") == 0)
606 return M_GET; /* see header_only in request_rec */
609 if (strcmp(method, "GET") == 0)
613 if (strcmp(method, "POST") == 0)
615 if (strcmp(method, "PUT") == 0)
617 if (strcmp(method, "PATCH") == 0)
619 if (strcmp(method, "PROPFIND") == 0)
621 if (strcmp(method, "PROPPATCH") == 0)
625 if (strcmp(method, "DELETE") == 0)
629 if (strcmp(method, "CONNECT") == 0)
631 if (strcmp(method, "COPY") == 0)
635 if (strcmp(method, "MKCOL") == 0)
637 if (strcmp(method, "MOVE") == 0)
641 if (strcmp(method, "OPTIONS") == 0)
645 if (strcmp(method, "TRACE") == 0)
649 if (strcmp(method, "LOCK") == 0)
653 if (strcmp(method, "UNLOCK") == 0)
660 /* Get a line of protocol input, including any continuation lines
661 * caused by MIME folding (or broken clients) if fold != 0, and place it
662 * in the buffer s, of size n bytes, without the ending newline.
664 * Returns -1 on error, or the length of s.
666 * Note: Because bgets uses 1 char for newline and 1 char for NUL,
667 * the most we can get is (n - 2) actual characters if it
668 * was ended by a newline, or (n - 1) characters if the line
669 * length exceeded (n - 1). So, if the result == (n - 1),
670 * then the actual input line exceeded the buffer length,
671 * and it would be a good idea for the caller to puke 400 or 414.
673 static int getline(char *s, int n, BUFF *in, int fold)
682 retval = ap_bgets(pos, n, in);
683 /* retval == -1 if error, 0 if EOF */
686 return ((retval < 0) && (total == 0)) ? -1 : total;
688 /* retval is the number of characters read, not including NUL */
690 n -= retval; /* Keep track of how much of s is full */
691 pos += (retval - 1); /* and where s ends */
692 total += retval; /* and how long s has become */
694 if (*pos == '\n') { /* Did we get a full line of input? */
696 * Trim any extra trailing spaces or tabs except for the first
697 * space or tab at the beginning of a blank string. This makes
698 * it much easier to check field values for exact matches, and
699 * saves memory as well. Terminate string at end of line.
701 while (pos > (s + 1) && (*(pos - 1) == ' ' || *(pos - 1) == '\t')) {
702 --pos; /* trim extra trailing spaces or tabs */
703 --total; /* but not one at the beginning of line */
711 return total; /* if not, input line exceeded buffer size */
713 /* Continue appending if line folding is desired and
714 * the last line was not empty and we have room in the buffer and
715 * the next line begins with a continuation character.
717 } while (fold && (retval != 1) && (n > 1)
718 && (next = ap_blookc(in))
719 && ((next == ' ') || (next == '\t')));
724 /* parse_uri: break apart the uri
726 * - sets r->args to rest after '?' (or NULL if no '?')
727 * - sets r->uri to request uri (without r->args part)
728 * - sets r->hostname (if not set already) from request (scheme://host:port)
730 CORE_EXPORT(void) ap_parse_uri(request_rec *r, const char *uri)
732 int status = HTTP_OK;
734 r->unparsed_uri = ap_pstrdup(r->pool, uri);
736 if (r->method_number == M_CONNECT) {
737 status = ap_parse_hostinfo_components(r->pool, uri, &r->parsed_uri);
739 /* Simple syntax Errors in URLs are trapped by parse_uri_components(). */
740 status = ap_parse_uri_components(r->pool, uri, &r->parsed_uri);
743 if (ap_is_HTTP_SUCCESS(status)) {
744 /* if it has a scheme we may need to do absoluteURI vhost stuff */
745 if (r->parsed_uri.scheme
746 && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r))) {
747 r->hostname = r->parsed_uri.hostname;
748 } else if (r->method_number == M_CONNECT) {
749 r->hostname = r->parsed_uri.hostname;
751 r->args = r->parsed_uri.query;
752 r->uri = r->parsed_uri.path ? r->parsed_uri.path
753 : ap_pstrdup(r->pool, "/");
754 #if defined(OS2) || defined(WIN32)
755 /* Handle path translations for OS/2 and plug security hole.
756 * This will prevent "http://www.wherever.com/..\..\/" from
757 * returning a directory for the root drive.
762 for (x = r->uri; (x = strchr(x, '\\')) != NULL; )
765 #endif /* OS2 || WIN32 */
770 r->status = status; /* set error status */
771 r->uri = ap_pstrdup(r->pool, uri);
775 static int read_request_line(request_rec *r)
777 char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* getline's two extra for \n\0 */
780 conn_rec *conn = r->connection;
781 int major = 1, minor = 0; /* Assume HTTP/1.0 if non-"HTTP" protocol */
784 /* Read past empty lines until we get a real request line,
785 * a read error, the connection closes (EOF), or we timeout.
787 * We skip empty lines because browsers have to tack a CRLF on to the end
788 * of POSTs to support old CERN webservers. But note that we may not
789 * have flushed any previous response completely to the client yet.
790 * We delay the flush as long as possible so that we can improve
791 * performance for clients that are pipelining requests. If a request
792 * is pipelined then we won't block during the (implicit) read() below.
793 * If the requests aren't pipelined, then the client is still waiting
794 * for the final buffer flush from us, and we will block in the implicit
795 * read(). B_SAFEREAD ensures that the BUFF layer flushes if it will
796 * have to block during a read.
798 /* TODO: re-implement SAFEREAD external to BUFF using a layer */
799 /* //ap_bsetflag(conn->client, B_SAFEREAD, 1); */
800 ap_bflush(conn->client);
801 while ((len = getline(l, sizeof(l), conn->client, 0)) <= 0) {
802 if ((len < 0) || ap_bgetflag(conn->client, B_EOF)) {
803 /* //ap_bsetflag(conn->client, B_SAFEREAD, 0); */
804 /* this is a hack to make sure that request time is set,
805 * it's not perfect, but it's better than nothing
807 r->request_time = time(0);
811 /* we've probably got something to do, ignore graceful restart requests */
813 /* XXX - sigwait doesn't work if the signal has been SIG_IGNed (under
814 * linux 2.0 w/ glibc 2.0, anyway), and this step isn't necessary when
815 * we're running a sigwait thread anyway. If/when unthreaded mode is
816 * put back in, we should make sure to ignore this signal iff a sigwait
817 * thread isn't used. - mvsk
820 signal(SIGWINCH, SIG_IGN);
824 /* //ap_bsetflag(conn->client, B_SAFEREAD, 0); */
826 r->request_time = time(NULL);
827 r->the_request = ap_pstrdup(r->pool, l);
828 r->method = ap_getword_white(r->pool, &ll);
829 uri = ap_getword_white(r->pool, &ll);
831 /* Provide quick information about the request method as soon as known */
833 r->method_number = ap_method_number_of(r->method);
834 if (r->method_number == M_GET && r->method[0] == 'H') {
838 ap_parse_uri(r, uri);
840 /* getline returns (size of max buffer - 1) if it fills up the
841 * buffer before finding the end-of-line. This is only going to
842 * happen if it exceeds the configured limit for a request-line.
844 if (len > r->server->limit_req_line) {
845 r->status = HTTP_REQUEST_URI_TOO_LARGE;
846 r->proto_num = HTTP_VERSION(1,0);
847 r->protocol = ap_pstrdup(r->pool, "HTTP/1.0");
851 r->assbackwards = (ll[0] == '\0');
852 r->protocol = ap_pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9");
854 if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
855 && minor < HTTP_VERSION(1,0)) /* don't allow HTTP/0.1000 */
856 r->proto_num = HTTP_VERSION(major, minor);
858 r->proto_num = HTTP_VERSION(1,0);
863 static void get_mime_headers(request_rec *r)
865 char field[DEFAULT_LIMIT_REQUEST_FIELDSIZE + 2]; /* getline's two extra */
866 conn_rec *c = r->connection;
870 unsigned int fields_read = 0;
873 /* We'll use ap_overlap_tables later to merge these into r->headers_in. */
874 tmp_headers = ap_make_table(r->pool, 50);
877 * Read header lines until we get the empty separator line, a read error,
878 * the connection closes (EOF), reach the server limit, or we timeout.
880 while ((len = getline(field, sizeof(field), c->client, 1)) > 0) {
882 if (r->server->limit_req_fields &&
883 (++fields_read > r->server->limit_req_fields)) {
884 r->status = HTTP_BAD_REQUEST;
885 ap_table_setn(r->notes, "error-notes",
886 "The number of request header fields exceeds "
887 "this server's limit.<P>\n");
890 /* getline returns (size of max buffer - 1) if it fills up the
891 * buffer before finding the end-of-line. This is only going to
892 * happen if it exceeds the configured limit for a field size.
894 if (len > r->server->limit_req_fieldsize) {
895 r->status = HTTP_BAD_REQUEST;
896 ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
897 "Size of a request header field exceeds server limit.<P>\n"
898 "<PRE>\n", field, "</PRE>\n", NULL));
901 copy = ap_palloc(r->pool, len + 1);
902 memcpy(copy, field, len + 1);
904 if (!(value = strchr(copy, ':'))) { /* Find the colon separator */
905 r->status = HTTP_BAD_REQUEST; /* or abort the bad request */
906 ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
907 "Request header field is missing colon separator.<P>\n"
908 "<PRE>\n", copy, "</PRE>\n", NULL));
914 while (*value == ' ' || *value == '\t')
915 ++value; /* Skip to start of value */
917 ap_table_addn(tmp_headers, copy, value);
920 ap_overlap_tables(r->headers_in, tmp_headers, AP_OVERLAP_TABLES_MERGE);
923 request_rec *ap_read_request(conn_rec *conn)
930 p = ap_make_sub_pool(conn->pool);
931 r = ap_pcalloc(p, sizeof(request_rec));
933 r->connection = conn;
934 r->server = conn->base_server;
936 conn->keptalive = conn->keepalive == 1;
940 r->ap_auth_type = NULL;
942 r->headers_in = ap_make_table(r->pool, 50);
943 r->subprocess_env = ap_make_table(r->pool, 50);
944 r->headers_out = ap_make_table(r->pool, 12);
945 r->err_headers_out = ap_make_table(r->pool, 5);
946 r->notes = ap_make_table(r->pool, 5);
948 r->request_config = ap_create_request_config(r->pool);
949 r->per_dir_config = r->server->lookup_defaults;
951 r->sent_bodyct = 0; /* bytect isn't for body */
954 r->read_body = REQUEST_NO_BODY;
956 r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
957 r->the_request = NULL;
959 #ifdef CHARSET_EBCDIC
960 ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
963 ap_bsetopt(conn->client, BO_TIMEOUT,
965 ? &r->server->keep_alive_timeout
966 : &r->server->timeout);
968 /* Get the request... */
969 if (!read_request_line(r)) {
970 if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
971 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
972 "request failed: URI too long");
973 ap_send_error_response(r, 0);
974 ap_run_log_transaction(r);
979 if (r->connection->keptalive) {
980 ap_bsetopt(r->connection->client, BO_TIMEOUT,
981 &r->server->timeout);
983 if (!r->assbackwards) {
985 if (r->status != HTTP_REQUEST_TIME_OUT) {
986 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
987 "request failed: error reading the headers");
988 ap_send_error_response(r, 0);
989 ap_run_log_transaction(r);
994 if (r->header_only) {
996 * Client asked for headers only with HTTP/0.9, which doesn't send
997 * headers! Have to dink things just to make sure the error message
1000 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1001 "client sent invalid HTTP/0.9 request: HEAD %s",
1004 r->status = HTTP_BAD_REQUEST;
1005 ap_send_error_response(r, 0);
1006 ap_run_log_transaction(r);
1011 r->status = HTTP_OK; /* Until further notice. */
1013 /* update what we think the virtual host is based on the headers we've
1016 ap_update_vhost_from_headers(r);
1018 /* we may have switched to another server */
1019 r->per_dir_config = r->server->lookup_defaults;
1021 conn->keptalive = 0; /* We now have a request to play with */
1023 if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1,1))) ||
1024 ((r->proto_num == HTTP_VERSION(1,1)) &&
1025 !ap_table_get(r->headers_in, "Host"))) {
1027 * Client sent us an HTTP/1.1 or later request without telling us the
1028 * hostname, either with a full URL or a Host: header. We therefore
1029 * need to (as per the 1.1 spec) send an error. As a special case,
1030 * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain
1031 * a Host: header, and the server MUST respond with 400 if it doesn't.
1033 r->status = HTTP_BAD_REQUEST;
1034 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1035 "client sent HTTP/1.1 request without hostname "
1036 "(see RFC2068 section 9, and 14.23): %s", r->uri);
1037 ap_send_error_response(r, 0);
1038 ap_run_log_transaction(r);
1041 if (((expect = ap_table_get(r->headers_in, "Expect")) != NULL) &&
1042 (expect[0] != '\0')) {
1044 * The Expect header field was added to HTTP/1.1 after RFC 2068
1045 * as a means to signal when a 100 response is desired and,
1046 * unfortunately, to signal a poor man's mandatory extension that
1047 * the server must understand or return 417 Expectation Failed.
1049 if (strcasecmp(expect, "100-continue") == 0) {
1050 r->expecting_100 = 1;
1053 r->status = HTTP_EXPECTATION_FAILED;
1054 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r,
1055 "client sent an unrecognized expectation value of "
1056 "Expect: %s", expect);
1057 ap_send_error_response(r, 0);
1058 (void) ap_discard_request_body(r);
1059 ap_run_log_transaction(r);
1064 if ((access_status = ap_run_post_read_request(r))) {
1065 ap_die(access_status, r);
1066 ap_run_log_transaction(r);
1074 * A couple of other functions which initialize some of the fields of
1075 * a request structure, as appropriate for adjuncts of one kind or another
1076 * to a request in progress. Best here, rather than elsewhere, since
1077 * *someone* has to set the protocol-specific fields...
1080 void ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r)
1082 rnew->the_request = r->the_request; /* Keep original request-line */
1084 rnew->assbackwards = 1; /* Don't send headers from this. */
1085 rnew->no_local_copy = 1; /* Don't try to send USE_LOCAL_COPY for a
1087 rnew->method = "GET";
1088 rnew->method_number = M_GET;
1089 rnew->protocol = "INCLUDED";
1091 rnew->status = HTTP_OK;
1093 rnew->headers_in = r->headers_in;
1094 rnew->subprocess_env = ap_copy_table(rnew->pool, r->subprocess_env);
1095 rnew->headers_out = ap_make_table(rnew->pool, 5);
1096 rnew->err_headers_out = ap_make_table(rnew->pool, 5);
1097 rnew->notes = ap_make_table(rnew->pool, 5);
1099 rnew->expecting_100 = r->expecting_100;
1100 rnew->read_length = r->read_length;
1101 rnew->read_body = REQUEST_NO_BODY;
1103 rnew->main = (request_rec *) r;
1106 void ap_finalize_sub_req_protocol(request_rec *sub)
1108 SET_BYTES_SENT(sub->main);
1112 * Support for the Basic authentication protocol, and a bit for Digest.
1115 API_EXPORT(void) ap_note_auth_failure(request_rec *r)
1117 if (!strcasecmp(ap_auth_type(r), "Basic"))
1118 ap_note_basic_auth_failure(r);
1119 else if (!strcasecmp(ap_auth_type(r), "Digest"))
1120 ap_note_digest_auth_failure(r);
1123 API_EXPORT(void) ap_note_basic_auth_failure(request_rec *r)
1125 if (strcasecmp(ap_auth_type(r), "Basic"))
1126 ap_note_auth_failure(r);
1128 ap_table_setn(r->err_headers_out,
1129 r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
1130 ap_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), "\"",
1134 API_EXPORT(void) ap_note_digest_auth_failure(request_rec *r)
1136 ap_table_setn(r->err_headers_out,
1137 r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
1138 ap_psprintf(r->pool, "Digest realm=\"%s\", nonce=\"%lu\"",
1139 ap_auth_name(r), r->request_time));
1142 API_EXPORT(int) ap_get_basic_auth_pw(request_rec *r, const char **pw)
1144 const char *auth_line = ap_table_get(r->headers_in,
1145 r->proxyreq ? "Proxy-Authorization"
1149 if (!(t = ap_auth_type(r)) || strcasecmp(t, "Basic"))
1152 if (!ap_auth_name(r)) {
1153 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,
1154 r, "need AuthName: %s", r->uri);
1155 return SERVER_ERROR;
1159 ap_note_basic_auth_failure(r);
1160 return AUTH_REQUIRED;
1163 if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
1164 /* Client tried to authenticate using wrong auth scheme */
1165 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1166 "client used wrong authentication scheme: %s", r->uri);
1167 ap_note_basic_auth_failure(r);
1168 return AUTH_REQUIRED;
1171 /* CHARSET_EBCDIC Issue's here ?!? Compare with 32/9 instead
1172 * as we are operating on an octed stream ?
1174 while (*auth_line== ' ' || *auth_line== '\t')
1177 t = ap_pbase64decode(r->pool, auth_line);
1178 /* Note that this allocation has to be made from r->connection->pool
1179 * because it has the lifetime of the connection. The other allocations
1180 * are temporary and can be tossed away any time.
1182 r->user = ap_getword_nulls (r->pool, &t, ':');
1183 r->ap_auth_type = "Basic";
1190 /* New Apache routine to map status codes into array indicies
1191 * e.g. 100 -> 0, 101 -> 1, 200 -> 2 ...
1192 * The number of status lines must equal the value of RESPONSE_CODES (httpd.h)
1193 * and must be listed in order.
1197 /* The second const triggers an assembler bug on UTS 2.1.
1198 * Another workaround is to move some code out of this file into another,
1199 * but this is easier. Dave Dykstra, 3/31/99
1201 static const char * status_lines[RESPONSE_CODES] =
1203 static const char * const status_lines[RESPONSE_CODES] =
1207 "101 Switching Protocols",
1213 "203 Non-Authoritative Information",
1215 "205 Reset Content",
1216 "206 Partial Content",
1218 #define LEVEL_300 11
1219 "300 Multiple Choices",
1220 "301 Moved Permanently",
1226 "307 Temporary Redirect",
1227 #define LEVEL_400 19
1229 "401 Authorization Required",
1230 "402 Payment Required",
1233 "405 Method Not Allowed",
1234 "406 Not Acceptable",
1235 "407 Proxy Authentication Required",
1236 "408 Request Time-out",
1239 "411 Length Required",
1240 "412 Precondition Failed",
1241 "413 Request Entity Too Large",
1242 "414 Request-URI Too Large",
1243 "415 Unsupported Media Type",
1244 "416 Requested Range Not Satisfiable",
1245 "417 Expectation Failed",
1250 "422 Unprocessable Entity",
1252 "424 Failed Dependency",
1253 #define LEVEL_500 44
1254 "500 Internal Server Error",
1255 "501 Method Not Implemented",
1257 "503 Service Temporarily Unavailable",
1258 "504 Gateway Time-out",
1259 "505 HTTP Version Not Supported",
1260 "506 Variant Also Negotiates",
1261 "507 Insufficient Storage",
1267 /* The index is found by its offset from the x00 code of each level.
1268 * Although this is fast, it will need to be replaced if some nutcase
1269 * decides to define a high-numbered code before the lower numbers.
1270 * If that sad event occurs, replace the code below with a linear search
1271 * from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1];
1273 API_EXPORT(int) ap_index_of_response(int status)
1275 static int shortcut[6] = {0, LEVEL_200, LEVEL_300, LEVEL_400,
1276 LEVEL_500, RESPONSE_CODES};
1279 if (status < 100) /* Below 100 is illegal for HTTP status */
1282 for (i = 0; i < 5; i++) {
1285 pos = (status + shortcut[i]);
1286 if (pos < shortcut[i + 1])
1289 return LEVEL_500; /* status unknown (falls in gap) */
1292 return LEVEL_500; /* 600 or above is also illegal */
1295 /* Send a single HTTP header field to the client. Note that this function
1296 * is used in calls to table_do(), so their interfaces are co-dependent.
1297 * In other words, don't change this one without checking table_do in alloc.c.
1298 * It returns true unless there was a write error of some kind.
1300 API_EXPORT_NONSTD(int) ap_send_header_field(request_rec *r,
1301 const char *fieldname, const char *fieldval)
1303 return (0 < ap_rvputs(r, fieldname, ": ", fieldval, "\015\012", NULL));
1306 API_EXPORT(void) ap_basic_http_header(request_rec *r)
1309 #ifdef CHARSET_EBCDIC
1310 int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
1311 #endif /*CHARSET_EBCDIC*/
1313 if (r->assbackwards)
1316 if (!r->status_line)
1317 r->status_line = status_lines[ap_index_of_response(r->status)];
1319 /* mod_proxy is only HTTP/1.0, so avoid sending HTTP/1.1 error response;
1320 * kluge around broken browsers when indicated by force-response-1.0
1323 || (r->proto_num == HTTP_VERSION(1,0)
1324 && ap_table_get(r->subprocess_env, "force-response-1.0"))) {
1326 protocol = "HTTP/1.0";
1327 r->connection->keepalive = -1;
1330 protocol = SERVER_PROTOCOL;
1332 #ifdef CHARSET_EBCDIC
1333 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
1334 #endif /*CHARSET_EBCDIC*/
1336 /* Output the HTTP/1.x Status-Line and the Date and Server fields */
1338 ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL);
1340 ap_send_header_field(r, "Date", ap_gm_timestr_822(r->pool, r->request_time));
1341 ap_send_header_field(r, "Server", ap_get_server_version());
1343 ap_table_unset(r->headers_out, "Date"); /* Avoid bogosity */
1344 ap_table_unset(r->headers_out, "Server");
1345 #ifdef CHARSET_EBCDIC
1347 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
1348 #endif /*CHARSET_EBCDIC*/
1351 /* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
1352 * have a header parsing bug. If the terminating \r\n occur starting
1353 * at offset 256, 257 or 258 of output then it will not properly parse
1354 * the headers. Curiously it doesn't exhibit this problem at 512, 513.
1355 * We are guessing that this is because their initial read of a new request
1356 * uses a 256 byte buffer, and subsequent reads use a larger buffer.
1357 * So the problem might exist at different offsets as well.
1359 * This should also work on keepalive connections assuming they use the
1360 * same small buffer for the first read of each new request.
1362 * At any rate, we check the bytes written so far and, if we are about to
1363 * tickle the bug, we instead insert a bogus padding header. Since the bug
1364 * manifests as a broken image in Navigator, users blame the server. :(
1365 * It is more expensive to check the User-Agent than it is to just add the
1366 * bytes, so we haven't used the BrowserMatch feature here.
1368 static void terminate_header(request_rec *r)
1372 ap_bgetopt(r->connection->client, BO_BYTECT, &bs);
1373 if (bs >= 255 && bs <= 257)
1374 ap_rputs("X-Pad: avoid browser bug\015\012", r);
1376 ap_rputs("\015\012", r); /* Send the terminating empty line */
1379 /* Build the Allow field-value from the request handler method mask.
1380 * Note that we always allow TRACE, since it is handled below.
1382 static char *make_allow(request_rec *r)
1384 return 2 + ap_pstrcat(r->pool,
1385 (r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
1386 (r->allowed & (1 << M_POST)) ? ", POST" : "",
1387 (r->allowed & (1 << M_PUT)) ? ", PUT" : "",
1388 (r->allowed & (1 << M_DELETE)) ? ", DELETE" : "",
1389 (r->allowed & (1 << M_CONNECT)) ? ", CONNECT" : "",
1390 (r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
1391 (r->allowed & (1 << M_PATCH)) ? ", PATCH" : "",
1392 (r->allowed & (1 << M_PROPFIND)) ? ", PROPFIND" : "",
1393 (r->allowed & (1 << M_PROPPATCH)) ? ", PROPPATCH" : "",
1394 (r->allowed & (1 << M_MKCOL)) ? ", MKCOL" : "",
1395 (r->allowed & (1 << M_COPY)) ? ", COPY" : "",
1396 (r->allowed & (1 << M_MOVE)) ? ", MOVE" : "",
1397 (r->allowed & (1 << M_LOCK)) ? ", LOCK" : "",
1398 (r->allowed & (1 << M_UNLOCK)) ? ", UNLOCK" : "",
1403 API_EXPORT(int) ap_send_http_trace(request_rec *r)
1407 /* Get the original request */
1411 if ((rv = ap_setup_client_block(r, REQUEST_NO_BODY)))
1414 r->content_type = "message/http";
1415 ap_send_http_header(r);
1417 /* Now we recreate the request, and echo it back */
1419 ap_rvputs(r, r->the_request, "\015\012", NULL);
1421 ap_table_do((int (*) (void *, const char *, const char *))
1422 ap_send_header_field, (void *) r, r->headers_in, NULL);
1423 ap_rputs("\015\012", r);
1428 int ap_send_http_options(request_rec *r)
1430 const long int zero = 0L;
1432 if (r->assbackwards)
1435 ap_basic_http_header(r);
1437 ap_table_setn(r->headers_out, "Content-Length", "0");
1438 ap_table_setn(r->headers_out, "Allow", make_allow(r));
1439 ap_set_keepalive(r);
1441 ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
1442 (void *) r, r->headers_out, NULL);
1444 terminate_header(r);
1446 ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
1452 * Here we try to be compatible with clients that want multipart/x-byteranges
1453 * instead of multipart/byteranges (also see above), as per HTTP/1.1. We
1454 * look for the Request-Range header (e.g. Netscape 2 and 3) as an indication
1455 * that the browser supports an older protocol. We also check User-Agent
1456 * for Microsoft Internet Explorer 3, which needs this as well.
1458 static int use_range_x(request_rec *r)
1461 return (ap_table_get(r->headers_in, "Request-Range") ||
1462 ((ua = ap_table_get(r->headers_in, "User-Agent"))
1463 && strstr(ua, "MSIE 3")));
1466 /* This routine is called by ap_table_do and merges all instances of
1467 * the passed field values into a single array that will be further
1468 * processed by some later routine. Originally intended to help split
1469 * and recombine multiple Vary fields, though it is generic to any field
1470 * consisting of comma/space-separated tokens.
1472 static int uniq_field_values(void *d, const char *key, const char *val)
1474 array_header *values;
1480 values = (array_header *)d;
1482 e = ap_pstrdup(values->pool, val);
1485 /* Find a non-empty fieldname */
1487 while (*e == ',' || ap_isspace(*e)) {
1494 while (*e != '\0' && *e != ',' && !ap_isspace(*e)) {
1501 /* Now add it to values if it isn't already represented.
1502 * Could be replaced by a ap_array_strcasecmp() if we had one.
1504 for (i = 0, strpp = (char **) values->elts; i < values->nelts;
1506 if (*strpp && strcasecmp(*strpp, start) == 0) {
1510 if (i == values->nelts) { /* if not found */
1511 *(char **)ap_push_array(values) = start;
1513 } while (*e != '\0');
1519 * Since some clients choke violently on multiple Vary fields, or
1520 * Vary fields with duplicate tokens, combine any multiples and remove
1523 static void fixup_vary(request_rec *r)
1525 array_header *varies;
1527 varies = ap_make_array(r->pool, 5, sizeof(char *));
1529 /* Extract all Vary fields from the headers_out, separate each into
1530 * its comma-separated fieldname values, and then add them to varies
1531 * if not already present in the array.
1533 ap_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
1534 (void *) varies, r->headers_out, "Vary", NULL);
1536 /* If we found any, replace old Vary fields with unique-ified value */
1538 if (varies->nelts > 0) {
1539 ap_table_setn(r->headers_out, "Vary",
1540 ap_array_pstrcat(r->pool, varies, ','));
1544 API_EXPORT(void) ap_send_http_header(request_rec *r)
1547 const long int zero = 0L;
1548 #ifdef CHARSET_EBCDIC
1549 int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
1550 #endif /*CHARSET_EBCDIC*/
1552 if (r->assbackwards) {
1554 ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
1563 * Now that we are ready to send a response, we need to combine the two
1564 * header field tables into a single table. If we don't do this, our
1565 * later attempts to set or unset a given fieldname might be bypassed.
1567 if (!ap_is_empty_table(r->err_headers_out))
1568 r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out,
1572 * Remove the 'Vary' header field if the client can't handle it.
1573 * Since this will have nasty effects on HTTP/1.1 caches, force
1574 * the response into HTTP/1.0 mode.
1576 if (ap_table_get(r->subprocess_env, "force-no-vary") != NULL) {
1577 ap_table_unset(r->headers_out, "Vary");
1578 r->proto_num = HTTP_VERSION(1,0);
1579 ap_table_set(r->subprocess_env, "force-response-1.0", "1");
1582 ap_basic_http_header(r);
1584 #ifdef CHARSET_EBCDIC
1585 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
1586 #endif /*CHARSET_EBCDIC*/
1588 ap_set_keepalive(r);
1591 ap_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
1592 ap_table_unset(r->headers_out, "Content-Length");
1595 if (r->byterange > 1)
1596 ap_table_setn(r->headers_out, "Content-Type",
1597 ap_pstrcat(r->pool, "multipart", use_range_x(r) ? "/x-" : "/",
1598 "byteranges; boundary=", r->boundary, NULL));
1599 else if (r->content_type)
1600 ap_table_setn(r->headers_out, "Content-Type", r->content_type);
1602 ap_table_setn(r->headers_out, "Content-Type", ap_default_type(r));
1604 if (r->content_encoding)
1605 ap_table_setn(r->headers_out, "Content-Encoding", r->content_encoding);
1607 if (r->content_languages && r->content_languages->nelts) {
1608 for (i = 0; i < r->content_languages->nelts; ++i) {
1609 ap_table_mergen(r->headers_out, "Content-Language",
1610 ((char **) (r->content_languages->elts))[i]);
1613 else if (r->content_language)
1614 ap_table_setn(r->headers_out, "Content-Language", r->content_language);
1617 * Control cachability for non-cachable responses if not already set by
1618 * some other part of the server configuration.
1620 if (r->no_cache && !ap_table_get(r->headers_out, "Expires"))
1621 ap_table_addn(r->headers_out, "Expires",
1622 ap_gm_timestr_822(r->pool, r->request_time));
1624 /* Send the entire table of header fields, terminated by an empty line. */
1626 ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
1627 (void *) r, r->headers_out, NULL);
1629 terminate_header(r);
1632 ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
1633 r->sent_bodyct = 1; /* Whatever follows is real body stuff... */
1635 /* Set buffer flags for the body */
1637 ap_bsetflag(r->connection->client, B_CHUNK, 1);
1638 #ifdef CHARSET_EBCDIC
1640 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
1641 #endif /*CHARSET_EBCDIC*/
1644 /* finalize_request_protocol is called at completion of sending the
1645 * response. It's sole purpose is to send the terminating protocol
1646 * information for any wrappers around the response message body
1647 * (i.e., transfer encodings). It should have been named finalize_response.
1649 API_EXPORT(void) ap_finalize_request_protocol(request_rec *r)
1651 if (r->chunked && !r->connection->aborted) {
1653 * Turn off chunked encoding --- we can only do this once.
1656 ap_bsetflag(r->connection->client, B_CHUNK, 0);
1658 ap_rputs("0\015\012", r);
1659 /* If we had footer "headers", we'd send them now */
1660 ap_rputs("\015\012", r);
1664 /* Here we deal with getting the request message body from the client.
1665 * Whether or not the request contains a body is signaled by the presence
1666 * of a non-zero Content-Length or by a Transfer-Encoding: chunked.
1668 * Note that this is more complicated than it was in Apache 1.1 and prior
1669 * versions, because chunked support means that the module does less.
1671 * The proper procedure is this:
1673 * 1. Call setup_client_block() near the beginning of the request
1674 * handler. This will set up all the necessary properties, and will
1675 * return either OK, or an error code. If the latter, the module should
1676 * return that error code. The second parameter selects the policy to
1677 * apply if the request message indicates a body, and how a chunked
1678 * transfer-coding should be interpreted. Choose one of
1680 * REQUEST_NO_BODY Send 413 error if message has any body
1681 * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
1682 * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
1683 * REQUEST_CHUNKED_PASS Pass the chunks to me without removal.
1685 * In order to use the last two options, the caller MUST provide a buffer
1686 * large enough to hold a chunk-size line, including any extensions.
1688 * 2. When you are ready to read a body (if any), call should_client_block().
1689 * This will tell the module whether or not to read input. If it is 0,
1690 * the module should assume that there is no message body to read.
1691 * This step also sends a 100 Continue response to HTTP/1.1 clients,
1692 * so should not be called until the module is *definitely* ready to
1693 * read content. (otherwise, the point of the 100 response is defeated).
1694 * Never call this function more than once.
1696 * 3. Finally, call get_client_block in a loop. Pass it a buffer and its size.
1697 * It will put data into the buffer (not necessarily a full buffer), and
1698 * return the length of the input block. When it is done reading, it will
1699 * return 0 if EOF, or -1 if there was an error.
1700 * If an error occurs on input, we force an end to keepalive.
1703 API_EXPORT(int) ap_setup_client_block(request_rec *r, int read_policy)
1705 const char *tenc = ap_table_get(r->headers_in, "Transfer-Encoding");
1706 const char *lenp = ap_table_get(r->headers_in, "Content-Length");
1707 unsigned long max_body;
1709 r->read_body = read_policy;
1710 r->read_chunked = 0;
1714 if (strcasecmp(tenc, "chunked")) {
1715 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1716 "Unknown Transfer-Encoding %s", tenc);
1717 return HTTP_NOT_IMPLEMENTED;
1719 if (r->read_body == REQUEST_CHUNKED_ERROR) {
1720 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1721 "chunked Transfer-Encoding forbidden: %s", r->uri);
1722 return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
1725 r->read_chunked = 1;
1728 const char *pos = lenp;
1730 while (ap_isdigit(*pos) || ap_isspace(*pos))
1733 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1734 "Invalid Content-Length %s", lenp);
1735 return HTTP_BAD_REQUEST;
1738 r->remaining = atol(lenp);
1741 if ((r->read_body == REQUEST_NO_BODY) &&
1742 (r->read_chunked || (r->remaining > 0))) {
1743 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1744 "%s with body is not allowed for %s", r->method, r->uri);
1745 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1748 max_body = ap_get_limit_req_body(r);
1749 if (max_body && (r->remaining > max_body)) {
1750 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1751 "Request content-length of %s is larger than the configured "
1752 "limit of %lu", lenp, max_body);
1753 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1759 API_EXPORT(int) ap_should_client_block(request_rec *r)
1761 /* First check if we have already read the request body */
1763 if (r->read_length || (!r->read_chunked && (r->remaining <= 0)))
1766 if (r->expecting_100 && r->proto_num >= HTTP_VERSION(1,1)) {
1767 /* sending 100 Continue interim response */
1768 ap_rvputs(r, SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012",
1776 static long get_chunk_size(char *b)
1780 while (ap_isxdigit(*b)) {
1783 if (*b >= '0' && *b <= '9')
1785 else if (*b >= 'A' && *b <= 'F')
1786 xvalue = *b - 'A' + 0xa;
1787 else if (*b >= 'a' && *b <= 'f')
1788 xvalue = *b - 'a' + 0xa;
1790 chunksize = (chunksize << 4) | xvalue;
1797 /* get_client_block is called in a loop to get the request message body.
1798 * This is quite simple if the client includes a content-length
1799 * (the normal case), but gets messy if the body is chunked. Note that
1800 * r->remaining is used to maintain state across calls and that
1801 * r->read_length is the total number of bytes given to the caller
1802 * across all invocations. It is messy because we have to be careful not
1803 * to read past the data provided by the client, since these reads block.
1804 * Returns 0 on End-of-body, -1 on error or premature chunk end.
1806 * Reading the chunked encoding requires a buffer size large enough to
1807 * hold a chunk-size line, including any extensions. For now, we'll leave
1808 * that to the caller, at least until we can come up with a better solution.
1810 API_EXPORT(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
1813 long len_read, len_to_read;
1814 long chunk_start = 0;
1815 unsigned long max_body;
1817 if (!r->read_chunked) { /* Content-length read */
1818 len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
1819 len_read = ap_bread(r->connection->client, buffer, len_to_read);
1820 if (len_read <= 0) {
1822 r->connection->keepalive = -1;
1825 r->read_length += len_read;
1826 r->remaining -= len_read;
1831 * Handle chunked reading Note: we are careful to shorten the input
1832 * bufsiz so that there will always be enough space for us to add a CRLF
1835 if (r->read_body == REQUEST_CHUNKED_PASS)
1838 return -1; /* Cannot read chunked with a small buffer */
1840 /* Check to see if we have already read too much request data.
1841 * For efficiency reasons, we only check this at the top of each
1842 * caller read pass, since the limit exists just to stop infinite
1843 * length requests and nobody cares if it goes over by one buffer.
1845 max_body = ap_get_limit_req_body(r);
1846 if (max_body && (r->read_length > max_body)) {
1847 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1848 "Chunked request body is larger than the configured limit of %lu",
1850 r->connection->keepalive = -1;
1854 if (r->remaining == 0) { /* Start of new chunk */
1856 chunk_start = getline(buffer, bufsiz, r->connection->client, 0);
1857 if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1))
1858 || !ap_isxdigit(*buffer)) {
1859 r->connection->keepalive = -1;
1863 len_to_read = get_chunk_size(buffer);
1865 if (len_to_read == 0) { /* Last chunk indicated, get footers */
1866 if (r->read_body == REQUEST_CHUNKED_DECHUNK) {
1867 get_mime_headers(r);
1868 ap_snprintf(buffer, bufsiz, "%ld", r->read_length);
1869 ap_table_unset(r->headers_in, "Transfer-Encoding");
1870 ap_table_setn(r->headers_in, "Content-Length",
1871 ap_pstrdup(r->pool, buffer));
1874 r->remaining = -1; /* Indicate footers in-progress */
1877 r->remaining = len_to_read;
1879 if (r->read_body == REQUEST_CHUNKED_PASS) {
1880 buffer[chunk_start++] = CR; /* Restore chunk-size line end */
1881 buffer[chunk_start++] = LF;
1882 buffer += chunk_start; /* and pass line on to caller */
1883 bufsiz -= chunk_start;
1886 /* REQUEST_CHUNKED_DECHUNK -- do not include the length of the
1887 * header in the return value
1892 /* When REQUEST_CHUNKED_PASS, we are */
1893 if (r->remaining == -1) { /* reading footers until empty line */
1894 len_read = chunk_start;
1896 while ((bufsiz > 1) && ((len_read =
1897 getline(buffer, bufsiz, r->connection->client, 1)) > 0)) {
1899 if (len_read != (bufsiz - 1)) {
1900 buffer[len_read++] = CR; /* Restore footer line end */
1901 buffer[len_read++] = LF;
1903 chunk_start += len_read;
1908 r->connection->keepalive = -1;
1912 if (len_read == 0) { /* Indicates an empty line */
1918 r->read_length += chunk_start;
1921 /* When REQUEST_CHUNKED_PASS, we */
1922 if (r->remaining == -2) { /* finished footers when last called */
1923 r->remaining = 0; /* so now we must signal EOF */
1927 /* Otherwise, we are in the midst of reading a chunk of data */
1929 len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
1931 len_read = ap_bread(r->connection->client, buffer, len_to_read);
1932 if (len_read <= 0) {
1933 r->connection->keepalive = -1;
1937 r->remaining -= len_read;
1939 if (r->remaining == 0) { /* End of chunk, get trailing CRLF */
1940 if ((c = ap_bgetc(r->connection->client)) == CR) {
1941 c = ap_bgetc(r->connection->client);
1944 r->connection->keepalive = -1;
1947 if (r->read_body == REQUEST_CHUNKED_PASS) {
1948 buffer[len_read++] = CR;
1949 buffer[len_read++] = LF;
1952 r->read_length += (chunk_start + len_read);
1954 return (chunk_start + len_read);
1957 /* In HTTP/1.1, any method can have a body. However, most GET handlers
1958 * wouldn't know what to do with a request body if they received one.
1959 * This helper routine tests for and reads any message body in the request,
1960 * simply discarding whatever it receives. We need to do this because
1961 * failing to read the request body would cause it to be interpreted
1962 * as the next request on a persistent connection.
1964 * Since we return an error status if the request is malformed, this
1965 * routine should be called at the beginning of a no-body handler, e.g.,
1967 * if ((retval = ap_discard_request_body(r)) != OK)
1970 API_EXPORT(int) ap_discard_request_body(request_rec *r)
1974 if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_PASS)))
1977 /* In order to avoid sending 100 Continue when we already know the
1978 * final response status, and yet not kill the connection if there is
1979 * no request body to be read, we need to duplicate the test from
1980 * ap_should_client_block() here negated rather than call it directly.
1982 if ((r->read_length == 0) && (r->read_chunked || (r->remaining > 0))) {
1983 char dumpbuf[HUGE_STRING_LEN];
1985 if (r->expecting_100) {
1986 r->connection->keepalive = -1;
1990 while ((rv = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN)) > 0)
1994 return HTTP_BAD_REQUEST;
2000 * Send the body of a response to the client.
2002 API_EXPORT(long) ap_send_fd(APRFile fd, request_rec *r)
2004 return ap_send_fd_length(fd, r, -1);
2007 API_EXPORT(long) ap_send_fd_length(APRFile fd, request_rec *r, long length)
2009 char buf[IOBUFSIZE];
2010 long total_bytes_sent = 0;
2011 register int n, w, o;
2016 while (!ap_is_aborted(r->connection)) {
2017 if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
2018 o = length - total_bytes_sent;
2022 while ((n = read(fd, buf, o)) < 0 &&
2023 (errno == EINTR || errno == EAGAIN) &&
2024 !ap_is_aborted(r->connection))
2032 while (n && !ap_is_aborted(r->connection)) {
2033 w = ap_bwrite(r->connection->client, &buf[o], n);
2035 total_bytes_sent += w;
2040 if (!ap_is_aborted(r->connection)) {
2041 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2042 "client stopped connection before send body completed");
2043 ap_bsetflag(r->connection->client, B_EOUT, 1);
2044 r->connection->aborted = 1;
2052 return total_bytes_sent;
2056 /* TODO: re-implement ap_send_fb */
2059 * Send the body of a response to the client.
2061 API_EXPORT(long) ap_send_fb(BUFF *fb, request_rec *r)
2063 return ap_send_fb_length(fb, r, -1);
2066 API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length)
2068 char buf[IOBUFSIZE];
2069 long total_bytes_sent = 0;
2070 register int n, w, o, len, fd;
2076 /* Make fb unbuffered and non-blocking */
2077 ap_bsetflag(fb, B_RD, 0);
2078 fd = ap_bfileno(fb, B_RD);
2080 #ifdef CHECK_FD_SETSIZE
2081 if (fd >= FD_SETSIZE) {
2082 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL,
2083 "send body: filedescriptor (%u) larger than FD_SETSIZE (%u) "
2084 "found, you probably need to rebuild Apache with a "
2085 "larger FD_SETSIZE", fd, FD_SETSIZE);
2091 fds.events = POLLIN;
2093 while (!ap_is_aborted(r->connection)) {
2094 #ifdef NDELAY_PIPE_RETURNS_ZERO
2095 /* Contributed by dwd@bell-labs.com for UTS 2.1.2, where the fcntl */
2096 /* O_NDELAY flag causes read to return 0 when there's nothing */
2097 /* available when reading from a pipe. That makes it tricky */
2098 /* to detect end-of-file :-(. This stupid bug is even documented */
2099 /* in the read(2) man page where it says that everything but */
2100 /* pipes return -1 and EAGAIN. That makes it a feature, right? */
2101 int afterselect = 0;
2103 if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
2104 len = length - total_bytes_sent;
2109 n = ap_bread(fb, buf, len);
2110 #ifdef NDELAY_PIPE_RETURNS_ZERO
2111 if ((n > 0) || (n == 0 && afterselect))
2117 if (ap_is_aborted(r->connection))
2119 if (n < 0 && errno != EAGAIN /* ZZZ rethink for threaded impl */)
2122 /* we need to block, so flush the output first */
2123 if (ap_bflush(r->connection->client) < 0) {
2124 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2125 "client stopped connection before send body completed");
2126 ap_bsetflag(r->connection->client, B_EOUT, 1);
2127 r->connection->aborted = 1;
2131 * we don't care what poll says, we might as well loop back
2132 * around and try another read
2136 #ifdef NDELAY_PIPE_RETURNS_ZERO
2139 } while (!ap_is_aborted(r->connection));
2141 if (n < 1 || ap_is_aborted(r->connection)) {
2146 while (n && !ap_is_aborted(r->connection)) {
2147 w = ap_bwrite(r->connection->client, &buf[o], n);
2149 total_bytes_sent += w;
2154 if (!ap_is_aborted(r->connection)) {
2155 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2156 "client stopped connection before send body completed");
2157 ap_bsetflag(r->connection->client, B_EOUT, 1);
2158 r->connection->aborted = 1;
2166 return total_bytes_sent;
2172 /* The code writes MMAP_SEGMENT_SIZE bytes at a time. This is due to Apache's
2173 * timeout model, which is a timeout per-write rather than a time for the
2174 * entire transaction to complete. Essentially this should be small enough
2175 * so that in one Timeout period, your slowest clients should be reasonably
2176 * able to receive this many bytes.
2178 * To take advantage of zero-copy TCP under Solaris 2.6 this should be a
2179 * multiple of 16k. (And you need a SunATM2.0 network card.)
2181 #ifndef MMAP_SEGMENT_SIZE
2182 #define MMAP_SEGMENT_SIZE 32768
2185 /* send data from an in-memory buffer */
2186 API_EXPORT(size_t) ap_send_mmap(void *mm, request_rec *r, size_t offset,
2189 size_t total_bytes_sent = 0;
2197 while (!r->connection->aborted && offset < length) {
2198 if (length - offset > MMAP_SEGMENT_SIZE) {
2199 n = MMAP_SEGMENT_SIZE;
2202 n = length - offset;
2205 while (n && !r->connection->aborted) {
2206 w = ap_bwrite(r->connection->client, (char *) mm + offset, n);
2208 total_bytes_sent += w;
2213 if (r->connection->aborted)
2215 else if (errno == EAGAIN)
2218 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2219 "client stopped connection before send mmap completed");
2220 ap_bsetflag(r->connection->client, B_EOUT, 1);
2221 r->connection->aborted = 1;
2229 return total_bytes_sent;
2232 API_EXPORT(int) ap_rputc(int c, request_rec *r)
2234 if (r->connection->aborted)
2237 if (ap_bputc(c, r->connection->client) < 0) {
2238 if (!r->connection->aborted) {
2239 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2240 "client stopped connection before rputc completed");
2241 ap_bsetflag(r->connection->client, B_EOUT, 1);
2242 r->connection->aborted = 1;
2250 API_EXPORT(int) ap_rputs(const char *str, request_rec *r)
2254 if (r->connection->aborted)
2257 rcode = ap_bputs(str, r->connection->client);
2259 if (!r->connection->aborted) {
2260 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2261 "client stopped connection before rputs completed");
2262 ap_bsetflag(r->connection->client, B_EOUT, 1);
2263 r->connection->aborted = 1;
2271 API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
2275 if (r->connection->aborted)
2278 n = ap_bwrite(r->connection->client, buf, nbyte);
2280 if (!r->connection->aborted) {
2281 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2282 "client stopped connection before rwrite completed");
2283 ap_bsetflag(r->connection->client, B_EOUT, 1);
2284 r->connection->aborted = 1;
2292 API_EXPORT(int) ap_vrprintf(request_rec *r, const char *fmt, va_list ap)
2296 if (r->connection->aborted)
2299 n = ap_vbprintf(r->connection->client, fmt, ap);
2302 if (!r->connection->aborted) {
2303 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2304 "client stopped connection before vrprintf completed");
2305 ap_bsetflag(r->connection->client, B_EOUT, 1);
2306 r->connection->aborted = 1;
2314 API_EXPORT(int) ap_rprintf(request_rec *r, const char *fmt,...)
2319 if (r->connection->aborted)
2322 va_start(vlist, fmt);
2323 n = ap_vbprintf(r->connection->client, fmt, vlist);
2327 if (!r->connection->aborted) {
2328 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2329 "client stopped connection before rprintf completed");
2330 ap_bsetflag(r->connection->client, B_EOUT, 1);
2331 r->connection->aborted = 1;
2339 API_EXPORT_NONSTD(int) ap_rvputs(request_rec *r,...)
2344 BUFF *fb = r->connection->client;
2346 if (r->connection->aborted)
2351 x = va_arg(args, const char *);
2355 i = ap_bwrite(fb, x, j);
2358 if (!r->connection->aborted) {
2359 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2360 "client stopped connection before rvputs completed");
2361 ap_bsetflag(r->connection->client, B_EOUT, 1);
2362 r->connection->aborted = 1;
2374 API_EXPORT(int) ap_rflush(request_rec *r)
2376 if (ap_bflush(r->connection->client) < 0) {
2377 if (!r->connection->aborted) {
2378 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2379 "client stopped connection before rflush completed");
2380 ap_bsetflag(r->connection->client, B_EOUT, 1);
2381 r->connection->aborted = 1;
2388 /* We should have named this send_canned_response, since it is used for any
2389 * response that can be generated by the server from the request record.
2390 * This includes all 204 (no content), 3xx (redirect), 4xx (client error),
2391 * and 5xx (server error) messages that have not been redirected to another
2392 * handler via the ErrorDocument feature.
2394 void ap_send_error_response(request_rec *r, int recursive_error)
2396 int status = r->status;
2397 int idx = ap_index_of_response(status);
2398 char *custom_response;
2399 const char *location = ap_table_get(r->headers_out, "Location");
2402 * It's possible that the Location field might be in r->err_headers_out
2403 * instead of r->headers_out; use the latter if possible, else the
2406 if (location == NULL) {
2407 location = ap_table_get(r->err_headers_out, "Location");
2409 /* We need to special-case the handling of 204 and 304 responses,
2410 * since they have specific HTTP requirements and do not include a
2411 * message body. Note that being assbackwards here is not an option.
2413 if (status == HTTP_NOT_MODIFIED) {
2414 if (!ap_is_empty_table(r->err_headers_out))
2415 r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out,
2417 ap_basic_http_header(r);
2418 ap_set_keepalive(r);
2420 ap_table_do((int (*)(void *, const char *, const char *)) ap_send_header_field,
2421 (void *) r, r->headers_out,
2431 "Proxy-Authenticate",
2434 terminate_header(r);
2439 if (status == HTTP_NO_CONTENT) {
2440 ap_send_http_header(r);
2441 ap_finalize_request_protocol(r);
2445 if (!r->assbackwards) {
2446 table *tmp = r->headers_out;
2448 /* For all HTTP/1.x responses for which we generate the message,
2449 * we need to avoid inheriting the "normal status" header fields
2450 * that may have been set by the request handler before the
2451 * error or redirect, except for Location on external redirects.
2453 r->headers_out = r->err_headers_out;
2454 r->err_headers_out = tmp;
2455 ap_clear_table(r->err_headers_out);
2457 if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) {
2458 if ((location != NULL) && *location) {
2459 ap_table_setn(r->headers_out, "Location", location);
2462 location = ""; /* avoids coredump when printing, below */
2466 r->content_language = NULL;
2467 r->content_languages = NULL;
2468 r->content_encoding = NULL;
2470 r->content_type = "text/html";
2472 if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
2473 ap_table_setn(r->headers_out, "Allow", make_allow(r));
2475 ap_send_http_header(r);
2477 if (r->header_only) {
2478 ap_finalize_request_protocol(r);
2484 if ((custom_response = ap_response_code_string(r, idx))) {
2486 * We have a custom response output. This should only be
2487 * a text-string to write back. But if the ErrorDocument
2488 * was a local redirect and the requested resource failed
2489 * for any reason, the custom_response will still hold the
2490 * redirect URL. We don't really want to output this URL
2491 * as a text message, so first check the custom response
2492 * string to ensure that it is a text-string (using the
2493 * same test used in ap_die(), i.e. does it start with a ").
2494 * If it doesn't, we've got a recursive error, so find
2495 * the original error and output that as well.
2497 if (custom_response[0] == '\"') {
2498 ap_rputs(custom_response + 1, r);
2499 ap_finalize_request_protocol(r);
2504 * Redirect failed, so get back the original error
2506 while (r->prev && (r->prev->status != HTTP_OK))
2510 const char *title = status_lines[idx];
2512 const char *error_notes;
2514 /* Accept a status_line set by a module, but only if it begins
2515 * with the 3 digit status code
2517 if (r->status_line != NULL
2518 && strlen(r->status_line) > 4 /* long enough */
2519 && ap_isdigit(r->status_line[0])
2520 && ap_isdigit(r->status_line[1])
2521 && ap_isdigit(r->status_line[2])
2522 && ap_isspace(r->status_line[3])
2523 && ap_isalnum(r->status_line[4])) {
2524 title = r->status_line;
2527 /* folks decided they didn't want the error code in the H1 text */
2532 "<HTML><HEAD>\n<TITLE>", title,
2533 "</TITLE>\n</HEAD><BODY>\n<H1>", h1, "</H1>\n",
2537 case HTTP_MOVED_PERMANENTLY:
2538 case HTTP_MOVED_TEMPORARILY:
2539 case HTTP_TEMPORARY_REDIRECT:
2540 ap_rvputs(r, "The document has moved <A HREF=\"",
2541 ap_escape_html(r->pool, location), "\">here</A>.<P>\n",
2544 case HTTP_SEE_OTHER:
2545 ap_rvputs(r, "The answer to your request is located <A HREF=\"",
2546 ap_escape_html(r->pool, location), "\">here</A>.<P>\n",
2549 case HTTP_USE_PROXY:
2550 ap_rvputs(r, "This resource is only accessible "
2551 "through the proxy\n",
2552 ap_escape_html(r->pool, location),
2553 "<BR>\nYou will need to ",
2554 "configure your client to use that proxy.<P>\n", NULL);
2556 case HTTP_PROXY_AUTHENTICATION_REQUIRED:
2558 ap_rputs("This server could not verify that you\n"
2559 "are authorized to access the document\n"
2560 "requested. Either you supplied the wrong\n"
2561 "credentials (e.g., bad password), or your\n"
2562 "browser doesn't understand how to supply\n"
2563 "the credentials required.<P>\n", r);
2566 ap_rputs("Your browser sent a request that "
2567 "this server could not understand.<P>\n", r);
2568 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2569 ap_rvputs(r, error_notes, "<P>\n", NULL);
2572 case HTTP_FORBIDDEN:
2573 ap_rvputs(r, "You don't have permission to access ",
2574 ap_escape_html(r->pool, r->uri),
2575 "\non this server.<P>\n", NULL);
2578 ap_rvputs(r, "The requested URL ",
2579 ap_escape_html(r->pool, r->uri),
2580 " was not found on this server.<P>\n", NULL);
2582 case METHOD_NOT_ALLOWED:
2583 ap_rvputs(r, "The requested method ", r->method,
2585 "for the URL ", ap_escape_html(r->pool, r->uri),
2588 case NOT_ACCEPTABLE:
2590 "An appropriate representation of the "
2591 "requested resource ",
2592 ap_escape_html(r->pool, r->uri),
2593 " could not be found on this server.<P>\n", NULL);
2595 case MULTIPLE_CHOICES:
2598 if ((list = ap_table_get(r->notes, "variant-list")))
2602 case LENGTH_REQUIRED:
2603 ap_rvputs(r, "A request of the requested method ", r->method,
2604 " requires a valid Content-length.<P>\n", NULL);
2605 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2606 ap_rvputs(r, error_notes, "<P>\n", NULL);
2609 case PRECONDITION_FAILED:
2610 ap_rvputs(r, "The precondition on the request for the URL ",
2611 ap_escape_html(r->pool, r->uri),
2612 " evaluated to false.<P>\n", NULL);
2614 case HTTP_NOT_IMPLEMENTED:
2615 ap_rvputs(r, ap_escape_html(r->pool, r->method), " to ",
2616 ap_escape_html(r->pool, r->uri),
2617 " not supported.<P>\n", NULL);
2618 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2619 ap_rvputs(r, error_notes, "<P>\n", NULL);
2623 ap_rputs("The proxy server received an invalid\015\012"
2624 "response from an upstream server.<P>\015\012", r);
2625 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2626 ap_rvputs(r, error_notes, "<P>\n", NULL);
2629 case VARIANT_ALSO_VARIES:
2630 ap_rvputs(r, "A variant for the requested resource\n<PRE>\n",
2631 ap_escape_html(r->pool, r->uri),
2632 "\n</PRE>\nis itself a negotiable resource. "
2633 "This indicates a configuration error.<P>\n", NULL);
2635 case HTTP_REQUEST_TIME_OUT:
2636 ap_rputs("I'm tired of waiting for your request.\n", r);
2639 ap_rvputs(r, "The requested resource<BR>",
2640 ap_escape_html(r->pool, r->uri),
2641 "<BR>\nis no longer available on this server ",
2642 "and there is no forwarding address.\n",
2643 "Please remove all references to this resource.\n",
2646 case HTTP_REQUEST_ENTITY_TOO_LARGE:
2647 ap_rvputs(r, "The requested resource<BR>",
2648 ap_escape_html(r->pool, r->uri), "<BR>\n",
2649 "does not allow request data with ", r->method,
2650 " requests, or the amount of data provided in\n",
2651 "the request exceeds the capacity limit.\n", NULL);
2653 case HTTP_REQUEST_URI_TOO_LARGE:
2654 ap_rputs("The requested URL's length exceeds the capacity\n"
2655 "limit for this server.<P>\n", r);
2656 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2657 ap_rvputs(r, error_notes, "<P>\n", NULL);
2660 case HTTP_UNSUPPORTED_MEDIA_TYPE:
2661 ap_rputs("The supplied request data is not in a format\n"
2662 "acceptable for processing by this resource.\n", r);
2664 case HTTP_RANGE_NOT_SATISFIABLE:
2665 ap_rputs("None of the range-specifier values in the Range\n"
2666 "request-header field overlap the current extent\n"
2667 "of the selected resource.\n", r);
2669 case HTTP_EXPECTATION_FAILED:
2670 ap_rvputs(r, "The expectation given in the Expect request-header"
2671 "\nfield could not be met by this server.<P>\n"
2672 "The client sent<PRE>\n Expect: ",
2673 ap_table_get(r->headers_in, "Expect"), "\n</PRE>\n"
2674 "but we only allow the 100-continue expectation.\n",
2677 case HTTP_UNPROCESSABLE_ENTITY:
2678 ap_rputs("The server understands the media type of the\n"
2679 "request entity, but was unable to process the\n"
2680 "contained instructions.\n", r);
2683 ap_rputs("The requested resource is currently locked.\n"
2684 "The lock must be released or proper identification\n"
2685 "given before the method can be applied.\n", r);
2687 case HTTP_FAILED_DEPENDENCY:
2688 ap_rputs("The method could not be performed on the resource\n"
2689 "because the requested action depended on another\n"
2690 "action and that other action failed.\n", r);
2692 case HTTP_INSUFFICIENT_STORAGE:
2693 ap_rputs("The method could not be performed on the resource\n"
2694 "because the server is unable to store the\n"
2695 "representation needed to successfully complete the\n"
2696 "request. There is insufficient free space left in\n"
2697 "your storage allocation.\n", r);
2699 case HTTP_SERVICE_UNAVAILABLE:
2700 ap_rputs("The server is temporarily unable to service your\n"
2701 "request due to maintenance downtime or capacity\n"
2702 "problems. Please try again later.\n", r);
2704 case HTTP_GATEWAY_TIME_OUT:
2705 ap_rputs("The proxy server did not receive a timely response\n"
2706 "from the upstream server.\n", r);
2708 case HTTP_NOT_EXTENDED:
2709 ap_rputs("A mandatory extension policy in the request is not\n"
2710 "accepted by the server for this resource.\n", r);
2712 default: /* HTTP_INTERNAL_SERVER_ERROR */
2714 * This comparison to expose error-notes could be modified to
2715 * use a configuration directive and export based on that
2716 * directive. For now "*" is used to designate an error-notes
2717 * that is totally safe for any user to see (ie lacks paths,
2718 * database passwords, etc.)
2720 if (((error_notes = ap_table_get(r->notes, "error-notes")) != NULL)
2721 && (h1 = ap_table_get(r->notes, "verbose-error-to")) != NULL
2722 && (strcmp(h1, "*") == 0)) {
2723 ap_rvputs(r, error_notes, "<P>\n", NULL);
2726 ap_rvputs(r, "The server encountered an internal error or\n"
2727 "misconfiguration and was unable to complete\n"
2728 "your request.<P>\n"
2729 "Please contact the server administrator,\n ",
2730 ap_escape_html(r->pool, r->server->server_admin),
2731 " and inform them of the time the error occurred,\n"
2732 "and anything you might have done that may have\n"
2733 "caused the error.<P>\n"
2734 "More information about this error may be available\n"
2735 "in the server error log.<P>\n", NULL);
2738 * It would be nice to give the user the information they need to
2739 * fix the problem directly since many users don't have access to
2740 * the error_log (think University sites) even though they can easily
2741 * get this error by misconfiguring an htaccess file. However, the
2742 * error notes tend to include the real file pathname in this case,
2743 * which some people consider to be a breach of privacy. Until we
2744 * can figure out a way to remove the pathname, leave this commented.
2746 * if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2747 * ap_rvputs(r, error_notes, "<P>\n", NULL);
2753 if (recursive_error) {
2754 ap_rvputs(r, "<P>Additionally, a ",
2755 status_lines[ap_index_of_response(recursive_error)],
2756 "\nerror was encountered while trying to use an "
2757 "ErrorDocument to handle the request.\n", NULL);
2759 ap_rputs(ap_psignature("<HR>\n", r), r);
2760 ap_rputs("</BODY></HTML>\n", r);
2762 ap_finalize_request_protocol(r);
2766 IMPLEMENT_HOOK_RUN_ALL(int,post_read_request,(request_rec *r),(r),OK,DECLINED)
2767 IMPLEMENT_HOOK_RUN_ALL(int,log_transaction,(request_rec *r),(r),OK,DECLINED)
2768 IMPLEMENT_HOOK_RUN_FIRST(const char *,http_method,(const request_rec *r),(r),
2770 IMPLEMENT_HOOK_RUN_FIRST(unsigned short,default_port,(const request_rec *r),