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 */
76 #include "mpm_status.h"
80 HOOK_LINK(post_read_request)
81 HOOK_LINK(log_transaction)
82 HOOK_LINK(http_method)
83 HOOK_LINK(default_port)
86 #define SET_BYTES_SENT(r) \
87 do { if (r->sent_bodyct) \
88 ap_bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \
92 static int parse_byterange(char *range, long clength, long *start, long *end)
94 char *dash = strchr(range, '-');
99 if ((dash == range)) {
100 /* In the form "-5" */
101 *start = clength - atol(dash + 1);
107 *start = atol(range);
123 return (*start > 0 || *end < clength - 1);
126 static int internal_byterange(int, long *, request_rec *, const char **,
129 API_EXPORT(int) ap_set_byterange(request_rec *r)
131 const char *range, *if_range, *match;
132 long range_start, range_end;
134 if (!r->clength || r->assbackwards)
137 /* Check for Range request-header (HTTP/1.1) or Request-Range for
138 * backwards-compatibility with second-draft Luotonen/Franks
139 * byte-ranges (e.g. Netscape Navigator 2-3).
141 * We support this form, with Request-Range, and (farther down) we
142 * send multipart/x-byteranges instead of multipart/byteranges for
143 * Request-Range based requests to work around a bug in Netscape
144 * Navigator 2-3 and MSIE 3.
147 if (!(range = ap_table_get(r->headers_in, "Range")))
148 range = ap_table_get(r->headers_in, "Request-Range");
150 if (!range || strncasecmp(range, "bytes=", 6)) {
154 /* Check the If-Range header for Etag or Date.
155 * Note that this check will return false (as required) if either
156 * of the two etags are weak.
158 if ((if_range = ap_table_get(r->headers_in, "If-Range"))) {
159 if (if_range[0] == '"') {
160 if (!(match = ap_table_get(r->headers_out, "Etag")) ||
161 (strcmp(if_range, match) != 0))
164 else if (!(match = ap_table_get(r->headers_out, "Last-Modified")) ||
165 (strcmp(if_range, match) != 0))
169 if (!strchr(range, ',')) {
171 if (!parse_byterange(ap_pstrdup(r->pool, range + 6), r->clength,
172 &range_start, &range_end))
177 ap_table_setn(r->headers_out, "Content-Range",
178 ap_psprintf(r->pool, "bytes %ld-%ld/%ld",
179 range_start, range_end, r->clength));
180 ap_table_setn(r->headers_out, "Content-Length",
181 ap_psprintf(r->pool, "%ld", range_end - range_start + 1));
184 /* a multiple range */
185 const char *r_range = ap_pstrdup(r->pool, range + 6);
189 r->boundary = ap_psprintf(r->pool, "%lx%lx",
190 r->request_time, (long) getpid());
191 while (internal_byterange(0, &tlength, r, &r_range, NULL, NULL));
192 ap_table_setn(r->headers_out, "Content-Length",
193 ap_psprintf(r->pool, "%ld", tlength));
196 r->status = PARTIAL_CONTENT;
197 r->range = range + 6;
202 API_EXPORT(int) ap_each_byterange(request_rec *r, ap_off_t *offset,
205 return internal_byterange(1, NULL, r, &r->range, offset, length);
208 /* If this function is called with realreq=1, it will spit out
209 * the correct headers for a byterange chunk, and set offset and
210 * length to the positions they should be.
212 * If it is called with realreq=0, it will add to tlength the length
213 * it *would* have used with realreq=1.
215 * Either case will return 1 if it should be called again, and 0
218 static int internal_byterange(int realreq, long *tlength, request_rec *r,
219 const char **r_range, ap_off_t *offset,
222 long range_start, range_end;
226 if (r->byterange > 1) {
228 ap_rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL);
230 *tlength += 4 + strlen(r->boundary) + 4;
235 range = ap_getword(r->pool, r_range, ',');
236 if (!parse_byterange(range, r->clength, &range_start, &range_end))
238 return internal_byterange(realreq, tlength, r, r_range, offset,
241 if (r->byterange > 1) {
242 const char *ct = r->content_type ? r->content_type : ap_default_type(r);
243 char ts[MAX_STRING_LEN];
245 ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end,
248 ap_rvputs(r, "\015\012--", r->boundary, "\015\012Content-type: ",
249 ct, "\015\012Content-range: bytes ", ts, "\015\012\015\012",
252 *tlength += 4 + strlen(r->boundary) + 16 + strlen(ct) + 23 +
257 *offset = range_start;
258 *length = range_end - range_start + 1;
261 *tlength += range_end - range_start + 1;
266 API_EXPORT(int) ap_set_content_length(request_rec *r, long clength)
268 r->clength = clength;
269 ap_table_setn(r->headers_out, "Content-Length", ap_psprintf(r->pool, "%ld", clength));
273 API_EXPORT(int) ap_set_keepalive(request_rec *r)
276 int wimpy = ap_find_token(r->pool,
277 ap_table_get(r->headers_out, "Connection"), "close");
278 const char *conn = ap_table_get(r->headers_in, "Connection");
280 /* The following convoluted conditional determines whether or not
281 * the current connection should remain persistent after this response
282 * (a.k.a. HTTP Keep-Alive) and whether or not the output message
283 * body should use the HTTP/1.1 chunked transfer-coding. In English,
285 * IF we have not marked this connection as errored;
286 * and the response body has a defined length due to the status code
287 * being 304 or 204, the request method being HEAD, already
288 * having defined Content-Length or Transfer-Encoding: chunked, or
289 * the request version being HTTP/1.1 and thus capable of being set
290 * as chunked [we know the (r->chunked = 1) side-effect is ugly];
291 * and the server configuration enables keep-alive;
292 * and the server configuration has a reasonable inter-request timeout;
293 * and there is no maximum # requests or the max hasn't been reached;
294 * and the response status does not require a close;
295 * and the response generator has not already indicated close;
296 * and the client did not request non-persistence (Connection: close);
297 * and we haven't been configured to ignore the buggy twit
298 * or they're a buggy twit coming through a HTTP/1.1 proxy
299 * and the client is requesting an HTTP/1.0-style keep-alive
300 * or the client claims to be HTTP/1.1 compliant (perhaps a proxy);
301 * THEN we can be persistent, which requires more headers be output.
303 * Note that the condition evaluation order is extremely important.
305 if ((r->connection->keepalive != -1) &&
306 ((r->status == HTTP_NOT_MODIFIED) ||
307 (r->status == HTTP_NO_CONTENT) ||
309 ap_table_get(r->headers_out, "Content-Length") ||
310 ap_find_last_token(r->pool,
311 ap_table_get(r->headers_out, "Transfer-Encoding"),
313 ((r->proto_num >= HTTP_VERSION(1,1)) &&
314 (r->chunked = 1))) && /* THIS CODE IS CORRECT, see comment above. */
315 r->server->keep_alive &&
316 /* ZZZ change to APR keepalive timeout defined value */
317 (r->server->keep_alive_timeout > 0) &&
318 ((r->server->keep_alive_max == 0) ||
319 (r->server->keep_alive_max > r->connection->keepalives)) &&
320 !ap_status_drops_connection(r->status) &&
322 !ap_find_token(r->pool, conn, "close") &&
323 (!ap_table_get(r->subprocess_env, "nokeepalive") ||
324 ap_table_get(r->headers_in, "Via")) &&
325 ((ka_sent = ap_find_token(r->pool, conn, "keep-alive")) ||
326 (r->proto_num >= HTTP_VERSION(1,1)))
328 int left = r->server->keep_alive_max - r->connection->keepalives;
330 r->connection->keepalive = 1;
331 r->connection->keepalives++;
333 /* If they sent a Keep-Alive token, send one back */
335 if (r->server->keep_alive_max)
336 ap_table_setn(r->headers_out, "Keep-Alive",
337 ap_psprintf(r->pool, "timeout=%d, max=%d",
338 r->server->keep_alive_timeout, left));
340 ap_table_setn(r->headers_out, "Keep-Alive",
341 ap_psprintf(r->pool, "timeout=%d",
342 r->server->keep_alive_timeout));
343 ap_table_mergen(r->headers_out, "Connection", "Keep-Alive");
349 /* Otherwise, we need to indicate that we will be closing this
350 * connection immediately after the current response.
352 * We only really need to send "close" to HTTP/1.1 clients, but we
353 * always send it anyway, because a broken proxy may identify itself
354 * as HTTP/1.0, but pass our request along with our HTTP/1.1 tag
355 * to a HTTP/1.1 client. Better safe than sorry.
358 ap_table_mergen(r->headers_out, "Connection", "close");
360 r->connection->keepalive = 0;
366 * Return the latest rational time from a request/mtime (modification time)
367 * pair. We return the mtime unless it's in the future, in which case we
368 * return the current time. We use the request time as a reference in order
369 * to limit the number of calls to time(). We don't check for futurosity
370 * unless the mtime is at least as new as the reference.
372 API_EXPORT(time_t) ap_rationalize_mtime(request_rec *r, time_t mtime)
376 /* For all static responses, it's almost certain that the file was
377 * last modified before the beginning of the request. So there's
378 * no reason to call time(NULL) again. But if the response has been
379 * created on demand, then it might be newer than the time the request
380 * started. In this event we really have to call time(NULL) again
381 * so that we can give the clients the most accurate Last-Modified. If we
382 * were given a time in the future, we return the current time - the
383 * Last-Modified can't be in the future.
385 /* ZZZ Change time call to use time AP time thread functions. */
386 now = (mtime < r->request_time) ? r->request_time : time(NULL);
387 return (mtime > now) ? now : mtime;
390 API_EXPORT(int) ap_meets_conditions(request_rec *r)
392 const char *etag = ap_table_get(r->headers_out, "ETag");
393 const char *if_match, *if_modified_since, *if_unmodified, *if_nonematch;
396 /* Check for conditional requests --- note that we only want to do
397 * this if we are successful so far and we are not processing a
398 * subrequest or an ErrorDocument.
400 * The order of the checks is important, since ETag checks are supposed
401 * to be more accurate than checks relative to the modification time.
402 * However, not all documents are guaranteed to *have* ETags, and some
403 * might have Last-Modified values w/o ETags, so this gets a little
407 if (!ap_is_HTTP_SUCCESS(r->status) || r->no_local_copy) {
411 /* ZZZ We are changing time(NULL) to AP time thread functions. */
412 mtime = (r->mtime != 0) ? r->mtime : time(NULL);
414 /* If an If-Match request-header field was given
415 * AND the field value is not "*" (meaning match anything)
416 * AND if our strong ETag does not match any entity tag in that field,
417 * respond with a status of 412 (Precondition Failed).
419 if ((if_match = ap_table_get(r->headers_in, "If-Match")) != NULL) {
420 if (if_match[0] != '*' &&
421 (etag == NULL || etag[0] == 'W' ||
422 !ap_find_list_item(r->pool, if_match, etag))) {
423 return HTTP_PRECONDITION_FAILED;
427 /* Else if a valid If-Unmodified-Since request-header field was given
428 * AND the requested resource has been modified since the time
429 * specified in this field, then the server MUST
430 * respond with a status of 412 (Precondition Failed).
432 if_unmodified = ap_table_get(r->headers_in, "If-Unmodified-Since");
433 if (if_unmodified != NULL) {
434 time_t ius = ap_parseHTTPdate(if_unmodified);
436 if ((ius != BAD_DATE) && (mtime > ius)) {
437 return HTTP_PRECONDITION_FAILED;
442 /* If an If-None-Match request-header field was given
443 * AND the field value is "*" (meaning match anything)
444 * OR our ETag matches any of the entity tags in that field, fail.
446 * If the request method was GET or HEAD, failure means the server
447 * SHOULD respond with a 304 (Not Modified) response.
448 * For all other request methods, failure means the server MUST
449 * respond with a status of 412 (Precondition Failed).
451 * GET or HEAD allow weak etag comparison, all other methods require
452 * strong comparison. We can only use weak if it's not a range request.
454 if_nonematch = ap_table_get(r->headers_in, "If-None-Match");
455 if (if_nonematch != NULL) {
456 if (r->method_number == M_GET) {
457 if (if_nonematch[0] == '*')
458 return HTTP_NOT_MODIFIED;
460 if (ap_table_get(r->headers_in, "Range")) {
461 if (etag[0] != 'W' &&
462 ap_find_list_item(r->pool, if_nonematch, etag)) {
463 return HTTP_NOT_MODIFIED;
466 else if (strstr(if_nonematch, etag)) {
467 return HTTP_NOT_MODIFIED;
471 else if (if_nonematch[0] == '*' ||
473 ap_find_list_item(r->pool, if_nonematch, etag))) {
474 return HTTP_PRECONDITION_FAILED;
477 /* Else if a valid If-Modified-Since request-header field was given
478 * AND it is a GET or HEAD request
479 * AND the requested resource has not been modified since the time
480 * specified in this field, then the server MUST
481 * respond with a status of 304 (Not Modified).
482 * A date later than the server's current request time is invalid.
484 else if ((r->method_number == M_GET)
485 && ((if_modified_since =
486 ap_table_get(r->headers_in, "If-Modified-Since")) != NULL)) {
487 time_t ims = ap_parseHTTPdate(if_modified_since);
489 if ((ims >= mtime) && (ims <= r->request_time)) {
490 return HTTP_NOT_MODIFIED;
497 * Construct an entity tag (ETag) from resource information. If it's a real
498 * file, build in some of the file characteristics. If the modification time
499 * is newer than (request-time minus 1 second), mark the ETag as weak - it
500 * could be modified again in as short an interval. We rationalize the
501 * modification time we're given to keep it from being in the future.
503 API_EXPORT(char *) ap_make_etag(request_rec *r, int force_weak)
509 * Make an ETag header out of various pieces of information. We use
510 * the last-modified date and, if we have a real file, the
511 * length and inode number - note that this doesn't have to match
512 * the content-length (i.e. includes), it just has to be unique
515 * If the request was made within a second of the last-modified date,
516 * we send a weak tag instead of a strong one, since it could
517 * be modified again later in the second, and the validation
518 * would be incorrect.
521 weak = ((r->request_time - r->mtime > 1) && !force_weak) ? "" : "W/";
523 if (r->finfo.st_mode != 0) {
524 etag = ap_psprintf(r->pool,
525 "%s\"%lx-%lx-%lx\"", weak,
526 (unsigned long) r->finfo.st_ino,
527 (unsigned long) r->finfo.st_size,
528 (unsigned long) r->mtime);
531 etag = ap_psprintf(r->pool, "%s\"%lx\"", weak,
532 (unsigned long) r->mtime);
538 API_EXPORT(void) ap_set_etag(request_rec *r)
541 char *variant_etag, *vlv;
544 if (!r->vlist_validator) {
545 etag = ap_make_etag(r, 0);
548 /* If we have a variant list validator (vlv) due to the
549 * response being negotiated, then we create a structured
550 * entity tag which merges the variant etag with the variant
551 * list validator (vlv). This merging makes revalidation
552 * somewhat safer, ensures that caches which can deal with
553 * Vary will (eventually) be updated if the set of variants is
554 * changed, and is also a protocol requirement for transparent
555 * content negotiation.
558 /* if the variant list validator is weak, we make the whole
559 * structured etag weak. If we would not, then clients could
560 * have problems merging range responses if we have different
561 * variants with the same non-globally-unique strong etag.
564 vlv = r->vlist_validator;
565 vlv_weak = (vlv[0] == 'W');
567 variant_etag = ap_make_etag(r, vlv_weak);
569 /* merge variant_etag and vlv into a structured etag */
571 variant_etag[strlen(variant_etag) - 1] = '\0';
576 etag = ap_pstrcat(r->pool, variant_etag, ";", vlv, NULL);
579 ap_table_setn(r->headers_out, "ETag", etag);
583 * This function sets the Last-Modified output header field to the value
584 * of the mtime field in the request structure - rationalized to keep it from
585 * being in the future.
587 API_EXPORT(void) ap_set_last_modified(request_rec *r)
589 time_t mod_time = ap_rationalize_mtime(r, r->mtime);
591 ap_table_setn(r->headers_out, "Last-Modified",
592 ap_gm_timestr_822(r->pool, mod_time));
595 /* Get the method number associated with the given string, assumed to
596 * contain an HTTP method. Returns M_INVALID if not recognized.
598 * This is the first step toward placing method names in a configurable
599 * list. Hopefully it (and other routines) can eventually be moved to
600 * something like a mod_http_methods.c, complete with config stuff.
602 API_EXPORT(int) ap_method_number_of(const char *method)
606 if (strcmp(method, "HEAD") == 0)
607 return M_GET; /* see header_only in request_rec */
610 if (strcmp(method, "GET") == 0)
614 if (strcmp(method, "POST") == 0)
616 if (strcmp(method, "PUT") == 0)
618 if (strcmp(method, "PATCH") == 0)
620 if (strcmp(method, "PROPFIND") == 0)
622 if (strcmp(method, "PROPPATCH") == 0)
626 if (strcmp(method, "DELETE") == 0)
630 if (strcmp(method, "CONNECT") == 0)
632 if (strcmp(method, "COPY") == 0)
636 if (strcmp(method, "MKCOL") == 0)
638 if (strcmp(method, "MOVE") == 0)
642 if (strcmp(method, "OPTIONS") == 0)
646 if (strcmp(method, "TRACE") == 0)
650 if (strcmp(method, "LOCK") == 0)
654 if (strcmp(method, "UNLOCK") == 0)
661 /* Get a line of protocol input, including any continuation lines
662 * caused by MIME folding (or broken clients) if fold != 0, and place it
663 * in the buffer s, of size n bytes, without the ending newline.
665 * Returns -1 on error, or the length of s.
667 * Note: Because bgets uses 1 char for newline and 1 char for NUL,
668 * the most we can get is (n - 2) actual characters if it
669 * was ended by a newline, or (n - 1) characters if the line
670 * length exceeded (n - 1). So, if the result == (n - 1),
671 * then the actual input line exceeded the buffer length,
672 * and it would be a good idea for the caller to puke 400 or 414.
674 static int getline(char *s, int n, BUFF *in, int fold)
683 retval = ap_bgets(pos, n, in);
684 /* retval == -1 if error, 0 if EOF */
687 return ((retval < 0) && (total == 0)) ? -1 : total;
689 /* retval is the number of characters read, not including NUL */
691 n -= retval; /* Keep track of how much of s is full */
692 pos += (retval - 1); /* and where s ends */
693 total += retval; /* and how long s has become */
695 if (*pos == '\n') { /* Did we get a full line of input? */
697 * Trim any extra trailing spaces or tabs except for the first
698 * space or tab at the beginning of a blank string. This makes
699 * it much easier to check field values for exact matches, and
700 * saves memory as well. Terminate string at end of line.
702 while (pos > (s + 1) && (*(pos - 1) == ' ' || *(pos - 1) == '\t')) {
703 --pos; /* trim extra trailing spaces or tabs */
704 --total; /* but not one at the beginning of line */
712 return total; /* if not, input line exceeded buffer size */
714 /* Continue appending if line folding is desired and
715 * the last line was not empty and we have room in the buffer and
716 * the next line begins with a continuation character.
718 } while (fold && (retval != 1) && (n > 1)
719 && (next = ap_blookc(in))
720 && ((next == ' ') || (next == '\t')));
725 /* parse_uri: break apart the uri
727 * - sets r->args to rest after '?' (or NULL if no '?')
728 * - sets r->uri to request uri (without r->args part)
729 * - sets r->hostname (if not set already) from request (scheme://host:port)
731 CORE_EXPORT(void) ap_parse_uri(request_rec *r, const char *uri)
733 int status = HTTP_OK;
735 r->unparsed_uri = ap_pstrdup(r->pool, uri);
737 if (r->method_number == M_CONNECT) {
738 status = ap_parse_hostinfo_components(r->pool, uri, &r->parsed_uri);
740 /* Simple syntax Errors in URLs are trapped by parse_uri_components(). */
741 status = ap_parse_uri_components(r->pool, uri, &r->parsed_uri);
744 if (ap_is_HTTP_SUCCESS(status)) {
745 /* if it has a scheme we may need to do absoluteURI vhost stuff */
746 if (r->parsed_uri.scheme
747 && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r))) {
748 r->hostname = r->parsed_uri.hostname;
749 } else if (r->method_number == M_CONNECT) {
750 r->hostname = r->parsed_uri.hostname;
752 r->args = r->parsed_uri.query;
753 r->uri = r->parsed_uri.path ? r->parsed_uri.path
754 : ap_pstrdup(r->pool, "/");
755 #if defined(OS2) || defined(WIN32)
756 /* Handle path translations for OS/2 and plug security hole.
757 * This will prevent "http://www.wherever.com/..\..\/" from
758 * returning a directory for the root drive.
763 for (x = r->uri; (x = strchr(x, '\\')) != NULL; )
766 #endif /* OS2 || WIN32 */
771 r->status = status; /* set error status */
772 r->uri = ap_pstrdup(r->pool, uri);
776 static int read_request_line(request_rec *r)
778 char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* getline's two extra for \n\0 */
781 conn_rec *conn = r->connection;
782 int major = 1, minor = 0; /* Assume HTTP/1.0 if non-"HTTP" protocol */
785 /* Read past empty lines until we get a real request line,
786 * a read error, the connection closes (EOF), or we timeout.
788 * We skip empty lines because browsers have to tack a CRLF on to the end
789 * of POSTs to support old CERN webservers. But note that we may not
790 * have flushed any previous response completely to the client yet.
791 * We delay the flush as long as possible so that we can improve
792 * performance for clients that are pipelining requests. If a request
793 * is pipelined then we won't block during the (implicit) read() below.
794 * If the requests aren't pipelined, then the client is still waiting
795 * for the final buffer flush from us, and we will block in the implicit
796 * read(). B_SAFEREAD ensures that the BUFF layer flushes if it will
797 * have to block during a read.
799 /* TODO: reimplement SAFEREAD external to BUFF using a layer */
800 /* //ap_bsetflag(conn->client, B_SAFEREAD, 1); */
801 ap_bflush(conn->client);
802 while ((len = getline(l, sizeof(l), conn->client, 0)) <= 0) {
803 if ((len < 0) || ap_bgetflag(conn->client, B_EOF)) {
804 /* //ap_bsetflag(conn->client, B_SAFEREAD, 0); */
805 /* this is a hack to make sure that request time is set,
806 * it's not perfect, but it's better than nothing
808 r->request_time = time(0);
812 /* we've probably got something to do, ignore graceful restart requests */
814 /* XXX - sigwait doesn't work if the signal has been SIG_IGNed (under
815 * linux 2.0 w/ glibc 2.0, anyway), and this step isn't necessary when
816 * we're running a sigwait thread anyway. If/when unthreaded mode is
817 * put back in, we should make sure to ignore this signal iff a sigwait
818 * thread isn't used. - mvsk
821 signal(SIGWINCH, SIG_IGN);
825 /* //ap_bsetflag(conn->client, B_SAFEREAD, 0); */
827 r->request_time = time(NULL);
828 r->the_request = ap_pstrdup(r->pool, l);
829 r->method = ap_getword_white(r->pool, &ll);
830 ap_update_connection_status(conn->id, "Method", r->method);
831 uri = ap_getword_white(r->pool, &ll);
833 /* Provide quick information about the request method as soon as known */
835 r->method_number = ap_method_number_of(r->method);
836 if (r->method_number == M_GET && r->method[0] == 'H') {
840 ap_parse_uri(r, uri);
842 /* getline returns (size of max buffer - 1) if it fills up the
843 * buffer before finding the end-of-line. This is only going to
844 * happen if it exceeds the configured limit for a request-line.
846 if (len > r->server->limit_req_line) {
847 r->status = HTTP_REQUEST_URI_TOO_LARGE;
848 r->proto_num = HTTP_VERSION(1,0);
849 r->protocol = ap_pstrdup(r->pool, "HTTP/1.0");
853 r->assbackwards = (ll[0] == '\0');
854 r->protocol = ap_pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9");
855 ap_update_connection_status(conn->id, "Protocol", r->protocol);
857 if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
858 && minor < HTTP_VERSION(1,0)) /* don't allow HTTP/0.1000 */
859 r->proto_num = HTTP_VERSION(major, minor);
861 r->proto_num = HTTP_VERSION(1,0);
866 static void get_mime_headers(request_rec *r)
868 char field[DEFAULT_LIMIT_REQUEST_FIELDSIZE + 2]; /* getline's two extra */
869 conn_rec *c = r->connection;
873 unsigned int fields_read = 0;
874 ap_table_t *tmp_headers;
876 /* We'll use ap_overlap_tables later to merge these into r->headers_in. */
877 tmp_headers = ap_make_table(r->pool, 50);
880 * Read header lines until we get the empty separator line, a read error,
881 * the connection closes (EOF), reach the server limit, or we timeout.
883 while ((len = getline(field, sizeof(field), c->client, 1)) > 0) {
885 if (r->server->limit_req_fields &&
886 (++fields_read > r->server->limit_req_fields)) {
887 r->status = HTTP_BAD_REQUEST;
888 ap_table_setn(r->notes, "error-notes",
889 "The number of request header fields exceeds "
890 "this server's limit.<P>\n");
893 /* getline returns (size of max buffer - 1) if it fills up the
894 * buffer before finding the end-of-line. This is only going to
895 * happen if it exceeds the configured limit for a field size.
897 if (len > r->server->limit_req_fieldsize) {
898 r->status = HTTP_BAD_REQUEST;
899 ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
900 "Size of a request header field exceeds server limit.<P>\n"
901 "<PRE>\n", field, "</PRE>\n", NULL));
904 copy = ap_palloc(r->pool, len + 1);
905 memcpy(copy, field, len + 1);
907 if (!(value = strchr(copy, ':'))) { /* Find the colon separator */
908 r->status = HTTP_BAD_REQUEST; /* or abort the bad request */
909 ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
910 "Request header field is missing colon separator.<P>\n"
911 "<PRE>\n", copy, "</PRE>\n", NULL));
917 while (*value == ' ' || *value == '\t')
918 ++value; /* Skip to start of value */
920 ap_table_addn(tmp_headers, copy, value);
923 ap_overlap_tables(r->headers_in, tmp_headers, AP_OVERLAP_TABLES_MERGE);
926 request_rec *ap_read_request(conn_rec *conn)
933 ap_create_context(&p, conn->pool);
934 r = ap_pcalloc(p, sizeof(request_rec));
936 r->connection = conn;
937 r->server = conn->base_server;
939 conn->keptalive = conn->keepalive == 1;
943 r->ap_auth_type = NULL;
945 r->headers_in = ap_make_table(r->pool, 50);
946 r->subprocess_env = ap_make_table(r->pool, 50);
947 r->headers_out = ap_make_table(r->pool, 12);
948 r->err_headers_out = ap_make_table(r->pool, 5);
949 r->notes = ap_make_table(r->pool, 5);
951 r->request_config = ap_create_request_config(r->pool);
952 r->per_dir_config = r->server->lookup_defaults;
954 r->sent_bodyct = 0; /* bytect isn't for body */
957 r->read_body = REQUEST_NO_BODY;
959 r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
960 r->the_request = NULL;
962 #ifdef CHARSET_EBCDIC
963 ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
966 ap_bsetopt(conn->client, BO_TIMEOUT,
968 ? &r->server->keep_alive_timeout
969 : &r->server->timeout);
971 /* Get the request... */
972 if (!read_request_line(r)) {
973 if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
974 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
975 "request failed: URI too long");
976 ap_send_error_response(r, 0);
977 ap_run_log_transaction(r);
982 if (r->connection->keptalive) {
983 ap_bsetopt(r->connection->client, BO_TIMEOUT,
984 &r->server->timeout);
986 if (!r->assbackwards) {
988 if (r->status != HTTP_REQUEST_TIME_OUT) {
989 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
990 "request failed: error reading the headers");
991 ap_send_error_response(r, 0);
992 ap_run_log_transaction(r);
997 if (r->header_only) {
999 * Client asked for headers only with HTTP/0.9, which doesn't send
1000 * headers! Have to dink things just to make sure the error message
1003 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
1004 "client sent invalid HTTP/0.9 request: HEAD %s",
1007 r->status = HTTP_BAD_REQUEST;
1008 ap_send_error_response(r, 0);
1009 ap_run_log_transaction(r);
1014 r->status = HTTP_OK; /* Until further notice. */
1016 /* update what we think the virtual host is based on the headers we've
1019 ap_update_vhost_from_headers(r);
1021 /* we may have switched to another server */
1022 r->per_dir_config = r->server->lookup_defaults;
1024 conn->keptalive = 0; /* We now have a request to play with */
1026 if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1,1))) ||
1027 ((r->proto_num == HTTP_VERSION(1,1)) &&
1028 !ap_table_get(r->headers_in, "Host"))) {
1030 * Client sent us an HTTP/1.1 or later request without telling us the
1031 * hostname, either with a full URL or a Host: header. We therefore
1032 * need to (as per the 1.1 spec) send an error. As a special case,
1033 * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain
1034 * a Host: header, and the server MUST respond with 400 if it doesn't.
1036 r->status = HTTP_BAD_REQUEST;
1037 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
1038 "client sent HTTP/1.1 request without hostname "
1039 "(see RFC2068 section 9, and 14.23): %s", r->uri);
1040 ap_send_error_response(r, 0);
1041 ap_run_log_transaction(r);
1044 if (((expect = ap_table_get(r->headers_in, "Expect")) != NULL) &&
1045 (expect[0] != '\0')) {
1047 * The Expect header field was added to HTTP/1.1 after RFC 2068
1048 * as a means to signal when a 100 response is desired and,
1049 * unfortunately, to signal a poor man's mandatory extension that
1050 * the server must understand or return 417 Expectation Failed.
1052 if (strcasecmp(expect, "100-continue") == 0) {
1053 r->expecting_100 = 1;
1056 r->status = HTTP_EXPECTATION_FAILED;
1057 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r,
1058 "client sent an unrecognized expectation value of "
1059 "Expect: %s", expect);
1060 ap_send_error_response(r, 0);
1061 (void) ap_discard_request_body(r);
1062 ap_run_log_transaction(r);
1067 if ((access_status = ap_run_post_read_request(r))) {
1068 ap_die(access_status, r);
1069 ap_run_log_transaction(r);
1077 * A couple of other functions which initialize some of the fields of
1078 * a request structure, as appropriate for adjuncts of one kind or another
1079 * to a request in progress. Best here, rather than elsewhere, since
1080 * *someone* has to set the protocol-specific fields...
1083 void ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r)
1085 rnew->the_request = r->the_request; /* Keep original request-line */
1087 rnew->assbackwards = 1; /* Don't send headers from this. */
1088 rnew->no_local_copy = 1; /* Don't try to send USE_LOCAL_COPY for a
1090 rnew->method = "GET";
1091 rnew->method_number = M_GET;
1092 rnew->protocol = "INCLUDED";
1094 rnew->status = HTTP_OK;
1096 rnew->headers_in = r->headers_in;
1097 rnew->subprocess_env = ap_copy_table(rnew->pool, r->subprocess_env);
1098 rnew->headers_out = ap_make_table(rnew->pool, 5);
1099 rnew->err_headers_out = ap_make_table(rnew->pool, 5);
1100 rnew->notes = ap_make_table(rnew->pool, 5);
1102 rnew->expecting_100 = r->expecting_100;
1103 rnew->read_length = r->read_length;
1104 rnew->read_body = REQUEST_NO_BODY;
1106 rnew->main = (request_rec *) r;
1109 void ap_finalize_sub_req_protocol(request_rec *sub)
1111 SET_BYTES_SENT(sub->main);
1115 * Support for the Basic authentication protocol, and a bit for Digest.
1118 API_EXPORT(void) ap_note_auth_failure(request_rec *r)
1120 if (!strcasecmp(ap_auth_type(r), "Basic"))
1121 ap_note_basic_auth_failure(r);
1122 else if (!strcasecmp(ap_auth_type(r), "Digest"))
1123 ap_note_digest_auth_failure(r);
1126 API_EXPORT(void) ap_note_basic_auth_failure(request_rec *r)
1128 if (strcasecmp(ap_auth_type(r), "Basic"))
1129 ap_note_auth_failure(r);
1131 ap_table_setn(r->err_headers_out,
1132 r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
1133 ap_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), "\"",
1137 API_EXPORT(void) ap_note_digest_auth_failure(request_rec *r)
1139 ap_table_setn(r->err_headers_out,
1140 r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
1141 ap_psprintf(r->pool, "Digest realm=\"%s\", nonce=\"%lu\"",
1142 ap_auth_name(r), r->request_time));
1145 API_EXPORT(int) ap_get_basic_auth_pw(request_rec *r, const char **pw)
1147 const char *auth_line = ap_table_get(r->headers_in,
1148 r->proxyreq ? "Proxy-Authorization"
1152 if (!(t = ap_auth_type(r)) || strcasecmp(t, "Basic"))
1155 if (!ap_auth_name(r)) {
1156 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,
1157 0, r, "need AuthName: %s", r->uri);
1158 return SERVER_ERROR;
1162 ap_note_basic_auth_failure(r);
1163 return AUTH_REQUIRED;
1166 if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
1167 /* Client tried to authenticate using wrong auth scheme */
1168 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
1169 "client used wrong authentication scheme: %s", r->uri);
1170 ap_note_basic_auth_failure(r);
1171 return AUTH_REQUIRED;
1174 /* CHARSET_EBCDIC Issue's here ?!? Compare with 32/9 instead
1175 * as we are operating on an octed stream ?
1177 while (*auth_line== ' ' || *auth_line== '\t')
1180 t = ap_pbase64decode(r->pool, auth_line);
1181 /* Note that this allocation has to be made from r->connection->pool
1182 * because it has the lifetime of the connection. The other allocations
1183 * are temporary and can be tossed away any time.
1185 r->user = ap_getword_nulls (r->pool, &t, ':');
1186 r->ap_auth_type = "Basic";
1193 /* New Apache routine to map status codes into array indicies
1194 * e.g. 100 -> 0, 101 -> 1, 200 -> 2 ...
1195 * The number of status lines must equal the value of RESPONSE_CODES (httpd.h)
1196 * and must be listed in order.
1200 /* The second const triggers an assembler bug on UTS 2.1.
1201 * Another workaround is to move some code out of this file into another,
1202 * but this is easier. Dave Dykstra, 3/31/99
1204 static const char * status_lines[RESPONSE_CODES] =
1206 static const char * const status_lines[RESPONSE_CODES] =
1210 "101 Switching Protocols",
1216 "203 Non-Authoritative Information",
1218 "205 Reset Content",
1219 "206 Partial Content",
1221 #define LEVEL_300 11
1222 "300 Multiple Choices",
1223 "301 Moved Permanently",
1229 "307 Temporary Redirect",
1230 #define LEVEL_400 19
1232 "401 Authorization Required",
1233 "402 Payment Required",
1236 "405 Method Not Allowed",
1237 "406 Not Acceptable",
1238 "407 Proxy Authentication Required",
1239 "408 Request Time-out",
1242 "411 Length Required",
1243 "412 Precondition Failed",
1244 "413 Request Entity Too Large",
1245 "414 Request-URI Too Large",
1246 "415 Unsupported Media Type",
1247 "416 Requested Range Not Satisfiable",
1248 "417 Expectation Failed",
1253 "422 Unprocessable Entity",
1255 "424 Failed Dependency",
1256 #define LEVEL_500 44
1257 "500 Internal Server Error",
1258 "501 Method Not Implemented",
1260 "503 Service Temporarily Unavailable",
1261 "504 Gateway Time-out",
1262 "505 HTTP Version Not Supported",
1263 "506 Variant Also Negotiates",
1264 "507 Insufficient Storage",
1270 /* The index is found by its offset from the x00 code of each level.
1271 * Although this is fast, it will need to be replaced if some nutcase
1272 * decides to define a high-numbered code before the lower numbers.
1273 * If that sad event occurs, replace the code below with a linear search
1274 * from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1];
1276 API_EXPORT(int) ap_index_of_response(int status)
1278 static int shortcut[6] = {0, LEVEL_200, LEVEL_300, LEVEL_400,
1279 LEVEL_500, RESPONSE_CODES};
1282 if (status < 100) /* Below 100 is illegal for HTTP status */
1285 for (i = 0; i < 5; i++) {
1288 pos = (status + shortcut[i]);
1289 if (pos < shortcut[i + 1])
1292 return LEVEL_500; /* status unknown (falls in gap) */
1295 return LEVEL_500; /* 600 or above is also illegal */
1298 /* Send a single HTTP header field to the client. Note that this function
1299 * is used in calls to table_do(), so their interfaces are co-dependent.
1300 * In other words, don't change this one without checking table_do in alloc.c.
1301 * It returns true unless there was a write error of some kind.
1303 API_EXPORT_NONSTD(int) ap_send_header_field(request_rec *r,
1304 const char *fieldname, const char *fieldval)
1306 return (0 < ap_rvputs(r, fieldname, ": ", fieldval, "\015\012", NULL));
1309 API_EXPORT(void) ap_basic_http_header(request_rec *r)
1312 #ifdef CHARSET_EBCDIC
1313 int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
1314 #endif /*CHARSET_EBCDIC*/
1316 if (r->assbackwards)
1319 if (!r->status_line)
1320 r->status_line = status_lines[ap_index_of_response(r->status)];
1322 /* mod_proxy is only HTTP/1.0, so avoid sending HTTP/1.1 error response;
1323 * kluge around broken browsers when indicated by force-response-1.0
1326 || (r->proto_num == HTTP_VERSION(1,0)
1327 && ap_table_get(r->subprocess_env, "force-response-1.0"))) {
1329 protocol = "HTTP/1.0";
1330 r->connection->keepalive = -1;
1333 protocol = SERVER_PROTOCOL;
1335 #ifdef CHARSET_EBCDIC
1336 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
1337 #endif /*CHARSET_EBCDIC*/
1339 /* Output the HTTP/1.x Status-Line and the Date and Server fields */
1341 ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL);
1343 ap_send_header_field(r, "Date", ap_gm_timestr_822(r->pool, r->request_time));
1344 ap_send_header_field(r, "Server", ap_get_server_version());
1346 ap_table_unset(r->headers_out, "Date"); /* Avoid bogosity */
1347 ap_table_unset(r->headers_out, "Server");
1348 #ifdef CHARSET_EBCDIC
1350 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
1351 #endif /*CHARSET_EBCDIC*/
1354 /* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
1355 * have a header parsing bug. If the terminating \r\n occur starting
1356 * at offset 256, 257 or 258 of output then it will not properly parse
1357 * the headers. Curiously it doesn't exhibit this problem at 512, 513.
1358 * We are guessing that this is because their initial read of a new request
1359 * uses a 256 byte buffer, and subsequent reads use a larger buffer.
1360 * So the problem might exist at different offsets as well.
1362 * This should also work on keepalive connections assuming they use the
1363 * same small buffer for the first read of each new request.
1365 * At any rate, we check the bytes written so far and, if we are about to
1366 * tickle the bug, we instead insert a bogus padding header. Since the bug
1367 * manifests as a broken image in Navigator, users blame the server. :(
1368 * It is more expensive to check the User-Agent than it is to just add the
1369 * bytes, so we haven't used the BrowserMatch feature here.
1371 static void terminate_header(request_rec *r)
1375 ap_bgetopt(r->connection->client, BO_BYTECT, &bs);
1376 if (bs >= 255 && bs <= 257)
1377 ap_rputs("X-Pad: avoid browser bug\015\012", r);
1379 ap_rputs("\015\012", r); /* Send the terminating empty line */
1382 /* Build the Allow field-value from the request handler method mask.
1383 * Note that we always allow TRACE, since it is handled below.
1385 static char *make_allow(request_rec *r)
1387 return 2 + ap_pstrcat(r->pool,
1388 (r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
1389 (r->allowed & (1 << M_POST)) ? ", POST" : "",
1390 (r->allowed & (1 << M_PUT)) ? ", PUT" : "",
1391 (r->allowed & (1 << M_DELETE)) ? ", DELETE" : "",
1392 (r->allowed & (1 << M_CONNECT)) ? ", CONNECT" : "",
1393 (r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
1394 (r->allowed & (1 << M_PATCH)) ? ", PATCH" : "",
1395 (r->allowed & (1 << M_PROPFIND)) ? ", PROPFIND" : "",
1396 (r->allowed & (1 << M_PROPPATCH)) ? ", PROPPATCH" : "",
1397 (r->allowed & (1 << M_MKCOL)) ? ", MKCOL" : "",
1398 (r->allowed & (1 << M_COPY)) ? ", COPY" : "",
1399 (r->allowed & (1 << M_MOVE)) ? ", MOVE" : "",
1400 (r->allowed & (1 << M_LOCK)) ? ", LOCK" : "",
1401 (r->allowed & (1 << M_UNLOCK)) ? ", UNLOCK" : "",
1406 API_EXPORT(int) ap_send_http_trace(request_rec *r)
1410 /* Get the original request */
1414 if ((rv = ap_setup_client_block(r, REQUEST_NO_BODY)))
1417 r->content_type = "message/http";
1418 ap_send_http_header(r);
1420 /* Now we recreate the request, and echo it back */
1422 ap_rvputs(r, r->the_request, "\015\012", NULL);
1424 ap_table_do((int (*) (void *, const char *, const char *))
1425 ap_send_header_field, (void *) r, r->headers_in, NULL);
1426 ap_rputs("\015\012", r);
1431 int ap_send_http_options(request_rec *r)
1433 const long int zero = 0L;
1435 if (r->assbackwards)
1438 ap_basic_http_header(r);
1440 ap_table_setn(r->headers_out, "Content-Length", "0");
1441 ap_table_setn(r->headers_out, "Allow", make_allow(r));
1442 ap_set_keepalive(r);
1444 ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
1445 (void *) r, r->headers_out, NULL);
1447 terminate_header(r);
1449 ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
1455 * Here we try to be compatible with clients that want multipart/x-byteranges
1456 * instead of multipart/byteranges (also see above), as per HTTP/1.1. We
1457 * look for the Request-Range header (e.g. Netscape 2 and 3) as an indication
1458 * that the browser supports an older protocol. We also check User-Agent
1459 * for Microsoft Internet Explorer 3, which needs this as well.
1461 static int use_range_x(request_rec *r)
1464 return (ap_table_get(r->headers_in, "Request-Range") ||
1465 ((ua = ap_table_get(r->headers_in, "User-Agent"))
1466 && strstr(ua, "MSIE 3")));
1469 /* This routine is called by ap_table_do and merges all instances of
1470 * the passed field values into a single array that will be further
1471 * processed by some later routine. Originally intended to help split
1472 * and recombine multiple Vary fields, though it is generic to any field
1473 * consisting of comma/space-separated tokens.
1475 static int uniq_field_values(void *d, const char *key, const char *val)
1477 ap_array_header_t *values;
1483 values = (ap_array_header_t *)d;
1485 e = ap_pstrdup(values->cont, val);
1488 /* Find a non-empty fieldname */
1490 while (*e == ',' || ap_isspace(*e)) {
1497 while (*e != '\0' && *e != ',' && !ap_isspace(*e)) {
1504 /* Now add it to values if it isn't already represented.
1505 * Could be replaced by a ap_array_strcasecmp() if we had one.
1507 for (i = 0, strpp = (char **) values->elts; i < values->nelts;
1509 if (*strpp && strcasecmp(*strpp, start) == 0) {
1513 if (i == values->nelts) { /* if not found */
1514 *(char **)ap_push_array(values) = start;
1516 } while (*e != '\0');
1522 * Since some clients choke violently on multiple Vary fields, or
1523 * Vary fields with duplicate tokens, combine any multiples and remove
1526 static void fixup_vary(request_rec *r)
1528 ap_array_header_t *varies;
1530 varies = ap_make_array(r->pool, 5, sizeof(char *));
1532 /* Extract all Vary fields from the headers_out, separate each into
1533 * its comma-separated fieldname values, and then add them to varies
1534 * if not already present in the array.
1536 ap_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
1537 (void *) varies, r->headers_out, "Vary", NULL);
1539 /* If we found any, replace old Vary fields with unique-ified value */
1541 if (varies->nelts > 0) {
1542 ap_table_setn(r->headers_out, "Vary",
1543 ap_array_pstrcat(r->pool, varies, ','));
1547 API_EXPORT(void) ap_send_http_header(request_rec *r)
1550 const long int zero = 0L;
1551 #ifdef CHARSET_EBCDIC
1552 int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
1553 #endif /*CHARSET_EBCDIC*/
1555 if (r->assbackwards) {
1557 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");
1585 ap_basic_http_header(r);
1587 #ifdef CHARSET_EBCDIC
1588 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
1589 #endif /*CHARSET_EBCDIC*/
1591 ap_set_keepalive(r);
1594 ap_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
1595 ap_table_unset(r->headers_out, "Content-Length");
1598 if (r->byterange > 1)
1599 ap_table_setn(r->headers_out, "Content-Type",
1600 ap_pstrcat(r->pool, "multipart", use_range_x(r) ? "/x-" : "/",
1601 "byteranges; boundary=", r->boundary, NULL));
1602 else if (r->content_type)
1603 ap_table_setn(r->headers_out, "Content-Type", r->content_type);
1605 ap_table_setn(r->headers_out, "Content-Type", ap_default_type(r));
1607 if (r->content_encoding)
1608 ap_table_setn(r->headers_out, "Content-Encoding", r->content_encoding);
1610 if (r->content_languages && r->content_languages->nelts) {
1611 for (i = 0; i < r->content_languages->nelts; ++i) {
1612 ap_table_mergen(r->headers_out, "Content-Language",
1613 ((char **) (r->content_languages->elts))[i]);
1616 else if (r->content_language)
1617 ap_table_setn(r->headers_out, "Content-Language", r->content_language);
1620 * Control cachability for non-cachable responses if not already set by
1621 * some other part of the server configuration.
1623 if (r->no_cache && !ap_table_get(r->headers_out, "Expires"))
1624 ap_table_addn(r->headers_out, "Expires",
1625 ap_gm_timestr_822(r->pool, r->request_time));
1627 /* Send the entire ap_table_t of header fields, terminated by an empty line. */
1629 ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
1630 (void *) r, r->headers_out, NULL);
1632 terminate_header(r);
1635 ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
1636 r->sent_bodyct = 1; /* Whatever follows is real body stuff... */
1638 /* Set buffer flags for the body */
1640 ap_bsetflag(r->connection->client, B_CHUNK, 1);
1641 #ifdef CHARSET_EBCDIC
1643 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
1644 #endif /*CHARSET_EBCDIC*/
1647 /* finalize_request_protocol is called at completion of sending the
1648 * response. It's sole purpose is to send the terminating protocol
1649 * information for any wrappers around the response message body
1650 * (i.e., transfer encodings). It should have been named finalize_response.
1652 API_EXPORT(void) ap_finalize_request_protocol(request_rec *r)
1654 if (r->chunked && !r->connection->aborted) {
1656 * Turn off chunked encoding --- we can only do this once.
1659 ap_bsetflag(r->connection->client, B_CHUNK, 0);
1661 ap_rputs("0\015\012", r);
1662 /* If we had footer "headers", we'd send them now */
1663 ap_rputs("\015\012", r);
1667 /* Here we deal with getting the request message body from the client.
1668 * Whether or not the request contains a body is signaled by the presence
1669 * of a non-zero Content-Length or by a Transfer-Encoding: chunked.
1671 * Note that this is more complicated than it was in Apache 1.1 and prior
1672 * versions, because chunked support means that the module does less.
1674 * The proper procedure is this:
1676 * 1. Call setup_client_block() near the beginning of the request
1677 * handler. This will set up all the necessary properties, and will
1678 * return either OK, or an error code. If the latter, the module should
1679 * return that error code. The second parameter selects the policy to
1680 * apply if the request message indicates a body, and how a chunked
1681 * transfer-coding should be interpreted. Choose one of
1683 * REQUEST_NO_BODY Send 413 error if message has any body
1684 * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
1685 * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
1686 * REQUEST_CHUNKED_PASS Pass the chunks to me without removal.
1688 * In order to use the last two options, the caller MUST provide a buffer
1689 * large enough to hold a chunk-size line, including any extensions.
1691 * 2. When you are ready to read a body (if any), call should_client_block().
1692 * This will tell the module whether or not to read input. If it is 0,
1693 * the module should assume that there is no message body to read.
1694 * This step also sends a 100 Continue response to HTTP/1.1 clients,
1695 * so should not be called until the module is *definitely* ready to
1696 * read content. (otherwise, the point of the 100 response is defeated).
1697 * Never call this function more than once.
1699 * 3. Finally, call get_client_block in a loop. Pass it a buffer and its size.
1700 * It will put data into the buffer (not necessarily a full buffer), and
1701 * return the length of the input block. When it is done reading, it will
1702 * return 0 if EOF, or -1 if there was an error.
1703 * If an error occurs on input, we force an end to keepalive.
1706 API_EXPORT(int) ap_setup_client_block(request_rec *r, int read_policy)
1708 const char *tenc = ap_table_get(r->headers_in, "Transfer-Encoding");
1709 const char *lenp = ap_table_get(r->headers_in, "Content-Length");
1710 unsigned long max_body;
1712 r->read_body = read_policy;
1713 r->read_chunked = 0;
1717 if (strcasecmp(tenc, "chunked")) {
1718 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
1719 "Unknown Transfer-Encoding %s", tenc);
1720 return HTTP_NOT_IMPLEMENTED;
1722 if (r->read_body == REQUEST_CHUNKED_ERROR) {
1723 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
1724 "chunked Transfer-Encoding forbidden: %s", r->uri);
1725 return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
1728 r->read_chunked = 1;
1731 const char *pos = lenp;
1733 while (ap_isdigit(*pos) || ap_isspace(*pos))
1736 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
1737 "Invalid Content-Length %s", lenp);
1738 return HTTP_BAD_REQUEST;
1741 r->remaining = atol(lenp);
1744 if ((r->read_body == REQUEST_NO_BODY) &&
1745 (r->read_chunked || (r->remaining > 0))) {
1746 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
1747 "%s with body is not allowed for %s", r->method, r->uri);
1748 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1751 max_body = ap_get_limit_req_body(r);
1752 if (max_body && (r->remaining > max_body)) {
1753 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
1754 "Request content-length of %s is larger than the configured "
1755 "limit of %lu", lenp, max_body);
1756 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1762 API_EXPORT(int) ap_should_client_block(request_rec *r)
1764 /* First check if we have already read the request body */
1766 if (r->read_length || (!r->read_chunked && (r->remaining <= 0)))
1769 if (r->expecting_100 && r->proto_num >= HTTP_VERSION(1,1)) {
1770 /* sending 100 Continue interim response */
1771 ap_rvputs(r, SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012",
1779 static long get_chunk_size(char *b)
1783 while (ap_isxdigit(*b)) {
1786 if (*b >= '0' && *b <= '9')
1788 else if (*b >= 'A' && *b <= 'F')
1789 xvalue = *b - 'A' + 0xa;
1790 else if (*b >= 'a' && *b <= 'f')
1791 xvalue = *b - 'a' + 0xa;
1793 chunksize = (chunksize << 4) | xvalue;
1800 /* get_client_block is called in a loop to get the request message body.
1801 * This is quite simple if the client includes a content-length
1802 * (the normal case), but gets messy if the body is chunked. Note that
1803 * r->remaining is used to maintain state across calls and that
1804 * r->read_length is the total number of bytes given to the caller
1805 * across all invocations. It is messy because we have to be careful not
1806 * to read past the data provided by the client, since these reads block.
1807 * Returns 0 on End-of-body, -1 on error or premature chunk end.
1809 * Reading the chunked encoding requires a buffer size large enough to
1810 * hold a chunk-size line, including any extensions. For now, we'll leave
1811 * that to the caller, at least until we can come up with a better solution.
1813 API_EXPORT(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
1816 ap_size_t len_to_read;
1817 ap_ssize_t len_read;
1818 long chunk_start = 0;
1819 unsigned long max_body;
1822 if (!r->read_chunked) { /* Content-length read */
1823 len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
1824 rv = ap_bread(r->connection->client, buffer, len_to_read, &len_read);
1825 if (len_read == 0) { /* error or eof */
1826 if (rv != APR_SUCCESS) {
1827 r->connection->keepalive = -1;
1832 r->read_length += len_read;
1833 r->remaining -= len_read;
1838 * Handle chunked reading Note: we are careful to shorten the input
1839 * bufsiz so that there will always be enough space for us to add a CRLF
1842 if (r->read_body == REQUEST_CHUNKED_PASS)
1845 return -1; /* Cannot read chunked with a small buffer */
1847 /* Check to see if we have already read too much request data.
1848 * For efficiency reasons, we only check this at the top of each
1849 * caller read pass, since the limit exists just to stop infinite
1850 * length requests and nobody cares if it goes over by one buffer.
1852 max_body = ap_get_limit_req_body(r);
1853 if (max_body && (r->read_length > max_body)) {
1854 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
1855 "Chunked request body is larger than the configured limit of %lu",
1857 r->connection->keepalive = -1;
1861 if (r->remaining == 0) { /* Start of new chunk */
1863 chunk_start = getline(buffer, bufsiz, r->connection->client, 0);
1864 if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1))
1865 || !ap_isxdigit(*buffer)) {
1866 r->connection->keepalive = -1;
1870 len_to_read = get_chunk_size(buffer);
1872 if (len_to_read == 0) { /* Last chunk indicated, get footers */
1873 if (r->read_body == REQUEST_CHUNKED_DECHUNK) {
1874 get_mime_headers(r);
1875 ap_snprintf(buffer, bufsiz, "%ld", r->read_length);
1876 ap_table_unset(r->headers_in, "Transfer-Encoding");
1877 ap_table_setn(r->headers_in, "Content-Length",
1878 ap_pstrdup(r->pool, buffer));
1881 r->remaining = -1; /* Indicate footers in-progress */
1884 r->remaining = len_to_read;
1886 if (r->read_body == REQUEST_CHUNKED_PASS) {
1887 buffer[chunk_start++] = CR; /* Restore chunk-size line end */
1888 buffer[chunk_start++] = LF;
1889 buffer += chunk_start; /* and pass line on to caller */
1890 bufsiz -= chunk_start;
1893 /* REQUEST_CHUNKED_DECHUNK -- do not include the length of the
1894 * header in the return value
1899 /* When REQUEST_CHUNKED_PASS, we are */
1900 if (r->remaining == -1) { /* reading footers until empty line */
1901 len_read = chunk_start;
1903 while ((bufsiz > 1) && ((len_read =
1904 getline(buffer, bufsiz, r->connection->client, 1)) > 0)) {
1906 if (len_read != (bufsiz - 1)) {
1907 buffer[len_read++] = CR; /* Restore footer line end */
1908 buffer[len_read++] = LF;
1910 chunk_start += len_read;
1915 r->connection->keepalive = -1;
1919 if (len_read == 0) { /* Indicates an empty line */
1925 r->read_length += chunk_start;
1928 /* When REQUEST_CHUNKED_PASS, we */
1929 if (r->remaining == -2) { /* finished footers when last called */
1930 r->remaining = 0; /* so now we must signal EOF */
1934 /* Otherwise, we are in the midst of reading a chunk of data */
1936 len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
1938 (void) ap_bread(r->connection->client, buffer, len_to_read, &len_read);
1939 if (len_read == 0) { /* error or eof */
1940 r->connection->keepalive = -1;
1944 r->remaining -= len_read;
1946 if (r->remaining == 0) { /* End of chunk, get trailing CRLF */
1947 if ((c = ap_bgetc(r->connection->client)) == CR) {
1948 c = ap_bgetc(r->connection->client);
1951 r->connection->keepalive = -1;
1954 if (r->read_body == REQUEST_CHUNKED_PASS) {
1955 buffer[len_read++] = CR;
1956 buffer[len_read++] = LF;
1959 r->read_length += (chunk_start + len_read);
1961 return (chunk_start + len_read);
1964 /* In HTTP/1.1, any method can have a body. However, most GET handlers
1965 * wouldn't know what to do with a request body if they received one.
1966 * This helper routine tests for and reads any message body in the request,
1967 * simply discarding whatever it receives. We need to do this because
1968 * failing to read the request body would cause it to be interpreted
1969 * as the next request on a persistent connection.
1971 * Since we return an error status if the request is malformed, this
1972 * routine should be called at the beginning of a no-body handler, e.g.,
1974 * if ((retval = ap_discard_request_body(r)) != OK)
1977 API_EXPORT(int) ap_discard_request_body(request_rec *r)
1981 if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_PASS)))
1984 /* In order to avoid sending 100 Continue when we already know the
1985 * final response status, and yet not kill the connection if there is
1986 * no request body to be read, we need to duplicate the test from
1987 * ap_should_client_block() here negated rather than call it directly.
1989 if ((r->read_length == 0) && (r->read_chunked || (r->remaining > 0))) {
1990 char dumpbuf[HUGE_STRING_LEN];
1992 if (r->expecting_100) {
1993 r->connection->keepalive = -1;
1997 while ((rv = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN)) > 0)
2001 return HTTP_BAD_REQUEST;
2007 * Send the body of a response to the client.
2009 API_EXPORT(long) ap_send_fd(ap_file_t *fd, request_rec *r)
2011 return ap_send_fd_length(fd, r, -1);
2014 API_EXPORT(long) ap_send_fd_length(ap_file_t *fd, request_rec *r, long length)
2016 char buf[IOBUFSIZE];
2017 long total_bytes_sent = 0;
2025 while (!ap_is_aborted(r->connection)) {
2026 if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
2027 o = length - total_bytes_sent;
2033 status = ap_read(fd, buf, &n);
2034 } while (status == APR_EINTR && !ap_is_aborted(r->connection) &&
2043 while (n && !ap_is_aborted(r->connection)) {
2044 w = ap_bwrite(r->connection->client, &buf[o], n);
2046 total_bytes_sent += w;
2051 if (!ap_is_aborted(r->connection)) {
2052 ap_log_rerror(APLOG_MARK, APLOG_INFO, errno, r,
2053 "client stopped connection before send body completed");
2054 ap_bsetflag(r->connection->client, B_EOUT, 1);
2055 r->connection->aborted = 1;
2063 return total_bytes_sent;
2067 * Send the body of a response to the client.
2069 API_EXPORT(long) ap_send_fb(BUFF *fb, request_rec *r)
2071 return ap_send_fb_length(fb, r, -1);
2074 API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length)
2076 char buf[IOBUFSIZE];
2077 long total_bytes_sent = 0;
2078 long zero_timeout = 0;
2087 /* This function tries to as much as possible through non-blocking
2088 * reads so that it can do writes while waiting for the CGI to
2089 * produce more data. This way, the CGI's output gets to the client
2090 * as soon as possible */
2092 ap_bsetopt(fb, BO_TIMEOUT, &zero_timeout);
2093 while (!ap_is_aborted(r->connection)) {
2094 rv = ap_bread(fb, buf, sizeof(buf), &n);
2096 if (rv == APR_SUCCESS) { /* eof */
2097 (void) ap_rflush(r);
2100 if (rv != APR_EAGAIN) {
2101 r->connection->aborted = 1;
2104 /* next read will block, so flush the client now */
2105 if (ap_rflush(r) == EOF) {
2109 ap_bsetopt(fb, BO_TIMEOUT, &r->server->timeout);
2110 rv = ap_bread(fb, buf, sizeof(buf), &n);
2112 if (rv == APR_SUCCESS) { /* eof */
2113 (void) ap_rflush(r);
2115 r->connection->aborted = 1;
2118 ap_bsetopt(fb, BO_TIMEOUT, &zero_timeout);
2122 while (n && !ap_is_aborted(r->connection)) {
2123 w = ap_bwrite(r->connection->client, &buf[o], n);
2125 total_bytes_sent += w;
2130 if (!ap_is_aborted(r->connection)) {
2131 ap_log_rerror(APLOG_MARK, APLOG_INFO, errno, r,
2132 "client stopped connection before rflush completed");
2133 ap_bsetflag(r->connection->client, B_EOUT, 1);
2134 r->connection->aborted = 1;
2141 return total_bytes_sent;
2144 /* The code writes MMAP_SEGMENT_SIZE bytes at a time. This is due to Apache's
2145 * timeout model, which is a timeout per-write rather than a time for the
2146 * entire transaction to complete. Essentially this should be small enough
2147 * so that in one Timeout period, your slowest clients should be reasonably
2148 * able to receive this many bytes.
2150 * To take advantage of zero-copy TCP under Solaris 2.6 this should be a
2151 * multiple of 16k. (And you need a SunATM2.0 network card.)
2153 #ifndef MMAP_SEGMENT_SIZE
2154 #define MMAP_SEGMENT_SIZE 32768
2157 /* send data from an in-memory buffer */
2158 API_EXPORT(size_t) ap_send_mmap(void *mm, request_rec *r, size_t offset,
2161 size_t total_bytes_sent = 0;
2169 while (!r->connection->aborted && offset < length) {
2170 if (length - offset > MMAP_SEGMENT_SIZE) {
2171 n = MMAP_SEGMENT_SIZE;
2174 n = length - offset;
2177 while (n && !r->connection->aborted) {
2178 w = ap_bwrite(r->connection->client, (char *) mm + offset, n);
2180 total_bytes_sent += w;
2185 if (r->connection->aborted)
2187 else if (errno == EAGAIN)
2190 ap_log_rerror(APLOG_MARK, APLOG_INFO, errno, r,
2191 "client stopped connection before send mmap completed");
2192 ap_bsetflag(r->connection->client, B_EOUT, 1);
2193 r->connection->aborted = 1;
2201 return total_bytes_sent;
2204 API_EXPORT(int) ap_rputc(int c, request_rec *r)
2206 if (r->connection->aborted)
2209 if (ap_bputc(c, r->connection->client) < 0) {
2210 if (!r->connection->aborted) {
2211 ap_log_rerror(APLOG_MARK, APLOG_INFO, errno, r,
2212 "client stopped connection before rputc completed");
2213 ap_bsetflag(r->connection->client, B_EOUT, 1);
2214 r->connection->aborted = 1;
2222 API_EXPORT(int) ap_rputs(const char *str, request_rec *r)
2226 if (r->connection->aborted)
2229 rcode = ap_bputs(str, r->connection->client);
2231 if (!r->connection->aborted) {
2232 ap_log_rerror(APLOG_MARK, APLOG_INFO, errno, r,
2233 "client stopped connection before rputs completed");
2234 ap_bsetflag(r->connection->client, B_EOUT, 1);
2235 r->connection->aborted = 1;
2243 API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
2247 if (r->connection->aborted)
2250 n = ap_bwrite(r->connection->client, buf, nbyte);
2252 if (!r->connection->aborted) {
2253 ap_log_rerror(APLOG_MARK, APLOG_INFO, errno, r,
2254 "client stopped connection before rwrite completed");
2255 ap_bsetflag(r->connection->client, B_EOUT, 1);
2256 r->connection->aborted = 1;
2264 API_EXPORT(int) ap_vrprintf(request_rec *r, const char *fmt, va_list ap)
2268 if (r->connection->aborted)
2271 n = ap_vbprintf(r->connection->client, fmt, ap);
2274 if (!r->connection->aborted) {
2275 ap_log_rerror(APLOG_MARK, APLOG_INFO, errno, r,
2276 "client stopped connection before vrprintf completed");
2277 ap_bsetflag(r->connection->client, B_EOUT, 1);
2278 r->connection->aborted = 1;
2286 API_EXPORT(int) ap_rprintf(request_rec *r, const char *fmt,...)
2291 if (r->connection->aborted)
2294 va_start(vlist, fmt);
2295 n = ap_vbprintf(r->connection->client, fmt, vlist);
2299 if (!r->connection->aborted) {
2300 ap_log_rerror(APLOG_MARK, APLOG_INFO, errno, r,
2301 "client stopped connection before rprintf completed");
2302 ap_bsetflag(r->connection->client, B_EOUT, 1);
2303 r->connection->aborted = 1;
2311 API_EXPORT_NONSTD(int) ap_rvputs(request_rec *r,...)
2316 BUFF *fb = r->connection->client;
2318 if (r->connection->aborted)
2323 x = va_arg(args, const char *);
2327 i = ap_bwrite(fb, x, j);
2330 if (!r->connection->aborted) {
2331 ap_log_rerror(APLOG_MARK, APLOG_INFO, errno, r,
2332 "client stopped connection before rvputs completed");
2333 ap_bsetflag(r->connection->client, B_EOUT, 1);
2334 r->connection->aborted = 1;
2346 API_EXPORT(int) ap_rflush(request_rec *r)
2350 if ((rv = ap_bflush(r->connection->client)) != APR_SUCCESS) {
2351 if (!ap_is_aborted(r->connection)) {
2352 ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, r,
2353 "client stopped connection before rflush completed");
2354 ap_bsetflag(r->connection->client, B_EOUT, 1);
2355 r->connection->aborted = 1;
2363 /* We should have named this send_canned_response, since it is used for any
2364 * response that can be generated by the server from the request record.
2365 * This includes all 204 (no content), 3xx (redirect), 4xx (client error),
2366 * and 5xx (server error) messages that have not been redirected to another
2367 * handler via the ErrorDocument feature.
2369 void ap_send_error_response(request_rec *r, int recursive_error)
2371 int status = r->status;
2372 int idx = ap_index_of_response(status);
2373 char *custom_response;
2374 const char *location = ap_table_get(r->headers_out, "Location");
2377 * It's possible that the Location field might be in r->err_headers_out
2378 * instead of r->headers_out; use the latter if possible, else the
2381 if (location == NULL) {
2382 location = ap_table_get(r->err_headers_out, "Location");
2384 /* We need to special-case the handling of 204 and 304 responses,
2385 * since they have specific HTTP requirements and do not include a
2386 * message body. Note that being assbackwards here is not an option.
2388 if (status == HTTP_NOT_MODIFIED) {
2389 if (!ap_is_empty_table(r->err_headers_out))
2390 r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out,
2392 ap_basic_http_header(r);
2393 ap_set_keepalive(r);
2395 ap_table_do((int (*)(void *, const char *, const char *)) ap_send_header_field,
2396 (void *) r, r->headers_out,
2406 "Proxy-Authenticate",
2409 terminate_header(r);
2414 if (status == HTTP_NO_CONTENT) {
2415 ap_send_http_header(r);
2416 ap_finalize_request_protocol(r);
2420 if (!r->assbackwards) {
2421 ap_table_t *tmp = r->headers_out;
2423 /* For all HTTP/1.x responses for which we generate the message,
2424 * we need to avoid inheriting the "normal status" header fields
2425 * that may have been set by the request handler before the
2426 * error or redirect, except for Location on external redirects.
2428 r->headers_out = r->err_headers_out;
2429 r->err_headers_out = tmp;
2430 ap_clear_table(r->err_headers_out);
2432 if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) {
2433 if ((location != NULL) && *location) {
2434 ap_table_setn(r->headers_out, "Location", location);
2437 location = ""; /* avoids coredump when printing, below */
2441 r->content_language = NULL;
2442 r->content_languages = NULL;
2443 r->content_encoding = NULL;
2445 r->content_type = "text/html";
2447 if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
2448 ap_table_setn(r->headers_out, "Allow", make_allow(r));
2450 ap_send_http_header(r);
2452 if (r->header_only) {
2453 ap_finalize_request_protocol(r);
2459 if ((custom_response = ap_response_code_string(r, idx))) {
2461 * We have a custom response output. This should only be
2462 * a text-string to write back. But if the ErrorDocument
2463 * was a local redirect and the requested resource failed
2464 * for any reason, the custom_response will still hold the
2465 * redirect URL. We don't really want to output this URL
2466 * as a text message, so first check the custom response
2467 * string to ensure that it is a text-string (using the
2468 * same test used in ap_die(), i.e. does it start with a ").
2469 * If it doesn't, we've got a recursive error, so find
2470 * the original error and output that as well.
2472 if (custom_response[0] == '\"') {
2473 ap_rputs(custom_response + 1, r);
2474 ap_finalize_request_protocol(r);
2479 * Redirect failed, so get back the original error
2481 while (r->prev && (r->prev->status != HTTP_OK))
2485 const char *title = status_lines[idx];
2487 const char *error_notes;
2489 /* Accept a status_line set by a module, but only if it begins
2490 * with the 3 digit status code
2492 if (r->status_line != NULL
2493 && strlen(r->status_line) > 4 /* long enough */
2494 && ap_isdigit(r->status_line[0])
2495 && ap_isdigit(r->status_line[1])
2496 && ap_isdigit(r->status_line[2])
2497 && ap_isspace(r->status_line[3])
2498 && ap_isalnum(r->status_line[4])) {
2499 title = r->status_line;
2502 /* folks decided they didn't want the error code in the H1 text */
2507 "<HTML><HEAD>\n<TITLE>", title,
2508 "</TITLE>\n</HEAD><BODY>\n<H1>", h1, "</H1>\n",
2512 case HTTP_MOVED_PERMANENTLY:
2513 case HTTP_MOVED_TEMPORARILY:
2514 case HTTP_TEMPORARY_REDIRECT:
2515 ap_rvputs(r, "The document has moved <A HREF=\"",
2516 ap_escape_html(r->pool, location), "\">here</A>.<P>\n",
2519 case HTTP_SEE_OTHER:
2520 ap_rvputs(r, "The answer to your request is located <A HREF=\"",
2521 ap_escape_html(r->pool, location), "\">here</A>.<P>\n",
2524 case HTTP_USE_PROXY:
2525 ap_rvputs(r, "This resource is only accessible "
2526 "through the proxy\n",
2527 ap_escape_html(r->pool, location),
2528 "<BR>\nYou will need to ",
2529 "configure your client to use that proxy.<P>\n", NULL);
2531 case HTTP_PROXY_AUTHENTICATION_REQUIRED:
2533 ap_rputs("This server could not verify that you\n"
2534 "are authorized to access the document\n"
2535 "requested. Either you supplied the wrong\n"
2536 "credentials (e.g., bad password), or your\n"
2537 "browser doesn't understand how to supply\n"
2538 "the credentials required.<P>\n", r);
2541 ap_rputs("Your browser sent a request that "
2542 "this server could not understand.<P>\n", r);
2543 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2544 ap_rvputs(r, error_notes, "<P>\n", NULL);
2547 case HTTP_FORBIDDEN:
2548 ap_rvputs(r, "You don't have permission to access ",
2549 ap_escape_html(r->pool, r->uri),
2550 "\non this server.<P>\n", NULL);
2553 ap_rvputs(r, "The requested URL ",
2554 ap_escape_html(r->pool, r->uri),
2555 " was not found on this server.<P>\n", NULL);
2557 case METHOD_NOT_ALLOWED:
2558 ap_rvputs(r, "The requested method ", r->method,
2560 "for the URL ", ap_escape_html(r->pool, r->uri),
2563 case NOT_ACCEPTABLE:
2565 "An appropriate representation of the "
2566 "requested resource ",
2567 ap_escape_html(r->pool, r->uri),
2568 " could not be found on this server.<P>\n", NULL);
2570 case MULTIPLE_CHOICES:
2573 if ((list = ap_table_get(r->notes, "variant-list")))
2577 case LENGTH_REQUIRED:
2578 ap_rvputs(r, "A request of the requested method ", r->method,
2579 " requires a valid Content-length.<P>\n", NULL);
2580 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2581 ap_rvputs(r, error_notes, "<P>\n", NULL);
2584 case PRECONDITION_FAILED:
2585 ap_rvputs(r, "The precondition on the request for the URL ",
2586 ap_escape_html(r->pool, r->uri),
2587 " evaluated to false.<P>\n", NULL);
2589 case HTTP_NOT_IMPLEMENTED:
2590 ap_rvputs(r, ap_escape_html(r->pool, r->method), " to ",
2591 ap_escape_html(r->pool, r->uri),
2592 " not supported.<P>\n", NULL);
2593 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2594 ap_rvputs(r, error_notes, "<P>\n", NULL);
2598 ap_rputs("The proxy server received an invalid\015\012"
2599 "response from an upstream server.<P>\015\012", r);
2600 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2601 ap_rvputs(r, error_notes, "<P>\n", NULL);
2604 case VARIANT_ALSO_VARIES:
2605 ap_rvputs(r, "A variant for the requested resource\n<PRE>\n",
2606 ap_escape_html(r->pool, r->uri),
2607 "\n</PRE>\nis itself a negotiable resource. "
2608 "This indicates a configuration error.<P>\n", NULL);
2610 case HTTP_REQUEST_TIME_OUT:
2611 ap_rputs("I'm tired of waiting for your request.\n", r);
2614 ap_rvputs(r, "The requested resource<BR>",
2615 ap_escape_html(r->pool, r->uri),
2616 "<BR>\nis no longer available on this server ",
2617 "and there is no forwarding address.\n",
2618 "Please remove all references to this resource.\n",
2621 case HTTP_REQUEST_ENTITY_TOO_LARGE:
2622 ap_rvputs(r, "The requested resource<BR>",
2623 ap_escape_html(r->pool, r->uri), "<BR>\n",
2624 "does not allow request data with ", r->method,
2625 " requests, or the amount of data provided in\n",
2626 "the request exceeds the capacity limit.\n", NULL);
2628 case HTTP_REQUEST_URI_TOO_LARGE:
2629 ap_rputs("The requested URL's length exceeds the capacity\n"
2630 "limit for this server.<P>\n", r);
2631 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2632 ap_rvputs(r, error_notes, "<P>\n", NULL);
2635 case HTTP_UNSUPPORTED_MEDIA_TYPE:
2636 ap_rputs("The supplied request data is not in a format\n"
2637 "acceptable for processing by this resource.\n", r);
2639 case HTTP_RANGE_NOT_SATISFIABLE:
2640 ap_rputs("None of the range-specifier values in the Range\n"
2641 "request-header field overlap the current extent\n"
2642 "of the selected resource.\n", r);
2644 case HTTP_EXPECTATION_FAILED:
2645 ap_rvputs(r, "The expectation given in the Expect request-header"
2646 "\nfield could not be met by this server.<P>\n"
2647 "The client sent<PRE>\n Expect: ",
2648 ap_table_get(r->headers_in, "Expect"), "\n</PRE>\n"
2649 "but we only allow the 100-continue expectation.\n",
2652 case HTTP_UNPROCESSABLE_ENTITY:
2653 ap_rputs("The server understands the media type of the\n"
2654 "request entity, but was unable to process the\n"
2655 "contained instructions.\n", r);
2658 ap_rputs("The requested resource is currently locked.\n"
2659 "The lock must be released or proper identification\n"
2660 "given before the method can be applied.\n", r);
2662 case HTTP_FAILED_DEPENDENCY:
2663 ap_rputs("The method could not be performed on the resource\n"
2664 "because the requested action depended on another\n"
2665 "action and that other action failed.\n", r);
2667 case HTTP_INSUFFICIENT_STORAGE:
2668 ap_rputs("The method could not be performed on the resource\n"
2669 "because the server is unable to store the\n"
2670 "representation needed to successfully complete the\n"
2671 "request. There is insufficient free space left in\n"
2672 "your storage allocation.\n", r);
2674 case HTTP_SERVICE_UNAVAILABLE:
2675 ap_rputs("The server is temporarily unable to service your\n"
2676 "request due to maintenance downtime or capacity\n"
2677 "problems. Please try again later.\n", r);
2679 case HTTP_GATEWAY_TIME_OUT:
2680 ap_rputs("The proxy server did not receive a timely response\n"
2681 "from the upstream server.\n", r);
2683 case HTTP_NOT_EXTENDED:
2684 ap_rputs("A mandatory extension policy in the request is not\n"
2685 "accepted by the server for this resource.\n", r);
2687 default: /* HTTP_INTERNAL_SERVER_ERROR */
2689 * This comparison to expose error-notes could be modified to
2690 * use a configuration directive and export based on that
2691 * directive. For now "*" is used to designate an error-notes
2692 * that is totally safe for any user to see (ie lacks paths,
2693 * database passwords, etc.)
2695 if (((error_notes = ap_table_get(r->notes, "error-notes")) != NULL)
2696 && (h1 = ap_table_get(r->notes, "verbose-error-to")) != NULL
2697 && (strcmp(h1, "*") == 0)) {
2698 ap_rvputs(r, error_notes, "<P>\n", NULL);
2701 ap_rvputs(r, "The server encountered an internal error or\n"
2702 "misconfiguration and was unable to complete\n"
2703 "your request.<P>\n"
2704 "Please contact the server administrator,\n ",
2705 ap_escape_html(r->pool, r->server->server_admin),
2706 " and inform them of the time the error occurred,\n"
2707 "and anything you might have done that may have\n"
2708 "caused the error.<P>\n"
2709 "More information about this error may be available\n"
2710 "in the server error log.<P>\n", NULL);
2713 * It would be nice to give the user the information they need to
2714 * fix the problem directly since many users don't have access to
2715 * the error_log (think University sites) even though they can easily
2716 * get this error by misconfiguring an htaccess file. However, the
2717 * error notes tend to include the real file pathname in this case,
2718 * which some people consider to be a breach of privacy. Until we
2719 * can figure out a way to remove the pathname, leave this commented.
2721 * if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2722 * ap_rvputs(r, error_notes, "<P>\n", NULL);
2728 if (recursive_error) {
2729 ap_rvputs(r, "<P>Additionally, a ",
2730 status_lines[ap_index_of_response(recursive_error)],
2731 "\nerror was encountered while trying to use an "
2732 "ErrorDocument to handle the request.\n", NULL);
2734 ap_rputs(ap_psignature("<HR>\n", r), r);
2735 ap_rputs("</BODY></HTML>\n", r);
2737 ap_finalize_request_protocol(r);
2741 IMPLEMENT_HOOK_RUN_ALL(int,post_read_request,(request_rec *r),(r),OK,DECLINED)
2742 IMPLEMENT_HOOK_RUN_ALL(int,log_transaction,(request_rec *r),(r),OK,DECLINED)
2743 IMPLEMENT_HOOK_RUN_FIRST(const char *,http_method,(const request_rec *r),(r),
2745 IMPLEMENT_HOOK_RUN_FIRST(unsigned short,default_port,(const request_rec *r),