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 */
77 #include "http_conf_globals.h"
79 #define SET_BYTES_SENT(r) \
80 do { if (r->sent_bodyct) \
81 ap_bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \
85 static int parse_byterange(char *range, long clength, long *start, long *end)
87 char *dash = strchr(range, '-');
92 if ((dash == range)) {
93 /* In the form "-5" */
94 *start = clength - atol(dash + 1);
100 *start = atol(range);
116 return (*start > 0 || *end < clength - 1);
119 static int internal_byterange(int, long *, request_rec *, const char **, long *,
122 API_EXPORT(int) ap_set_byterange(request_rec *r)
124 const char *range, *if_range, *match;
125 long range_start, range_end;
127 if (!r->clength || r->assbackwards)
130 /* Check for Range request-header (HTTP/1.1) or Request-Range for
131 * backwards-compatibility with second-draft Luotonen/Franks
132 * byte-ranges (e.g. Netscape Navigator 2-3).
134 * We support this form, with Request-Range, and (farther down) we
135 * send multipart/x-byteranges instead of multipart/byteranges for
136 * Request-Range based requests to work around a bug in Netscape
137 * Navigator 2-3 and MSIE 3.
140 if (!(range = ap_table_get(r->headers_in, "Range")))
141 range = ap_table_get(r->headers_in, "Request-Range");
143 if (!range || strncasecmp(range, "bytes=", 6)) {
147 /* Check the If-Range header for Etag or Date.
148 * Note that this check will return false (as required) if either
149 * of the two etags are weak.
151 if ((if_range = ap_table_get(r->headers_in, "If-Range"))) {
152 if (if_range[0] == '"') {
153 if (!(match = ap_table_get(r->headers_out, "Etag")) ||
154 (strcmp(if_range, match) != 0))
157 else if (!(match = ap_table_get(r->headers_out, "Last-Modified")) ||
158 (strcmp(if_range, match) != 0))
162 if (!strchr(range, ',')) {
164 if (!parse_byterange(ap_pstrdup(r->pool, range + 6), r->clength,
165 &range_start, &range_end))
170 ap_table_setn(r->headers_out, "Content-Range",
171 ap_psprintf(r->pool, "bytes %ld-%ld/%ld",
172 range_start, range_end, r->clength));
173 ap_table_setn(r->headers_out, "Content-Length",
174 ap_psprintf(r->pool, "%ld", range_end - range_start + 1));
177 /* a multiple range */
178 const char *r_range = ap_pstrdup(r->pool, range + 6);
182 r->boundary = ap_psprintf(r->pool, "%lx%lx",
183 r->request_time, (long) getpid());
184 while (internal_byterange(0, &tlength, r, &r_range, NULL, NULL));
185 ap_table_setn(r->headers_out, "Content-Length",
186 ap_psprintf(r->pool, "%ld", tlength));
189 r->status = PARTIAL_CONTENT;
190 r->range = range + 6;
195 API_EXPORT(int) ap_each_byterange(request_rec *r, long *offset, long *length)
197 return internal_byterange(1, NULL, r, &r->range, offset, length);
200 /* If this function is called with realreq=1, it will spit out
201 * the correct headers for a byterange chunk, and set offset and
202 * length to the positions they should be.
204 * If it is called with realreq=0, it will add to tlength the length
205 * it *would* have used with realreq=1.
207 * Either case will return 1 if it should be called again, and 0
210 static int internal_byterange(int realreq, long *tlength, request_rec *r,
211 const char **r_range, long *offset, long *length)
213 long range_start, range_end;
217 if (r->byterange > 1) {
219 ap_rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL);
221 *tlength += 4 + strlen(r->boundary) + 4;
226 range = ap_getword(r->pool, r_range, ',');
227 if (!parse_byterange(range, r->clength, &range_start, &range_end))
229 return internal_byterange(realreq, tlength, r, r_range, offset,
232 if (r->byterange > 1) {
233 const char *ct = r->content_type ? r->content_type : ap_default_type(r);
234 char ts[MAX_STRING_LEN];
236 ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end,
239 ap_rvputs(r, "\015\012--", r->boundary, "\015\012Content-type: ",
240 ct, "\015\012Content-range: bytes ", ts, "\015\012\015\012",
243 *tlength += 4 + strlen(r->boundary) + 16 + strlen(ct) + 23 +
248 *offset = range_start;
249 *length = range_end - range_start + 1;
252 *tlength += range_end - range_start + 1;
257 API_EXPORT(int) ap_set_content_length(request_rec *r, long clength)
259 r->clength = clength;
260 ap_table_setn(r->headers_out, "Content-Length", ap_psprintf(r->pool, "%ld", clength));
264 API_EXPORT(int) ap_set_keepalive(request_rec *r)
267 int wimpy = ap_find_token(r->pool,
268 ap_table_get(r->headers_out, "Connection"), "close");
269 const char *conn = ap_table_get(r->headers_in, "Connection");
271 /* The following convoluted conditional determines whether or not
272 * the current connection should remain persistent after this response
273 * (a.k.a. HTTP Keep-Alive) and whether or not the output message
274 * body should use the HTTP/1.1 chunked transfer-coding. In English,
276 * IF we have not marked this connection as errored;
277 * and the response body has a defined length due to the status code
278 * being 304 or 204, the request method being HEAD, already
279 * having defined Content-Length or Transfer-Encoding: chunked, or
280 * the request version being HTTP/1.1 and thus capable of being set
281 * as chunked [we know the (r->chunked = 1) side-effect is ugly];
282 * and the server configuration enables keep-alive;
283 * and the server configuration has a reasonable inter-request timeout;
284 * and there is no maximum # requests or the max hasn't been reached;
285 * and the response status does not require a close;
286 * and the response generator has not already indicated close;
287 * and the client did not request non-persistence (Connection: close);
288 * and we haven't been configured to ignore the buggy twit
289 * or they're a buggy twit coming through a HTTP/1.1 proxy
290 * and the client is requesting an HTTP/1.0-style keep-alive
291 * or the client claims to be HTTP/1.1 compliant (perhaps a proxy);
292 * THEN we can be persistent, which requires more headers be output.
294 * Note that the condition evaluation order is extremely important.
296 if ((r->connection->keepalive != -1) &&
297 ((r->status == HTTP_NOT_MODIFIED) ||
298 (r->status == HTTP_NO_CONTENT) ||
300 ap_table_get(r->headers_out, "Content-Length") ||
301 ap_find_last_token(r->pool,
302 ap_table_get(r->headers_out, "Transfer-Encoding"),
304 ((r->proto_num >= HTTP_VERSION(1,1)) &&
305 (r->chunked = 1))) && /* THIS CODE IS CORRECT, see comment above. */
306 r->server->keep_alive &&
307 (r->server->keep_alive_timeout > 0) &&
308 ((r->server->keep_alive_max == 0) ||
309 (r->server->keep_alive_max > r->connection->keepalives)) &&
310 !ap_status_drops_connection(r->status) &&
312 !ap_find_token(r->pool, conn, "close") &&
313 (!ap_table_get(r->subprocess_env, "nokeepalive") ||
314 ap_table_get(r->headers_in, "Via")) &&
315 ((ka_sent = ap_find_token(r->pool, conn, "keep-alive")) ||
316 (r->proto_num >= HTTP_VERSION(1,1)))
318 int left = r->server->keep_alive_max - r->connection->keepalives;
320 r->connection->keepalive = 1;
321 r->connection->keepalives++;
323 /* If they sent a Keep-Alive token, send one back */
325 if (r->server->keep_alive_max)
326 ap_table_setn(r->headers_out, "Keep-Alive",
327 ap_psprintf(r->pool, "timeout=%d, max=%d",
328 r->server->keep_alive_timeout, left));
330 ap_table_setn(r->headers_out, "Keep-Alive",
331 ap_psprintf(r->pool, "timeout=%d",
332 r->server->keep_alive_timeout));
333 ap_table_mergen(r->headers_out, "Connection", "Keep-Alive");
339 /* Otherwise, we need to indicate that we will be closing this
340 * connection immediately after the current response.
342 * We only really need to send "close" to HTTP/1.1 clients, but we
343 * always send it anyway, because a broken proxy may identify itself
344 * as HTTP/1.0, but pass our request along with our HTTP/1.1 tag
345 * to a HTTP/1.1 client. Better safe than sorry.
348 ap_table_mergen(r->headers_out, "Connection", "close");
350 r->connection->keepalive = 0;
356 * Return the latest rational time from a request/mtime (modification time)
357 * pair. We return the mtime unless it's in the future, in which case we
358 * return the current time. We use the request time as a reference in order
359 * to limit the number of calls to time(). We don't check for futurosity
360 * unless the mtime is at least as new as the reference.
362 API_EXPORT(time_t) ap_rationalize_mtime(request_rec *r, time_t mtime)
366 /* For all static responses, it's almost certain that the file was
367 * last modified before the beginning of the request. So there's
368 * no reason to call time(NULL) again. But if the response has been
369 * created on demand, then it might be newer than the time the request
370 * started. In this event we really have to call time(NULL) again
371 * so that we can give the clients the most accurate Last-Modified. If we
372 * were given a time in the future, we return the current time - the
373 * Last-Modified can't be in the future.
375 now = (mtime < r->request_time) ? r->request_time : time(NULL);
376 return (mtime > now) ? now : mtime;
379 API_EXPORT(int) ap_meets_conditions(request_rec *r)
381 const char *etag = ap_table_get(r->headers_out, "ETag");
382 const char *if_match, *if_modified_since, *if_unmodified, *if_nonematch;
385 /* Check for conditional requests --- note that we only want to do
386 * this if we are successful so far and we are not processing a
387 * subrequest or an ErrorDocument.
389 * The order of the checks is important, since ETag checks are supposed
390 * to be more accurate than checks relative to the modification time.
391 * However, not all documents are guaranteed to *have* ETags, and some
392 * might have Last-Modified values w/o ETags, so this gets a little
396 if (!ap_is_HTTP_SUCCESS(r->status) || r->no_local_copy) {
400 mtime = (r->mtime != 0) ? r->mtime : time(NULL);
402 /* If an If-Match request-header field was given
403 * AND the field value is not "*" (meaning match anything)
404 * AND if our strong ETag does not match any entity tag in that field,
405 * respond with a status of 412 (Precondition Failed).
407 if ((if_match = ap_table_get(r->headers_in, "If-Match")) != NULL) {
408 if (if_match[0] != '*' &&
409 (etag == NULL || etag[0] == 'W' ||
410 !ap_find_list_item(r->pool, if_match, etag))) {
411 return HTTP_PRECONDITION_FAILED;
415 /* Else if a valid If-Unmodified-Since request-header field was given
416 * AND the requested resource has been modified since the time
417 * specified in this field, then the server MUST
418 * respond with a status of 412 (Precondition Failed).
420 if_unmodified = ap_table_get(r->headers_in, "If-Unmodified-Since");
421 if (if_unmodified != NULL) {
422 time_t ius = ap_parseHTTPdate(if_unmodified);
424 if ((ius != BAD_DATE) && (mtime > ius)) {
425 return HTTP_PRECONDITION_FAILED;
430 /* If an If-None-Match request-header field was given
431 * AND the field value is "*" (meaning match anything)
432 * OR our ETag matches any of the entity tags in that field, fail.
434 * If the request method was GET or HEAD, failure means the server
435 * SHOULD respond with a 304 (Not Modified) response.
436 * For all other request methods, failure means the server MUST
437 * respond with a status of 412 (Precondition Failed).
439 * GET or HEAD allow weak etag comparison, all other methods require
440 * strong comparison. We can only use weak if it's not a range request.
442 if_nonematch = ap_table_get(r->headers_in, "If-None-Match");
443 if (if_nonematch != NULL) {
444 if (r->method_number == M_GET) {
445 if (if_nonematch[0] == '*')
446 return HTTP_NOT_MODIFIED;
448 if (ap_table_get(r->headers_in, "Range")) {
449 if (etag[0] != 'W' &&
450 ap_find_list_item(r->pool, if_nonematch, etag)) {
451 return HTTP_NOT_MODIFIED;
454 else if (strstr(if_nonematch, etag)) {
455 return HTTP_NOT_MODIFIED;
459 else if (if_nonematch[0] == '*' ||
461 ap_find_list_item(r->pool, if_nonematch, etag))) {
462 return HTTP_PRECONDITION_FAILED;
465 /* Else if a valid If-Modified-Since request-header field was given
466 * AND it is a GET or HEAD request
467 * AND the requested resource has not been modified since the time
468 * specified in this field, then the server MUST
469 * respond with a status of 304 (Not Modified).
470 * A date later than the server's current request time is invalid.
472 else if ((r->method_number == M_GET)
473 && ((if_modified_since =
474 ap_table_get(r->headers_in, "If-Modified-Since")) != NULL)) {
475 time_t ims = ap_parseHTTPdate(if_modified_since);
477 if ((ims >= mtime) && (ims <= r->request_time)) {
478 return HTTP_NOT_MODIFIED;
485 * Construct an entity tag (ETag) from resource information. If it's a real
486 * file, build in some of the file characteristics. If the modification time
487 * is newer than (request-time minus 1 second), mark the ETag as weak - it
488 * could be modified again in as short an interval. We rationalize the
489 * modification time we're given to keep it from being in the future.
491 API_EXPORT(char *) ap_make_etag(request_rec *r, int force_weak)
497 * Make an ETag header out of various pieces of information. We use
498 * the last-modified date and, if we have a real file, the
499 * length and inode number - note that this doesn't have to match
500 * the content-length (i.e. includes), it just has to be unique
503 * If the request was made within a second of the last-modified date,
504 * we send a weak tag instead of a strong one, since it could
505 * be modified again later in the second, and the validation
506 * would be incorrect.
509 weak = ((r->request_time - r->mtime > 1) && !force_weak) ? "" : "W/";
511 if (r->finfo.st_mode != 0) {
512 etag = ap_psprintf(r->pool,
513 "%s\"%lx-%lx-%lx\"", weak,
514 (unsigned long) r->finfo.st_ino,
515 (unsigned long) r->finfo.st_size,
516 (unsigned long) r->mtime);
519 etag = ap_psprintf(r->pool, "%s\"%lx\"", weak,
520 (unsigned long) r->mtime);
526 API_EXPORT(void) ap_set_etag(request_rec *r)
529 char *variant_etag, *vlv;
532 if (!r->vlist_validator) {
533 etag = ap_make_etag(r, 0);
536 /* If we have a variant list validator (vlv) due to the
537 * response being negotiated, then we create a structured
538 * entity tag which merges the variant etag with the variant
539 * list validator (vlv). This merging makes revalidation
540 * somewhat safer, ensures that caches which can deal with
541 * Vary will (eventually) be updated if the set of variants is
542 * changed, and is also a protocol requirement for transparent
543 * content negotiation.
546 /* if the variant list validator is weak, we make the whole
547 * structured etag weak. If we would not, then clients could
548 * have problems merging range responses if we have different
549 * variants with the same non-globally-unique strong etag.
552 vlv = r->vlist_validator;
553 vlv_weak = (vlv[0] == 'W');
555 variant_etag = ap_make_etag(r, vlv_weak);
557 /* merge variant_etag and vlv into a structured etag */
559 variant_etag[strlen(variant_etag) - 1] = '\0';
564 etag = ap_pstrcat(r->pool, variant_etag, ";", vlv, NULL);
567 ap_table_setn(r->headers_out, "ETag", etag);
571 * This function sets the Last-Modified output header field to the value
572 * of the mtime field in the request structure - rationalized to keep it from
573 * being in the future.
575 API_EXPORT(void) ap_set_last_modified(request_rec *r)
577 time_t mod_time = ap_rationalize_mtime(r, r->mtime);
579 ap_table_setn(r->headers_out, "Last-Modified",
580 ap_gm_timestr_822(r->pool, mod_time));
583 /* Get the method number associated with the given string, assumed to
584 * contain an HTTP method. Returns M_INVALID if not recognized.
586 * This is the first step toward placing method names in a configurable
587 * list. Hopefully it (and other routines) can eventually be moved to
588 * something like a mod_http_methods.c, complete with config stuff.
590 API_EXPORT(int) ap_method_number_of(const char *method)
594 if (strcmp(method, "HEAD") == 0)
595 return M_GET; /* see header_only in request_rec */
598 if (strcmp(method, "GET") == 0)
602 if (strcmp(method, "POST") == 0)
604 if (strcmp(method, "PUT") == 0)
606 if (strcmp(method, "PATCH") == 0)
608 if (strcmp(method, "PROPFIND") == 0)
610 if (strcmp(method, "PROPPATCH") == 0)
614 if (strcmp(method, "DELETE") == 0)
618 if (strcmp(method, "CONNECT") == 0)
620 if (strcmp(method, "COPY") == 0)
624 if (strcmp(method, "MKCOL") == 0)
626 if (strcmp(method, "MOVE") == 0)
630 if (strcmp(method, "OPTIONS") == 0)
634 if (strcmp(method, "TRACE") == 0)
638 if (strcmp(method, "LOCK") == 0)
642 if (strcmp(method, "UNLOCK") == 0)
649 /* Get a line of protocol input, including any continuation lines
650 * caused by MIME folding (or broken clients) if fold != 0, and place it
651 * in the buffer s, of size n bytes, without the ending newline.
653 * Returns -1 on error, or the length of s.
655 * Note: Because bgets uses 1 char for newline and 1 char for NUL,
656 * the most we can get is (n - 2) actual characters if it
657 * was ended by a newline, or (n - 1) characters if the line
658 * length exceeded (n - 1). So, if the result == (n - 1),
659 * then the actual input line exceeded the buffer length,
660 * and it would be a good idea for the caller to puke 400 or 414.
662 static int getline(char *s, int n, BUFF *in, int fold)
671 retval = ap_bgets(pos, n, in); /* retval == -1 if error, 0 if EOF */
674 return ((retval < 0) && (total == 0)) ? -1 : total;
676 /* retval is the number of characters read, not including NUL */
678 n -= retval; /* Keep track of how much of s is full */
679 pos += (retval - 1); /* and where s ends */
680 total += retval; /* and how long s has become */
682 if (*pos == '\n') { /* Did we get a full line of input? */
684 * Trim any extra trailing spaces or tabs except for the first
685 * space or tab at the beginning of a blank string. This makes
686 * it much easier to check field values for exact matches, and
687 * saves memory as well. Terminate string at end of line.
689 while (pos > (s + 1) && (*(pos - 1) == ' ' || *(pos - 1) == '\t')) {
690 --pos; /* trim extra trailing spaces or tabs */
691 --total; /* but not one at the beginning of line */
699 return total; /* if not, input line exceeded buffer size */
701 /* Continue appending if line folding is desired and
702 * the last line was not empty and we have room in the buffer and
703 * the next line begins with a continuation character.
705 } while (fold && (retval != 1) && (n > 1)
706 && (ap_blookc(&next, in) == 1)
707 && ((next == ' ') || (next == '\t')));
712 /* parse_uri: break apart the uri
714 * - sets r->args to rest after '?' (or NULL if no '?')
715 * - sets r->uri to request uri (without r->args part)
716 * - sets r->hostname (if not set already) from request (scheme://host:port)
718 CORE_EXPORT(void) ap_parse_uri(request_rec *r, const char *uri)
720 int status = HTTP_OK;
722 r->unparsed_uri = ap_pstrdup(r->pool, uri);
724 if (r->method_number == M_CONNECT) {
725 status = ap_parse_hostinfo_components(r->pool, uri, &r->parsed_uri);
727 /* Simple syntax Errors in URLs are trapped by parse_uri_components(). */
728 status = ap_parse_uri_components(r->pool, uri, &r->parsed_uri);
731 if (ap_is_HTTP_SUCCESS(status)) {
732 /* if it has a scheme we may need to do absoluteURI vhost stuff */
733 if (r->parsed_uri.scheme
734 && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r))) {
735 r->hostname = r->parsed_uri.hostname;
736 } else if (r->method_number == M_CONNECT) {
737 r->hostname = r->parsed_uri.hostname;
739 r->args = r->parsed_uri.query;
740 r->uri = r->parsed_uri.path ? r->parsed_uri.path
741 : ap_pstrdup(r->pool, "/");
742 #if defined(OS2) || defined(WIN32)
743 /* Handle path translations for OS/2 and plug security hole.
744 * This will prevent "http://www.wherever.com/..\..\/" from
745 * returning a directory for the root drive.
750 for (x = r->uri; (x = strchr(x, '\\')) != NULL; )
753 #endif /* OS2 || WIN32 */
758 r->status = status; /* set error status */
759 r->uri = ap_pstrdup(r->pool, uri);
763 static int read_request_line(request_rec *r)
765 char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* getline's two extra for \n\0 */
768 conn_rec *conn = r->connection;
769 int major = 1, minor = 0; /* Assume HTTP/1.0 if non-"HTTP" protocol */
772 /* Read past empty lines until we get a real request line,
773 * a read error, the connection closes (EOF), or we timeout.
775 * We skip empty lines because browsers have to tack a CRLF on to the end
776 * of POSTs to support old CERN webservers. But note that we may not
777 * have flushed any previous response completely to the client yet.
778 * We delay the flush as long as possible so that we can improve
779 * performance for clients that are pipelining requests. If a request
780 * is pipelined then we won't block during the (implicit) read() below.
781 * If the requests aren't pipelined, then the client is still waiting
782 * for the final buffer flush from us, and we will block in the implicit
783 * read(). B_SAFEREAD ensures that the BUFF layer flushes if it will
784 * have to block during a read.
786 ap_bsetflag(conn->client, B_SAFEREAD, 1);
787 while ((len = getline(l, sizeof(l), conn->client, 0)) <= 0) {
788 if ((len < 0) || ap_bgetflag(conn->client, B_EOF)) {
789 ap_bsetflag(conn->client, B_SAFEREAD, 0);
790 /* this is a hack to make sure that request time is set,
791 * it's not perfect, but it's better than nothing
793 r->request_time = time(0);
797 /* we've probably got something to do, ignore graceful restart requests */
799 signal(SIGUSR1, SIG_IGN);
802 ap_bsetflag(conn->client, B_SAFEREAD, 0);
804 r->request_time = time(NULL);
805 r->the_request = ap_pstrdup(r->pool, l);
806 r->method = ap_getword_white(r->pool, &ll);
807 uri = ap_getword_white(r->pool, &ll);
809 /* Provide quick information about the request method as soon as known */
811 r->method_number = ap_method_number_of(r->method);
812 if (r->method_number == M_GET && r->method[0] == 'H') {
816 ap_parse_uri(r, uri);
818 /* getline returns (size of max buffer - 1) if it fills up the
819 * buffer before finding the end-of-line. This is only going to
820 * happen if it exceeds the configured limit for a request-line.
822 if (len > r->server->limit_req_line) {
823 r->status = HTTP_REQUEST_URI_TOO_LARGE;
824 r->proto_num = HTTP_VERSION(1,0);
825 r->protocol = ap_pstrdup(r->pool, "HTTP/1.0");
829 r->assbackwards = (ll[0] == '\0');
830 r->protocol = ap_pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9");
832 if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
833 && minor < HTTP_VERSION(1,0)) /* don't allow HTTP/0.1000 */
834 r->proto_num = HTTP_VERSION(major, minor);
836 r->proto_num = HTTP_VERSION(1,0);
841 static void get_mime_headers(request_rec *r)
843 char field[DEFAULT_LIMIT_REQUEST_FIELDSIZE + 2]; /* getline's two extra */
844 conn_rec *c = r->connection;
848 unsigned int fields_read = 0;
851 /* We'll use ap_overlap_tables later to merge these into r->headers_in. */
852 tmp_headers = ap_make_table(r->pool, 50);
855 * Read header lines until we get the empty separator line, a read error,
856 * the connection closes (EOF), reach the server limit, or we timeout.
858 while ((len = getline(field, sizeof(field), c->client, 1)) > 0) {
860 if (r->server->limit_req_fields &&
861 (++fields_read > r->server->limit_req_fields)) {
862 r->status = HTTP_BAD_REQUEST;
863 ap_table_setn(r->notes, "error-notes",
864 "The number of request header fields exceeds "
865 "this server's limit.<P>\n");
868 /* getline returns (size of max buffer - 1) if it fills up the
869 * buffer before finding the end-of-line. This is only going to
870 * happen if it exceeds the configured limit for a field size.
872 if (len > r->server->limit_req_fieldsize) {
873 r->status = HTTP_BAD_REQUEST;
874 ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
875 "Size of a request header field exceeds server limit.<P>\n"
876 "<PRE>\n", field, "</PRE>\n", NULL));
879 copy = ap_palloc(r->pool, len + 1);
880 memcpy(copy, field, len + 1);
882 if (!(value = strchr(copy, ':'))) { /* Find the colon separator */
883 r->status = HTTP_BAD_REQUEST; /* or abort the bad request */
884 ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
885 "Request header field is missing colon separator.<P>\n"
886 "<PRE>\n", copy, "</PRE>\n", NULL));
892 while (*value == ' ' || *value == '\t')
893 ++value; /* Skip to start of value */
895 ap_table_addn(tmp_headers, copy, value);
898 ap_overlap_tables(r->headers_in, tmp_headers, AP_OVERLAP_TABLES_MERGE);
901 request_rec *ap_read_request(conn_rec *conn)
908 p = ap_make_sub_pool(conn->pool);
909 r = ap_pcalloc(p, sizeof(request_rec));
911 r->connection = conn;
912 conn->server = conn->base_server;
913 r->server = conn->server;
915 conn->keptalive = conn->keepalive == 1;
919 conn->ap_auth_type = NULL;
921 r->headers_in = ap_make_table(r->pool, 50);
922 r->subprocess_env = ap_make_table(r->pool, 50);
923 r->headers_out = ap_make_table(r->pool, 12);
924 r->err_headers_out = ap_make_table(r->pool, 5);
925 r->notes = ap_make_table(r->pool, 5);
927 r->request_config = ap_create_request_config(r->pool);
928 r->per_dir_config = r->server->lookup_defaults;
930 r->sent_bodyct = 0; /* bytect isn't for body */
933 r->read_body = REQUEST_NO_BODY;
935 r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
936 r->the_request = NULL;
938 #ifdef CHARSET_EBCDIC
939 ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
942 /* Get the request... */
944 ap_keepalive_timeout("read request line", r);
945 if (!read_request_line(r)) {
947 if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
949 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
950 "request failed: URI too long");
951 ap_send_error_response(r, 0);
952 ap_log_transaction(r);
957 if (!r->assbackwards) {
958 ap_hard_timeout("read request headers", r);
961 if (r->status != HTTP_REQUEST_TIME_OUT) {
962 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
963 "request failed: error reading the headers");
964 ap_send_error_response(r, 0);
965 ap_log_transaction(r);
972 if (r->header_only) {
974 * Client asked for headers only with HTTP/0.9, which doesn't send
975 * headers! Have to dink things just to make sure the error message
978 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
979 "client sent invalid HTTP/0.9 request: HEAD %s",
982 r->status = HTTP_BAD_REQUEST;
983 ap_send_error_response(r, 0);
984 ap_log_transaction(r);
989 r->status = HTTP_OK; /* Until further notice. */
991 /* update what we think the virtual host is based on the headers we've
994 ap_update_vhost_from_headers(r);
996 /* we may have switched to another server */
997 r->per_dir_config = r->server->lookup_defaults;
999 conn->keptalive = 0; /* We now have a request to play with */
1001 if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1,1))) ||
1002 ((r->proto_num == HTTP_VERSION(1,1)) &&
1003 !ap_table_get(r->headers_in, "Host"))) {
1005 * Client sent us an HTTP/1.1 or later request without telling us the
1006 * hostname, either with a full URL or a Host: header. We therefore
1007 * need to (as per the 1.1 spec) send an error. As a special case,
1008 * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain
1009 * a Host: header, and the server MUST respond with 400 if it doesn't.
1011 r->status = HTTP_BAD_REQUEST;
1012 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1013 "client sent HTTP/1.1 request without hostname "
1014 "(see RFC2068 section 9, and 14.23): %s", r->uri);
1015 ap_send_error_response(r, 0);
1016 ap_log_transaction(r);
1019 if (((expect = ap_table_get(r->headers_in, "Expect")) != NULL) &&
1020 (expect[0] != '\0')) {
1022 * The Expect header field was added to HTTP/1.1 after RFC 2068
1023 * as a means to signal when a 100 response is desired and,
1024 * unfortunately, to signal a poor man's mandatory extension that
1025 * the server must understand or return 417 Expectation Failed.
1027 if (strcasecmp(expect, "100-continue") == 0) {
1028 r->expecting_100 = 1;
1031 r->status = HTTP_EXPECTATION_FAILED;
1032 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r,
1033 "client sent an unrecognized expectation value of "
1034 "Expect: %s", expect);
1035 ap_send_error_response(r, 0);
1036 (void) ap_discard_request_body(r);
1037 ap_log_transaction(r);
1042 if ((access_status = ap_run_post_read_request(r))) {
1043 ap_die(access_status, r);
1044 ap_log_transaction(r);
1052 * A couple of other functions which initialize some of the fields of
1053 * a request structure, as appropriate for adjuncts of one kind or another
1054 * to a request in progress. Best here, rather than elsewhere, since
1055 * *someone* has to set the protocol-specific fields...
1058 void ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r)
1060 rnew->the_request = r->the_request; /* Keep original request-line */
1062 rnew->assbackwards = 1; /* Don't send headers from this. */
1063 rnew->no_local_copy = 1; /* Don't try to send USE_LOCAL_COPY for a
1065 rnew->method = "GET";
1066 rnew->method_number = M_GET;
1067 rnew->protocol = "INCLUDED";
1069 rnew->status = HTTP_OK;
1071 rnew->headers_in = r->headers_in;
1072 rnew->subprocess_env = ap_copy_table(rnew->pool, r->subprocess_env);
1073 rnew->headers_out = ap_make_table(rnew->pool, 5);
1074 rnew->err_headers_out = ap_make_table(rnew->pool, 5);
1075 rnew->notes = ap_make_table(rnew->pool, 5);
1077 rnew->expecting_100 = r->expecting_100;
1078 rnew->read_length = r->read_length;
1079 rnew->read_body = REQUEST_NO_BODY;
1081 rnew->main = (request_rec *) r;
1084 void ap_finalize_sub_req_protocol(request_rec *sub)
1086 SET_BYTES_SENT(sub->main);
1090 * Support for the Basic authentication protocol, and a bit for Digest.
1093 API_EXPORT(void) ap_note_auth_failure(request_rec *r)
1095 if (!strcasecmp(ap_auth_type(r), "Basic"))
1096 ap_note_basic_auth_failure(r);
1097 else if (!strcasecmp(ap_auth_type(r), "Digest"))
1098 ap_note_digest_auth_failure(r);
1101 API_EXPORT(void) ap_note_basic_auth_failure(request_rec *r)
1103 if (strcasecmp(ap_auth_type(r), "Basic"))
1104 ap_note_auth_failure(r);
1106 ap_table_setn(r->err_headers_out,
1107 r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
1108 ap_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), "\"",
1112 API_EXPORT(void) ap_note_digest_auth_failure(request_rec *r)
1114 ap_table_setn(r->err_headers_out,
1115 r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
1116 ap_psprintf(r->pool, "Digest realm=\"%s\", nonce=\"%lu\"",
1117 ap_auth_name(r), r->request_time));
1120 API_EXPORT(int) ap_get_basic_auth_pw(request_rec *r, const char **pw)
1122 const char *auth_line = ap_table_get(r->headers_in,
1123 r->proxyreq ? "Proxy-Authorization"
1127 if (!(t = ap_auth_type(r)) || strcasecmp(t, "Basic"))
1130 if (!ap_auth_name(r)) {
1131 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,
1132 r, "need AuthName: %s", r->uri);
1133 return SERVER_ERROR;
1137 ap_note_basic_auth_failure(r);
1138 return AUTH_REQUIRED;
1141 if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
1142 /* Client tried to authenticate using wrong auth scheme */
1143 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1144 "client used wrong authentication scheme: %s", r->uri);
1145 ap_note_basic_auth_failure(r);
1146 return AUTH_REQUIRED;
1149 /* CHARSET_EBCDIC Issue's here ?!? Compare with 32/9 instead
1150 * as we are operating on an octed stream ?
1152 while (*auth_line== ' ' || *auth_line== '\t')
1155 t = ap_pbase64decode(r->pool, auth_line);
1156 /* Note that this allocation has to be made from r->connection->pool
1157 * because it has the lifetime of the connection. The other allocations
1158 * are temporary and can be tossed away any time.
1160 r->connection->user = ap_getword_nulls (r->connection->pool, &t, ':');
1161 r->connection->ap_auth_type = "Basic";
1168 /* New Apache routine to map status codes into array indicies
1169 * e.g. 100 -> 0, 101 -> 1, 200 -> 2 ...
1170 * The number of status lines must equal the value of RESPONSE_CODES (httpd.h)
1171 * and must be listed in order.
1175 /* The second const triggers an assembler bug on UTS 2.1.
1176 * Another workaround is to move some code out of this file into another,
1177 * but this is easier. Dave Dykstra, 3/31/99
1179 static const char * status_lines[RESPONSE_CODES] =
1181 static const char * const status_lines[RESPONSE_CODES] =
1185 "101 Switching Protocols",
1191 "203 Non-Authoritative Information",
1193 "205 Reset Content",
1194 "206 Partial Content",
1196 #define LEVEL_300 11
1197 "300 Multiple Choices",
1198 "301 Moved Permanently",
1204 "307 Temporary Redirect",
1205 #define LEVEL_400 19
1207 "401 Authorization Required",
1208 "402 Payment Required",
1211 "405 Method Not Allowed",
1212 "406 Not Acceptable",
1213 "407 Proxy Authentication Required",
1214 "408 Request Time-out",
1217 "411 Length Required",
1218 "412 Precondition Failed",
1219 "413 Request Entity Too Large",
1220 "414 Request-URI Too Large",
1221 "415 Unsupported Media Type",
1222 "416 Requested Range Not Satisfiable",
1223 "417 Expectation Failed",
1228 "422 Unprocessable Entity",
1230 "424 Failed Dependency",
1231 #define LEVEL_500 44
1232 "500 Internal Server Error",
1233 "501 Method Not Implemented",
1235 "503 Service Temporarily Unavailable",
1236 "504 Gateway Time-out",
1237 "505 HTTP Version Not Supported",
1238 "506 Variant Also Negotiates",
1239 "507 Insufficient Storage",
1245 /* The index is found by its offset from the x00 code of each level.
1246 * Although this is fast, it will need to be replaced if some nutcase
1247 * decides to define a high-numbered code before the lower numbers.
1248 * If that sad event occurs, replace the code below with a linear search
1249 * from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1];
1251 API_EXPORT(int) ap_index_of_response(int status)
1253 static int shortcut[6] = {0, LEVEL_200, LEVEL_300, LEVEL_400,
1254 LEVEL_500, RESPONSE_CODES};
1257 if (status < 100) /* Below 100 is illegal for HTTP status */
1260 for (i = 0; i < 5; i++) {
1263 pos = (status + shortcut[i]);
1264 if (pos < shortcut[i + 1])
1267 return LEVEL_500; /* status unknown (falls in gap) */
1270 return LEVEL_500; /* 600 or above is also illegal */
1273 /* Send a single HTTP header field to the client. Note that this function
1274 * is used in calls to table_do(), so their interfaces are co-dependent.
1275 * In other words, don't change this one without checking table_do in alloc.c.
1276 * It returns true unless there was a write error of some kind.
1278 API_EXPORT_NONSTD(int) ap_send_header_field(request_rec *r,
1279 const char *fieldname, const char *fieldval)
1281 return (0 < ap_rvputs(r, fieldname, ": ", fieldval, "\015\012", NULL));
1284 API_EXPORT(void) ap_basic_http_header(request_rec *r)
1287 #ifdef CHARSET_EBCDIC
1288 int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
1289 #endif /*CHARSET_EBCDIC*/
1291 if (r->assbackwards)
1294 if (!r->status_line)
1295 r->status_line = status_lines[ap_index_of_response(r->status)];
1297 /* mod_proxy is only HTTP/1.0, so avoid sending HTTP/1.1 error response;
1298 * kluge around broken browsers when indicated by force-response-1.0
1301 || (r->proto_num == HTTP_VERSION(1,0)
1302 && ap_table_get(r->subprocess_env, "force-response-1.0"))) {
1304 protocol = "HTTP/1.0";
1305 r->connection->keepalive = -1;
1308 protocol = SERVER_PROTOCOL;
1310 #ifdef CHARSET_EBCDIC
1311 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
1312 #endif /*CHARSET_EBCDIC*/
1314 /* Output the HTTP/1.x Status-Line and the Date and Server fields */
1316 ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL);
1318 ap_send_header_field(r, "Date", ap_gm_timestr_822(r->pool, r->request_time));
1319 ap_send_header_field(r, "Server", ap_get_server_version());
1321 ap_table_unset(r->headers_out, "Date"); /* Avoid bogosity */
1322 ap_table_unset(r->headers_out, "Server");
1323 #ifdef CHARSET_EBCDIC
1325 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
1326 #endif /*CHARSET_EBCDIC*/
1329 /* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
1330 * have a header parsing bug. If the terminating \r\n occur starting
1331 * at offset 256, 257 or 258 of output then it will not properly parse
1332 * the headers. Curiously it doesn't exhibit this problem at 512, 513.
1333 * We are guessing that this is because their initial read of a new request
1334 * uses a 256 byte buffer, and subsequent reads use a larger buffer.
1335 * So the problem might exist at different offsets as well.
1337 * This should also work on keepalive connections assuming they use the
1338 * same small buffer for the first read of each new request.
1340 * At any rate, we check the bytes written so far and, if we are about to
1341 * tickle the bug, we instead insert a bogus padding header. Since the bug
1342 * manifests as a broken image in Navigator, users blame the server. :(
1343 * It is more expensive to check the User-Agent than it is to just add the
1344 * bytes, so we haven't used the BrowserMatch feature here.
1346 static void terminate_header(BUFF *client)
1350 ap_bgetopt(client, BO_BYTECT, &bs);
1351 if (bs >= 255 && bs <= 257)
1352 ap_bputs("X-Pad: avoid browser bug\015\012", client);
1354 ap_bputs("\015\012", client); /* Send the terminating empty line */
1357 /* Build the Allow field-value from the request handler method mask.
1358 * Note that we always allow TRACE, since it is handled below.
1360 static char *make_allow(request_rec *r)
1362 return 2 + ap_pstrcat(r->pool,
1363 (r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
1364 (r->allowed & (1 << M_POST)) ? ", POST" : "",
1365 (r->allowed & (1 << M_PUT)) ? ", PUT" : "",
1366 (r->allowed & (1 << M_DELETE)) ? ", DELETE" : "",
1367 (r->allowed & (1 << M_CONNECT)) ? ", CONNECT" : "",
1368 (r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
1369 (r->allowed & (1 << M_PATCH)) ? ", PATCH" : "",
1370 (r->allowed & (1 << M_PROPFIND)) ? ", PROPFIND" : "",
1371 (r->allowed & (1 << M_PROPPATCH)) ? ", PROPPATCH" : "",
1372 (r->allowed & (1 << M_MKCOL)) ? ", MKCOL" : "",
1373 (r->allowed & (1 << M_COPY)) ? ", COPY" : "",
1374 (r->allowed & (1 << M_MOVE)) ? ", MOVE" : "",
1375 (r->allowed & (1 << M_LOCK)) ? ", LOCK" : "",
1376 (r->allowed & (1 << M_UNLOCK)) ? ", UNLOCK" : "",
1381 API_EXPORT(int) ap_send_http_trace(request_rec *r)
1385 /* Get the original request */
1389 if ((rv = ap_setup_client_block(r, REQUEST_NO_BODY)))
1392 ap_hard_timeout("send TRACE", r);
1394 r->content_type = "message/http";
1395 ap_send_http_header(r);
1397 /* Now we recreate the request, and echo it back */
1399 ap_rvputs(r, r->the_request, "\015\012", NULL);
1401 ap_table_do((int (*) (void *, const char *, const char *))
1402 ap_send_header_field, (void *) r, r->headers_in, NULL);
1403 ap_rputs("\015\012", r);
1409 int ap_send_http_options(request_rec *r)
1411 const long int zero = 0L;
1413 if (r->assbackwards)
1416 ap_hard_timeout("send OPTIONS", r);
1418 ap_basic_http_header(r);
1420 ap_table_setn(r->headers_out, "Content-Length", "0");
1421 ap_table_setn(r->headers_out, "Allow", make_allow(r));
1422 ap_set_keepalive(r);
1424 ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
1425 (void *) r, r->headers_out, NULL);
1427 terminate_header(r->connection->client);
1430 ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
1436 * Here we try to be compatible with clients that want multipart/x-byteranges
1437 * instead of multipart/byteranges (also see above), as per HTTP/1.1. We
1438 * look for the Request-Range header (e.g. Netscape 2 and 3) as an indication
1439 * that the browser supports an older protocol. We also check User-Agent
1440 * for Microsoft Internet Explorer 3, which needs this as well.
1442 static int use_range_x(request_rec *r)
1445 return (ap_table_get(r->headers_in, "Request-Range") ||
1446 ((ua = ap_table_get(r->headers_in, "User-Agent"))
1447 && strstr(ua, "MSIE 3")));
1450 /* This routine is called by ap_table_do and merges all instances of
1451 * the passed field values into a single array that will be further
1452 * processed by some later routine. Originally intended to help split
1453 * and recombine multiple Vary fields, though it is generic to any field
1454 * consisting of comma/space-separated tokens.
1456 static int uniq_field_values(void *d, const char *key, const char *val)
1458 array_header *values;
1464 values = (array_header *)d;
1466 e = ap_pstrdup(values->pool, val);
1469 /* Find a non-empty fieldname */
1471 while (*e == ',' || ap_isspace(*e)) {
1478 while (*e != '\0' && *e != ',' && !ap_isspace(*e)) {
1485 /* Now add it to values if it isn't already represented.
1486 * Could be replaced by a ap_array_strcasecmp() if we had one.
1488 for (i = 0, strpp = (char **) values->elts; i < values->nelts;
1490 if (*strpp && strcasecmp(*strpp, start) == 0) {
1494 if (i == values->nelts) { /* if not found */
1495 *(char **)ap_push_array(values) = start;
1497 } while (*e != '\0');
1503 * Since some clients choke violently on multiple Vary fields, or
1504 * Vary fields with duplicate tokens, combine any multiples and remove
1507 static void fixup_vary(request_rec *r)
1509 array_header *varies;
1511 varies = ap_make_array(r->pool, 5, sizeof(char *));
1513 /* Extract all Vary fields from the headers_out, separate each into
1514 * its comma-separated fieldname values, and then add them to varies
1515 * if not already present in the array.
1517 ap_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
1518 (void *) varies, r->headers_out, "Vary", NULL);
1520 /* If we found any, replace old Vary fields with unique-ified value */
1522 if (varies->nelts > 0) {
1523 ap_table_setn(r->headers_out, "Vary",
1524 ap_array_pstrcat(r->pool, varies, ','));
1528 API_EXPORT(void) ap_send_http_header(request_rec *r)
1531 const long int zero = 0L;
1532 #ifdef CHARSET_EBCDIC
1533 int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
1534 #endif /*CHARSET_EBCDIC*/
1536 if (r->assbackwards) {
1538 ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
1544 * Now that we are ready to send a response, we need to combine the two
1545 * header field tables into a single table. If we don't do this, our
1546 * later attempts to set or unset a given fieldname might be bypassed.
1548 if (!ap_is_empty_table(r->err_headers_out))
1549 r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out,
1553 * Remove the 'Vary' header field if the client can't handle it.
1554 * Since this will have nasty effects on HTTP/1.1 caches, force
1555 * the response into HTTP/1.0 mode.
1557 if (ap_table_get(r->subprocess_env, "force-no-vary") != NULL) {
1558 ap_table_unset(r->headers_out, "Vary");
1559 r->proto_num = HTTP_VERSION(1,0);
1560 ap_table_set(r->subprocess_env, "force-response-1.0", "1");
1566 ap_hard_timeout("send headers", r);
1568 ap_basic_http_header(r);
1570 #ifdef CHARSET_EBCDIC
1571 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
1572 #endif /*CHARSET_EBCDIC*/
1574 ap_set_keepalive(r);
1577 ap_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
1578 ap_table_unset(r->headers_out, "Content-Length");
1581 if (r->byterange > 1)
1582 ap_table_setn(r->headers_out, "Content-Type",
1583 ap_pstrcat(r->pool, "multipart", use_range_x(r) ? "/x-" : "/",
1584 "byteranges; boundary=", r->boundary, NULL));
1585 else if (r->content_type)
1586 ap_table_setn(r->headers_out, "Content-Type", r->content_type);
1588 ap_table_setn(r->headers_out, "Content-Type", ap_default_type(r));
1590 if (r->content_encoding)
1591 ap_table_setn(r->headers_out, "Content-Encoding", r->content_encoding);
1593 if (r->content_languages && r->content_languages->nelts) {
1594 for (i = 0; i < r->content_languages->nelts; ++i) {
1595 ap_table_mergen(r->headers_out, "Content-Language",
1596 ((char **) (r->content_languages->elts))[i]);
1599 else if (r->content_language)
1600 ap_table_setn(r->headers_out, "Content-Language", r->content_language);
1603 * Control cachability for non-cachable responses if not already set by
1604 * some other part of the server configuration.
1606 if (r->no_cache && !ap_table_get(r->headers_out, "Expires"))
1607 ap_table_addn(r->headers_out, "Expires",
1608 ap_gm_timestr_822(r->pool, r->request_time));
1610 /* Send the entire table of header fields, terminated by an empty line. */
1612 ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
1613 (void *) r, r->headers_out, NULL);
1615 terminate_header(r->connection->client);
1619 ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
1620 r->sent_bodyct = 1; /* Whatever follows is real body stuff... */
1622 /* Set buffer flags for the body */
1624 ap_bsetflag(r->connection->client, B_CHUNK, 1);
1625 #ifdef CHARSET_EBCDIC
1627 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
1628 #endif /*CHARSET_EBCDIC*/
1631 /* finalize_request_protocol is called at completion of sending the
1632 * response. It's sole purpose is to send the terminating protocol
1633 * information for any wrappers around the response message body
1634 * (i.e., transfer encodings). It should have been named finalize_response.
1636 API_EXPORT(void) ap_finalize_request_protocol(request_rec *r)
1638 if (r->chunked && !r->connection->aborted) {
1640 * Turn off chunked encoding --- we can only do this once.
1643 ap_bsetflag(r->connection->client, B_CHUNK, 0);
1645 ap_soft_timeout("send ending chunk", r);
1646 ap_rputs("0\015\012", r);
1647 /* If we had footer "headers", we'd send them now */
1648 ap_rputs("\015\012", r);
1653 /* Here we deal with getting the request message body from the client.
1654 * Whether or not the request contains a body is signaled by the presence
1655 * of a non-zero Content-Length or by a Transfer-Encoding: chunked.
1657 * Note that this is more complicated than it was in Apache 1.1 and prior
1658 * versions, because chunked support means that the module does less.
1660 * The proper procedure is this:
1662 * 1. Call setup_client_block() near the beginning of the request
1663 * handler. This will set up all the necessary properties, and will
1664 * return either OK, or an error code. If the latter, the module should
1665 * return that error code. The second parameter selects the policy to
1666 * apply if the request message indicates a body, and how a chunked
1667 * transfer-coding should be interpreted. Choose one of
1669 * REQUEST_NO_BODY Send 413 error if message has any body
1670 * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
1671 * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
1672 * REQUEST_CHUNKED_PASS Pass the chunks to me without removal.
1674 * In order to use the last two options, the caller MUST provide a buffer
1675 * large enough to hold a chunk-size line, including any extensions.
1677 * 2. When you are ready to read a body (if any), call should_client_block().
1678 * This will tell the module whether or not to read input. If it is 0,
1679 * the module should assume that there is no message body to read.
1680 * This step also sends a 100 Continue response to HTTP/1.1 clients,
1681 * so should not be called until the module is *definitely* ready to
1682 * read content. (otherwise, the point of the 100 response is defeated).
1683 * Never call this function more than once.
1685 * 3. Finally, call get_client_block in a loop. Pass it a buffer and its size.
1686 * It will put data into the buffer (not necessarily a full buffer), and
1687 * return the length of the input block. When it is done reading, it will
1688 * return 0 if EOF, or -1 if there was an error.
1689 * If an error occurs on input, we force an end to keepalive.
1692 API_EXPORT(int) ap_setup_client_block(request_rec *r, int read_policy)
1694 const char *tenc = ap_table_get(r->headers_in, "Transfer-Encoding");
1695 const char *lenp = ap_table_get(r->headers_in, "Content-Length");
1696 unsigned long max_body;
1698 r->read_body = read_policy;
1699 r->read_chunked = 0;
1703 if (strcasecmp(tenc, "chunked")) {
1704 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1705 "Unknown Transfer-Encoding %s", tenc);
1706 return HTTP_NOT_IMPLEMENTED;
1708 if (r->read_body == REQUEST_CHUNKED_ERROR) {
1709 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1710 "chunked Transfer-Encoding forbidden: %s", r->uri);
1711 return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
1714 r->read_chunked = 1;
1717 const char *pos = lenp;
1719 while (ap_isdigit(*pos) || ap_isspace(*pos))
1722 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1723 "Invalid Content-Length %s", lenp);
1724 return HTTP_BAD_REQUEST;
1727 r->remaining = atol(lenp);
1730 if ((r->read_body == REQUEST_NO_BODY) &&
1731 (r->read_chunked || (r->remaining > 0))) {
1732 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1733 "%s with body is not allowed for %s", r->method, r->uri);
1734 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1737 max_body = ap_get_limit_req_body(r);
1738 if (max_body && (r->remaining > max_body)) {
1739 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1740 "Request content-length of %s is larger than the configured "
1741 "limit of %lu", lenp, max_body);
1742 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1748 API_EXPORT(int) ap_should_client_block(request_rec *r)
1750 /* First check if we have already read the request body */
1752 if (r->read_length || (!r->read_chunked && (r->remaining <= 0)))
1755 if (r->expecting_100 && r->proto_num >= HTTP_VERSION(1,1)) {
1756 /* sending 100 Continue interim response */
1757 ap_rvputs(r, SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012",
1765 static long get_chunk_size(char *b)
1769 while (ap_isxdigit(*b)) {
1772 if (*b >= '0' && *b <= '9')
1774 else if (*b >= 'A' && *b <= 'F')
1775 xvalue = *b - 'A' + 0xa;
1776 else if (*b >= 'a' && *b <= 'f')
1777 xvalue = *b - 'a' + 0xa;
1779 chunksize = (chunksize << 4) | xvalue;
1786 /* get_client_block is called in a loop to get the request message body.
1787 * This is quite simple if the client includes a content-length
1788 * (the normal case), but gets messy if the body is chunked. Note that
1789 * r->remaining is used to maintain state across calls and that
1790 * r->read_length is the total number of bytes given to the caller
1791 * across all invocations. It is messy because we have to be careful not
1792 * to read past the data provided by the client, since these reads block.
1793 * Returns 0 on End-of-body, -1 on error or premature chunk end.
1795 * Reading the chunked encoding requires a buffer size large enough to
1796 * hold a chunk-size line, including any extensions. For now, we'll leave
1797 * that to the caller, at least until we can come up with a better solution.
1799 API_EXPORT(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
1802 long len_read, len_to_read;
1803 long chunk_start = 0;
1804 unsigned long max_body;
1806 if (!r->read_chunked) { /* Content-length read */
1807 len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
1808 len_read = ap_bread(r->connection->client, buffer, len_to_read);
1809 if (len_read <= 0) {
1811 r->connection->keepalive = -1;
1814 r->read_length += len_read;
1815 r->remaining -= len_read;
1820 * Handle chunked reading Note: we are careful to shorten the input
1821 * bufsiz so that there will always be enough space for us to add a CRLF
1824 if (r->read_body == REQUEST_CHUNKED_PASS)
1827 return -1; /* Cannot read chunked with a small buffer */
1829 /* Check to see if we have already read too much request data.
1830 * For efficiency reasons, we only check this at the top of each
1831 * caller read pass, since the limit exists just to stop infinite
1832 * length requests and nobody cares if it goes over by one buffer.
1834 max_body = ap_get_limit_req_body(r);
1835 if (max_body && (r->read_length > max_body)) {
1836 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
1837 "Chunked request body is larger than the configured limit of %lu",
1839 r->connection->keepalive = -1;
1843 if (r->remaining == 0) { /* Start of new chunk */
1845 chunk_start = getline(buffer, bufsiz, r->connection->client, 0);
1846 if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1))
1847 || !ap_isxdigit(*buffer)) {
1848 r->connection->keepalive = -1;
1852 len_to_read = get_chunk_size(buffer);
1854 if (len_to_read == 0) { /* Last chunk indicated, get footers */
1855 if (r->read_body == REQUEST_CHUNKED_DECHUNK) {
1856 get_mime_headers(r);
1857 ap_snprintf(buffer, bufsiz, "%ld", r->read_length);
1858 ap_table_unset(r->headers_in, "Transfer-Encoding");
1859 ap_table_setn(r->headers_in, "Content-Length",
1860 ap_pstrdup(r->pool, buffer));
1863 r->remaining = -1; /* Indicate footers in-progress */
1866 r->remaining = len_to_read;
1868 if (r->read_body == REQUEST_CHUNKED_PASS) {
1869 buffer[chunk_start++] = CR; /* Restore chunk-size line end */
1870 buffer[chunk_start++] = LF;
1871 buffer += chunk_start; /* and pass line on to caller */
1872 bufsiz -= chunk_start;
1875 /* REQUEST_CHUNKED_DECHUNK -- do not include the length of the
1876 * header in the return value
1881 /* When REQUEST_CHUNKED_PASS, we are */
1882 if (r->remaining == -1) { /* reading footers until empty line */
1883 len_read = chunk_start;
1885 while ((bufsiz > 1) && ((len_read =
1886 getline(buffer, bufsiz, r->connection->client, 1)) > 0)) {
1888 if (len_read != (bufsiz - 1)) {
1889 buffer[len_read++] = CR; /* Restore footer line end */
1890 buffer[len_read++] = LF;
1892 chunk_start += len_read;
1897 r->connection->keepalive = -1;
1901 if (len_read == 0) { /* Indicates an empty line */
1907 r->read_length += chunk_start;
1910 /* When REQUEST_CHUNKED_PASS, we */
1911 if (r->remaining == -2) { /* finished footers when last called */
1912 r->remaining = 0; /* so now we must signal EOF */
1916 /* Otherwise, we are in the midst of reading a chunk of data */
1918 len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
1920 len_read = ap_bread(r->connection->client, buffer, len_to_read);
1921 if (len_read <= 0) {
1922 r->connection->keepalive = -1;
1926 r->remaining -= len_read;
1928 if (r->remaining == 0) { /* End of chunk, get trailing CRLF */
1929 if ((c = ap_bgetc(r->connection->client)) == CR) {
1930 c = ap_bgetc(r->connection->client);
1933 r->connection->keepalive = -1;
1936 if (r->read_body == REQUEST_CHUNKED_PASS) {
1937 buffer[len_read++] = CR;
1938 buffer[len_read++] = LF;
1941 r->read_length += (chunk_start + len_read);
1943 return (chunk_start + len_read);
1946 /* In HTTP/1.1, any method can have a body. However, most GET handlers
1947 * wouldn't know what to do with a request body if they received one.
1948 * This helper routine tests for and reads any message body in the request,
1949 * simply discarding whatever it receives. We need to do this because
1950 * failing to read the request body would cause it to be interpreted
1951 * as the next request on a persistent connection.
1953 * Since we return an error status if the request is malformed, this
1954 * routine should be called at the beginning of a no-body handler, e.g.,
1956 * if ((retval = ap_discard_request_body(r)) != OK)
1959 API_EXPORT(int) ap_discard_request_body(request_rec *r)
1963 if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_PASS)))
1966 /* In order to avoid sending 100 Continue when we already know the
1967 * final response status, and yet not kill the connection if there is
1968 * no request body to be read, we need to duplicate the test from
1969 * ap_should_client_block() here negated rather than call it directly.
1971 if ((r->read_length == 0) && (r->read_chunked || (r->remaining > 0))) {
1972 char dumpbuf[HUGE_STRING_LEN];
1974 if (r->expecting_100) {
1975 r->connection->keepalive = -1;
1978 ap_hard_timeout("reading request body", r);
1979 while ((rv = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN)) > 0)
1984 return HTTP_BAD_REQUEST;
1990 * Send the body of a response to the client.
1992 API_EXPORT(long) ap_send_fd(FILE *f, request_rec *r)
1994 return ap_send_fd_length(f, r, -1);
1997 API_EXPORT(long) ap_send_fd_length(FILE *f, request_rec *r, long length)
1999 char buf[IOBUFSIZE];
2000 long total_bytes_sent = 0;
2001 register int n, w, o, len;
2006 ap_soft_timeout("send body", r);
2008 while (!r->connection->aborted) {
2009 if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
2010 len = length - total_bytes_sent;
2014 while ((n = fread(buf, sizeof(char), len, f)) < 1
2015 && ferror(f) && errno == EINTR && !r->connection->aborted)
2023 while (n && !r->connection->aborted) {
2024 w = ap_bwrite(r->connection->client, &buf[o], n);
2026 ap_reset_timeout(r); /* reset timeout after successful write */
2027 total_bytes_sent += w;
2032 if (!r->connection->aborted) {
2033 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2034 "client stopped connection before send body completed");
2035 ap_bsetflag(r->connection->client, B_EOUT, 1);
2036 r->connection->aborted = 1;
2045 return total_bytes_sent;
2049 * Send the body of a response to the client.
2051 API_EXPORT(long) ap_send_fb(BUFF *fb, request_rec *r)
2053 return ap_send_fb_length(fb, r, -1);
2056 API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length)
2058 char buf[IOBUFSIZE];
2059 long total_bytes_sent = 0;
2060 register int n, w, o, len, fd;
2066 /* Make fb unbuffered and non-blocking */
2067 ap_bsetflag(fb, B_RD, 0);
2069 ap_bnonblock(fb, B_RD);
2071 fd = ap_bfileno(fb, B_RD);
2072 #ifdef CHECK_FD_SETSIZE
2073 if (fd >= FD_SETSIZE) {
2074 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL,
2075 "send body: filedescriptor (%u) larger than FD_SETSIZE (%u) "
2076 "found, you probably need to rebuild Apache with a "
2077 "larger FD_SETSIZE", fd, FD_SETSIZE);
2082 ap_soft_timeout("send body", r);
2085 while (!r->connection->aborted) {
2086 #ifdef NDELAY_PIPE_RETURNS_ZERO
2087 /* Contributed by dwd@bell-labs.com for UTS 2.1.2, where the fcntl */
2088 /* O_NDELAY flag causes read to return 0 when there's nothing */
2089 /* available when reading from a pipe. That makes it tricky */
2090 /* to detect end-of-file :-(. This stupid bug is even documented */
2091 /* in the read(2) man page where it says that everything but */
2092 /* pipes return -1 and EAGAIN. That makes it a feature, right? */
2093 int afterselect = 0;
2095 if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
2096 len = length - total_bytes_sent;
2101 n = ap_bread(fb, buf, len);
2102 #ifdef NDELAY_PIPE_RETURNS_ZERO
2103 if ((n > 0) || (n == 0 && afterselect))
2109 if (r->connection->aborted)
2111 if (n < 0 && errno != EAGAIN)
2114 /* we need to block, so flush the output first */
2115 if (ap_bflush(r->connection->client) < 0) {
2116 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2117 "client stopped connection before send body completed");
2118 ap_bsetflag(r->connection->client, B_EOUT, 1);
2119 r->connection->aborted = 1;
2124 * we don't care what select says, we might as well loop back
2125 * around and try another read
2127 ap_select(fd + 1, &fds, NULL, NULL, NULL);
2128 #ifdef NDELAY_PIPE_RETURNS_ZERO
2131 } while (!r->connection->aborted);
2133 if (n < 1 || r->connection->aborted) {
2138 while (n && !r->connection->aborted) {
2139 w = ap_bwrite(r->connection->client, &buf[o], n);
2141 ap_reset_timeout(r); /* reset timeout after successful write */
2142 total_bytes_sent += w;
2147 if (!r->connection->aborted) {
2148 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2149 "client stopped connection before send body completed");
2150 ap_bsetflag(r->connection->client, B_EOUT, 1);
2151 r->connection->aborted = 1;
2160 return total_bytes_sent;
2165 /* The code writes MMAP_SEGMENT_SIZE bytes at a time. This is due to Apache's
2166 * timeout model, which is a timeout per-write rather than a time for the
2167 * entire transaction to complete. Essentially this should be small enough
2168 * so that in one Timeout period, your slowest clients should be reasonably
2169 * able to receive this many bytes.
2171 * To take advantage of zero-copy TCP under Solaris 2.6 this should be a
2172 * multiple of 16k. (And you need a SunATM2.0 network card.)
2174 #ifndef MMAP_SEGMENT_SIZE
2175 #define MMAP_SEGMENT_SIZE 32768
2178 /* send data from an in-memory buffer */
2179 API_EXPORT(size_t) ap_send_mmap(void *mm, request_rec *r, size_t offset,
2182 size_t total_bytes_sent = 0;
2188 ap_soft_timeout("send mmap", r);
2191 while (!r->connection->aborted && offset < length) {
2192 if (length - offset > MMAP_SEGMENT_SIZE) {
2193 n = MMAP_SEGMENT_SIZE;
2196 n = length - offset;
2199 while (n && !r->connection->aborted) {
2200 w = ap_bwrite(r->connection->client, (char *) mm + offset, n);
2202 ap_reset_timeout(r); /* reset timeout after successful write */
2203 total_bytes_sent += w;
2208 if (!r->connection->aborted) {
2209 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2210 "client stopped connection before send mmap completed");
2211 ap_bsetflag(r->connection->client, B_EOUT, 1);
2212 r->connection->aborted = 1;
2221 return total_bytes_sent;
2224 API_EXPORT(int) ap_rputc(int c, request_rec *r)
2226 if (r->connection->aborted)
2229 if (ap_bputc(c, r->connection->client) < 0) {
2230 if (!r->connection->aborted) {
2231 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2232 "client stopped connection before rputc completed");
2233 ap_bsetflag(r->connection->client, B_EOUT, 1);
2234 r->connection->aborted = 1;
2242 API_EXPORT(int) ap_rputs(const char *str, request_rec *r)
2246 if (r->connection->aborted)
2249 rcode = ap_bputs(str, r->connection->client);
2251 if (!r->connection->aborted) {
2252 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2253 "client stopped connection before rputs completed");
2254 ap_bsetflag(r->connection->client, B_EOUT, 1);
2255 r->connection->aborted = 1;
2263 API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
2267 if (r->connection->aborted)
2270 n = ap_bwrite(r->connection->client, buf, nbyte);
2272 if (!r->connection->aborted) {
2273 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2274 "client stopped connection before rwrite completed");
2275 ap_bsetflag(r->connection->client, B_EOUT, 1);
2276 r->connection->aborted = 1;
2284 API_EXPORT(int) ap_vrprintf(request_rec *r, const char *fmt, va_list ap)
2288 if (r->connection->aborted)
2291 n = ap_vbprintf(r->connection->client, fmt, ap);
2294 if (!r->connection->aborted) {
2295 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2296 "client stopped connection before vrprintf completed");
2297 ap_bsetflag(r->connection->client, B_EOUT, 1);
2298 r->connection->aborted = 1;
2306 API_EXPORT(int) ap_rprintf(request_rec *r, const char *fmt,...)
2311 if (r->connection->aborted)
2314 va_start(vlist, fmt);
2315 n = ap_vbprintf(r->connection->client, fmt, vlist);
2319 if (!r->connection->aborted) {
2320 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2321 "client stopped connection before rprintf completed");
2322 ap_bsetflag(r->connection->client, B_EOUT, 1);
2323 r->connection->aborted = 1;
2331 API_EXPORT_NONSTD(int) ap_rvputs(request_rec *r,...)
2336 BUFF *fb = r->connection->client;
2338 if (r->connection->aborted)
2343 x = va_arg(args, const char *);
2347 i = ap_bwrite(fb, x, j);
2350 if (!r->connection->aborted) {
2351 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2352 "client stopped connection before rvputs completed");
2353 ap_bsetflag(r->connection->client, B_EOUT, 1);
2354 r->connection->aborted = 1;
2366 API_EXPORT(int) ap_rflush(request_rec *r)
2368 if (ap_bflush(r->connection->client) < 0) {
2369 if (!r->connection->aborted) {
2370 ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
2371 "client stopped connection before rflush completed");
2372 ap_bsetflag(r->connection->client, B_EOUT, 1);
2373 r->connection->aborted = 1;
2380 /* We should have named this send_canned_response, since it is used for any
2381 * response that can be generated by the server from the request record.
2382 * This includes all 204 (no content), 3xx (redirect), 4xx (client error),
2383 * and 5xx (server error) messages that have not been redirected to another
2384 * handler via the ErrorDocument feature.
2386 void ap_send_error_response(request_rec *r, int recursive_error)
2388 int status = r->status;
2389 int idx = ap_index_of_response(status);
2390 char *custom_response;
2391 const char *location = ap_table_get(r->headers_out, "Location");
2394 * It's possible that the Location field might be in r->err_headers_out
2395 * instead of r->headers_out; use the latter if possible, else the
2398 if (location == NULL) {
2399 location = ap_table_get(r->err_headers_out, "Location");
2401 /* We need to special-case the handling of 204 and 304 responses,
2402 * since they have specific HTTP requirements and do not include a
2403 * message body. Note that being assbackwards here is not an option.
2405 if (status == HTTP_NOT_MODIFIED) {
2406 if (!ap_is_empty_table(r->err_headers_out))
2407 r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out,
2409 ap_hard_timeout("send 304", r);
2411 ap_basic_http_header(r);
2412 ap_set_keepalive(r);
2414 ap_table_do((int (*)(void *, const char *, const char *)) ap_send_header_field,
2415 (void *) r, r->headers_out,
2425 "Proxy-Authenticate",
2428 terminate_header(r->connection->client);
2434 if (status == HTTP_NO_CONTENT) {
2435 ap_send_http_header(r);
2436 ap_finalize_request_protocol(r);
2440 if (!r->assbackwards) {
2441 table *tmp = r->headers_out;
2443 /* For all HTTP/1.x responses for which we generate the message,
2444 * we need to avoid inheriting the "normal status" header fields
2445 * that may have been set by the request handler before the
2446 * error or redirect, except for Location on external redirects.
2448 r->headers_out = r->err_headers_out;
2449 r->err_headers_out = tmp;
2450 ap_clear_table(r->err_headers_out);
2452 if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) {
2453 if ((location != NULL) && *location) {
2454 ap_table_setn(r->headers_out, "Location", location);
2457 location = ""; /* avoids coredump when printing, below */
2461 r->content_language = NULL;
2462 r->content_languages = NULL;
2463 r->content_encoding = NULL;
2465 r->content_type = "text/html";
2467 if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
2468 ap_table_setn(r->headers_out, "Allow", make_allow(r));
2470 ap_send_http_header(r);
2472 if (r->header_only) {
2473 ap_finalize_request_protocol(r);
2479 ap_hard_timeout("send error body", r);
2481 if ((custom_response = ap_response_code_string(r, idx))) {
2483 * We have a custom response output. This should only be
2484 * a text-string to write back. But if the ErrorDocument
2485 * was a local redirect and the requested resource failed
2486 * for any reason, the custom_response will still hold the
2487 * redirect URL. We don't really want to output this URL
2488 * as a text message, so first check the custom response
2489 * string to ensure that it is a text-string (using the
2490 * same test used in ap_die(), i.e. does it start with a ").
2491 * If it doesn't, we've got a recursive error, so find
2492 * the original error and output that as well.
2494 if (custom_response[0] == '\"') {
2495 ap_rputs(custom_response + 1, r);
2497 ap_finalize_request_protocol(r);
2502 * Redirect failed, so get back the original error
2504 while (r->prev && (r->prev->status != HTTP_OK))
2508 const char *title = status_lines[idx];
2510 const char *error_notes;
2512 /* Accept a status_line set by a module, but only if it begins
2513 * with the 3 digit status code
2515 if (r->status_line != NULL
2516 && strlen(r->status_line) > 4 /* long enough */
2517 && ap_isdigit(r->status_line[0])
2518 && ap_isdigit(r->status_line[1])
2519 && ap_isdigit(r->status_line[2])
2520 && ap_isspace(r->status_line[3])
2521 && ap_isalnum(r->status_line[4])) {
2522 title = r->status_line;
2525 /* folks decided they didn't want the error code in the H1 text */
2530 "<HTML><HEAD>\n<TITLE>", title,
2531 "</TITLE>\n</HEAD><BODY>\n<H1>", h1, "</H1>\n",
2535 case HTTP_MOVED_PERMANENTLY:
2536 case HTTP_MOVED_TEMPORARILY:
2537 case HTTP_TEMPORARY_REDIRECT:
2538 ap_rvputs(r, "The document has moved <A HREF=\"",
2539 ap_escape_html(r->pool, location), "\">here</A>.<P>\n",
2542 case HTTP_SEE_OTHER:
2543 ap_rvputs(r, "The answer to your request is located <A HREF=\"",
2544 ap_escape_html(r->pool, location), "\">here</A>.<P>\n",
2547 case HTTP_USE_PROXY:
2548 ap_rvputs(r, "This resource is only accessible "
2549 "through the proxy\n",
2550 ap_escape_html(r->pool, location),
2551 "<BR>\nYou will need to ",
2552 "configure your client to use that proxy.<P>\n", NULL);
2554 case HTTP_PROXY_AUTHENTICATION_REQUIRED:
2556 ap_rputs("This server could not verify that you\n"
2557 "are authorized to access the document\n"
2558 "requested. Either you supplied the wrong\n"
2559 "credentials (e.g., bad password), or your\n"
2560 "browser doesn't understand how to supply\n"
2561 "the credentials required.<P>\n", r);
2564 ap_rputs("Your browser sent a request that "
2565 "this server could not understand.<P>\n", r);
2566 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2567 ap_rvputs(r, error_notes, "<P>\n", NULL);
2570 case HTTP_FORBIDDEN:
2571 ap_rvputs(r, "You don't have permission to access ",
2572 ap_escape_html(r->pool, r->uri),
2573 "\non this server.<P>\n", NULL);
2576 ap_rvputs(r, "The requested URL ",
2577 ap_escape_html(r->pool, r->uri),
2578 " was not found on this server.<P>\n", NULL);
2580 case METHOD_NOT_ALLOWED:
2581 ap_rvputs(r, "The requested method ", r->method,
2583 "for the URL ", ap_escape_html(r->pool, r->uri),
2586 case NOT_ACCEPTABLE:
2588 "An appropriate representation of the "
2589 "requested resource ",
2590 ap_escape_html(r->pool, r->uri),
2591 " could not be found on this server.<P>\n", NULL);
2593 case MULTIPLE_CHOICES:
2596 if ((list = ap_table_get(r->notes, "variant-list")))
2600 case LENGTH_REQUIRED:
2601 ap_rvputs(r, "A request of the requested method ", r->method,
2602 " requires a valid Content-length.<P>\n", NULL);
2603 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2604 ap_rvputs(r, error_notes, "<P>\n", NULL);
2607 case PRECONDITION_FAILED:
2608 ap_rvputs(r, "The precondition on the request for the URL ",
2609 ap_escape_html(r->pool, r->uri),
2610 " evaluated to false.<P>\n", NULL);
2612 case HTTP_NOT_IMPLEMENTED:
2613 ap_rvputs(r, ap_escape_html(r->pool, r->method), " to ",
2614 ap_escape_html(r->pool, r->uri),
2615 " not supported.<P>\n", NULL);
2616 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2617 ap_rvputs(r, error_notes, "<P>\n", NULL);
2621 ap_rputs("The proxy server received an invalid\015\012"
2622 "response from an upstream server.<P>\015\012", r);
2623 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2624 ap_rvputs(r, error_notes, "<P>\n", NULL);
2627 case VARIANT_ALSO_VARIES:
2628 ap_rvputs(r, "A variant for the requested resource\n<PRE>\n",
2629 ap_escape_html(r->pool, r->uri),
2630 "\n</PRE>\nis itself a negotiable resource. "
2631 "This indicates a configuration error.<P>\n", NULL);
2633 case HTTP_REQUEST_TIME_OUT:
2634 ap_rputs("I'm tired of waiting for your request.\n", r);
2637 ap_rvputs(r, "The requested resource<BR>",
2638 ap_escape_html(r->pool, r->uri),
2639 "<BR>\nis no longer available on this server ",
2640 "and there is no forwarding address.\n",
2641 "Please remove all references to this resource.\n",
2644 case HTTP_REQUEST_ENTITY_TOO_LARGE:
2645 ap_rvputs(r, "The requested resource<BR>",
2646 ap_escape_html(r->pool, r->uri), "<BR>\n",
2647 "does not allow request data with ", r->method,
2648 " requests, or the amount of data provided in\n",
2649 "the request exceeds the capacity limit.\n", NULL);
2651 case HTTP_REQUEST_URI_TOO_LARGE:
2652 ap_rputs("The requested URL's length exceeds the capacity\n"
2653 "limit for this server.<P>\n", r);
2654 if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2655 ap_rvputs(r, error_notes, "<P>\n", NULL);
2658 case HTTP_UNSUPPORTED_MEDIA_TYPE:
2659 ap_rputs("The supplied request data is not in a format\n"
2660 "acceptable for processing by this resource.\n", r);
2662 case HTTP_RANGE_NOT_SATISFIABLE:
2663 ap_rputs("None of the range-specifier values in the Range\n"
2664 "request-header field overlap the current extent\n"
2665 "of the selected resource.\n", r);
2667 case HTTP_EXPECTATION_FAILED:
2668 ap_rvputs(r, "The expectation given in the Expect request-header"
2669 "\nfield could not be met by this server.<P>\n"
2670 "The client sent<PRE>\n Expect: ",
2671 ap_table_get(r->headers_in, "Expect"), "\n</PRE>\n"
2672 "but we only allow the 100-continue expectation.\n",
2675 case HTTP_UNPROCESSABLE_ENTITY:
2676 ap_rputs("The server understands the media type of the\n"
2677 "request entity, but was unable to process the\n"
2678 "contained instructions.\n", r);
2681 ap_rputs("The requested resource is currently locked.\n"
2682 "The lock must be released or proper identification\n"
2683 "given before the method can be applied.\n", r);
2685 case HTTP_FAILED_DEPENDENCY:
2686 ap_rputs("The method could not be performed on the resource\n"
2687 "because the requested action depended on another\n"
2688 "action and that other action failed.\n", r);
2690 case HTTP_INSUFFICIENT_STORAGE:
2691 ap_rputs("The method could not be performed on the resource\n"
2692 "because the server is unable to store the\n"
2693 "representation needed to successfully complete the\n"
2694 "request. There is insufficient free space left in\n"
2695 "your storage allocation.\n", r);
2697 case HTTP_SERVICE_UNAVAILABLE:
2698 ap_rputs("The server is temporarily unable to service your\n"
2699 "request due to maintenance downtime or capacity\n"
2700 "problems. Please try again later.\n", r);
2702 case HTTP_GATEWAY_TIME_OUT:
2703 ap_rputs("The proxy server did not receive a timely response\n"
2704 "from the upstream server.\n", r);
2706 case HTTP_NOT_EXTENDED:
2707 ap_rputs("A mandatory extension policy in the request is not\n"
2708 "accepted by the server for this resource.\n", r);
2710 default: /* HTTP_INTERNAL_SERVER_ERROR */
2712 * This comparison to expose error-notes could be modified to
2713 * use a configuration directive and export based on that
2714 * directive. For now "*" is used to designate an error-notes
2715 * that is totally safe for any user to see (ie lacks paths,
2716 * database passwords, etc.)
2718 if (((error_notes = ap_table_get(r->notes, "error-notes")) != NULL)
2719 && (h1 = ap_table_get(r->notes, "verbose-error-to")) != NULL
2720 && (strcmp(h1, "*") == 0)) {
2721 ap_rvputs(r, error_notes, "<P>\n", NULL);
2724 ap_rvputs(r, "The server encountered an internal error or\n"
2725 "misconfiguration and was unable to complete\n"
2726 "your request.<P>\n"
2727 "Please contact the server administrator,\n ",
2728 ap_escape_html(r->pool, r->server->server_admin),
2729 " and inform them of the time the error occurred,\n"
2730 "and anything you might have done that may have\n"
2731 "caused the error.<P>\n"
2732 "More information about this error may be available\n"
2733 "in the server error log.<P>\n", NULL);
2736 * It would be nice to give the user the information they need to
2737 * fix the problem directly since many users don't have access to
2738 * the error_log (think University sites) even though they can easily
2739 * get this error by misconfiguring an htaccess file. However, the
2740 * error notes tend to include the real file pathname in this case,
2741 * which some people consider to be a breach of privacy. Until we
2742 * can figure out a way to remove the pathname, leave this commented.
2744 * if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
2745 * ap_rvputs(r, error_notes, "<P>\n", NULL);
2751 if (recursive_error) {
2752 ap_rvputs(r, "<P>Additionally, a ",
2753 status_lines[ap_index_of_response(recursive_error)],
2754 "\nerror was encountered while trying to use an "
2755 "ErrorDocument to handle the request.\n", NULL);
2757 ap_rputs(ap_psignature("<HR>\n", r), r);
2758 ap_rputs("</BODY></HTML>\n", r);
2761 ap_finalize_request_protocol(r);