1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * http_protocol.c --- routines which directly communicate with the client.
20 * Code originally by Rob McCool; much redone by Robert S. Thau
21 * and the Apache Software Foundation.
25 #include "apr_strings.h"
26 #include "apr_buckets.h"
28 #include "apr_signal.h"
30 #define APR_WANT_STDIO /* for sscanf */
31 #define APR_WANT_STRFUNC
32 #define APR_WANT_MEMFUNC
36 #include "util_filter.h"
37 #include "ap_config.h"
39 #include "http_config.h"
40 #include "http_core.h"
41 #include "http_protocol.h"
42 #include "http_main.h"
43 #include "http_request.h"
44 #include "http_vhost.h"
45 #include "http_log.h" /* For errors detected in basic auth common
47 #include "apr_date.h" /* For apr_date_parse_http and APR_DATE_BAD */
48 #include "util_charset.h"
49 #include "util_ebcdic.h"
50 #include "util_time.h"
61 /* New Apache routine to map status codes into array indicies
62 * e.g. 100 -> 0, 101 -> 1, 200 -> 2 ...
63 * The number of status lines must equal the value of RESPONSE_CODES (httpd.h)
64 * and must be listed in order.
68 /* The second const triggers an assembler bug on UTS 2.1.
69 * Another workaround is to move some code out of this file into another,
70 * but this is easier. Dave Dykstra, 3/31/99
72 static const char * status_lines[RESPONSE_CODES] =
74 static const char * const status_lines[RESPONSE_CODES] =
78 "101 Switching Protocols",
84 "203 Non-Authoritative Information",
87 "206 Partial Content",
90 "300 Multiple Choices",
91 "301 Moved Permanently",
97 "307 Temporary Redirect",
100 "401 Authorization Required",
101 "402 Payment Required",
104 "405 Method Not Allowed",
105 "406 Not Acceptable",
106 "407 Proxy Authentication Required",
107 "408 Request Time-out",
110 "411 Length Required",
111 "412 Precondition Failed",
112 "413 Request Entity Too Large",
113 "414 Request-URI Too Large",
114 "415 Unsupported Media Type",
115 "416 Requested Range Not Satisfiable",
116 "417 Expectation Failed",
121 "422 Unprocessable Entity",
123 "424 Failed Dependency",
124 /* This is a hack, but it is required for ap_index_of_response
128 "426 Upgrade Required",
130 "500 Internal Server Error",
131 "501 Method Not Implemented",
133 "503 Service Temporarily Unavailable",
134 "504 Gateway Time-out",
135 "505 HTTP Version Not Supported",
136 "506 Variant Also Negotiates",
137 "507 Insufficient Storage",
144 APR_HOOK_LINK(insert_error_filter)
147 AP_IMPLEMENT_HOOK_VOID(insert_error_filter, (request_rec *r), (r))
149 /* The index of the first bit field that is used to index into a limit
150 * bitmask. M_INVALID + 1 to METHOD_NUMBER_LAST.
152 #define METHOD_NUMBER_FIRST (M_INVALID + 1)
154 /* The max method number. Method numbers are used to shift bitmasks,
155 * so this cannot exceed 63, and all bits high is equal to -1, which is a
156 * special flag, so the last bit used has index 62.
158 #define METHOD_NUMBER_LAST 62
161 AP_DECLARE(int) ap_set_keepalive(request_rec *r)
164 int wimpy = ap_find_token(r->pool,
165 apr_table_get(r->headers_out, "Connection"),
167 const char *conn = apr_table_get(r->headers_in, "Connection");
169 /* The following convoluted conditional determines whether or not
170 * the current connection should remain persistent after this response
171 * (a.k.a. HTTP Keep-Alive) and whether or not the output message
172 * body should use the HTTP/1.1 chunked transfer-coding. In English,
174 * IF we have not marked this connection as errored;
175 * and the response body has a defined length due to the status code
176 * being 304 or 204, the request method being HEAD, already
177 * having defined Content-Length or Transfer-Encoding: chunked, or
178 * the request version being HTTP/1.1 and thus capable of being set
179 * as chunked [we know the (r->chunked = 1) side-effect is ugly];
180 * and the server configuration enables keep-alive;
181 * and the server configuration has a reasonable inter-request timeout;
182 * and there is no maximum # requests or the max hasn't been reached;
183 * and the response status does not require a close;
184 * and the response generator has not already indicated close;
185 * and the client did not request non-persistence (Connection: close);
186 * and we haven't been configured to ignore the buggy twit
187 * or they're a buggy twit coming through a HTTP/1.1 proxy
188 * and the client is requesting an HTTP/1.0-style keep-alive
189 * or the client claims to be HTTP/1.1 compliant (perhaps a proxy);
190 * THEN we can be persistent, which requires more headers be output.
192 * Note that the condition evaluation order is extremely important.
194 if ((r->connection->keepalive != AP_CONN_CLOSE)
195 && ((r->status == HTTP_NOT_MODIFIED)
196 || (r->status == HTTP_NO_CONTENT)
198 || apr_table_get(r->headers_out, "Content-Length")
199 || ap_find_last_token(r->pool,
200 apr_table_get(r->headers_out,
201 "Transfer-Encoding"),
203 || ((r->proto_num >= HTTP_VERSION(1,1))
204 && (r->chunked = 1))) /* THIS CODE IS CORRECT, see above. */
205 && r->server->keep_alive
206 && (r->server->keep_alive_timeout > 0)
207 && ((r->server->keep_alive_max == 0)
208 || (r->server->keep_alive_max > r->connection->keepalives))
209 && !ap_status_drops_connection(r->status)
211 && !ap_find_token(r->pool, conn, "close")
212 && (!apr_table_get(r->subprocess_env, "nokeepalive")
213 || apr_table_get(r->headers_in, "Via"))
214 && ((ka_sent = ap_find_token(r->pool, conn, "keep-alive"))
215 || (r->proto_num >= HTTP_VERSION(1,1)))) {
216 int left = r->server->keep_alive_max - r->connection->keepalives;
218 r->connection->keepalive = AP_CONN_KEEPALIVE;
219 r->connection->keepalives++;
221 /* If they sent a Keep-Alive token, send one back */
223 if (r->server->keep_alive_max) {
224 apr_table_setn(r->headers_out, "Keep-Alive",
225 apr_psprintf(r->pool, "timeout=%d, max=%d",
226 (int)apr_time_sec(r->server->keep_alive_timeout),
230 apr_table_setn(r->headers_out, "Keep-Alive",
231 apr_psprintf(r->pool, "timeout=%d",
232 (int)apr_time_sec(r->server->keep_alive_timeout)));
234 apr_table_mergen(r->headers_out, "Connection", "Keep-Alive");
240 /* Otherwise, we need to indicate that we will be closing this
241 * connection immediately after the current response.
243 * We only really need to send "close" to HTTP/1.1 clients, but we
244 * always send it anyway, because a broken proxy may identify itself
245 * as HTTP/1.0, but pass our request along with our HTTP/1.1 tag
246 * to a HTTP/1.1 client. Better safe than sorry.
249 apr_table_mergen(r->headers_out, "Connection", "close");
252 r->connection->keepalive = AP_CONN_CLOSE;
257 AP_DECLARE(int) ap_meets_conditions(request_rec *r)
260 const char *if_match, *if_modified_since, *if_unmodified, *if_nonematch;
264 /* Check for conditional requests --- note that we only want to do
265 * this if we are successful so far and we are not processing a
266 * subrequest or an ErrorDocument.
268 * The order of the checks is important, since ETag checks are supposed
269 * to be more accurate than checks relative to the modification time.
270 * However, not all documents are guaranteed to *have* ETags, and some
271 * might have Last-Modified values w/o ETags, so this gets a little
275 if (!ap_is_HTTP_SUCCESS(r->status) || r->no_local_copy) {
279 etag = apr_table_get(r->headers_out, "ETag");
281 /* All of our comparisons must be in seconds, because that's the
282 * highest time resolution the HTTP specification allows.
284 /* XXX: we should define a "time unset" constant */
285 tmp_time = ((r->mtime != 0) ? r->mtime : apr_time_now());
286 mtime = apr_time_sec(tmp_time);
288 /* If an If-Match request-header field was given
289 * AND the field value is not "*" (meaning match anything)
290 * AND if our strong ETag does not match any entity tag in that field,
291 * respond with a status of 412 (Precondition Failed).
293 if ((if_match = apr_table_get(r->headers_in, "If-Match")) != NULL) {
294 if (if_match[0] != '*'
295 && (etag == NULL || etag[0] == 'W'
296 || !ap_find_list_item(r->pool, if_match, etag))) {
297 return HTTP_PRECONDITION_FAILED;
301 /* Else if a valid If-Unmodified-Since request-header field was given
302 * AND the requested resource has been modified since the time
303 * specified in this field, then the server MUST
304 * respond with a status of 412 (Precondition Failed).
306 if_unmodified = apr_table_get(r->headers_in, "If-Unmodified-Since");
307 if (if_unmodified != NULL) {
308 apr_time_t ius = apr_date_parse_http(if_unmodified);
310 if ((ius != APR_DATE_BAD) && (mtime > apr_time_sec(ius))) {
311 return HTTP_PRECONDITION_FAILED;
316 /* If an If-None-Match request-header field was given
317 * AND the field value is "*" (meaning match anything)
318 * OR our ETag matches any of the entity tags in that field, fail.
320 * If the request method was GET or HEAD, failure means the server
321 * SHOULD respond with a 304 (Not Modified) response.
322 * For all other request methods, failure means the server MUST
323 * respond with a status of 412 (Precondition Failed).
325 * GET or HEAD allow weak etag comparison, all other methods require
326 * strong comparison. We can only use weak if it's not a range request.
328 if_nonematch = apr_table_get(r->headers_in, "If-None-Match");
329 if (if_nonematch != NULL) {
330 if (r->method_number == M_GET) {
331 if (if_nonematch[0] == '*') {
332 return HTTP_NOT_MODIFIED;
335 if (apr_table_get(r->headers_in, "Range")) {
337 && ap_find_list_item(r->pool, if_nonematch, etag)) {
338 return HTTP_NOT_MODIFIED;
341 else if (ap_strstr_c(if_nonematch, etag)) {
342 return HTTP_NOT_MODIFIED;
346 else if (if_nonematch[0] == '*'
348 && ap_find_list_item(r->pool, if_nonematch, etag))) {
349 return HTTP_PRECONDITION_FAILED;
352 /* Else if a valid If-Modified-Since request-header field was given
353 * AND it is a GET or HEAD request
354 * AND the requested resource has not been modified since the time
355 * specified in this field, then the server MUST
356 * respond with a status of 304 (Not Modified).
357 * A date later than the server's current request time is invalid.
359 else if ((r->method_number == M_GET)
360 && ((if_modified_since =
361 apr_table_get(r->headers_in,
362 "If-Modified-Since")) != NULL)) {
364 apr_int64_t ims, reqtime;
366 ims_time = apr_date_parse_http(if_modified_since);
367 ims = apr_time_sec(ims_time);
368 reqtime = apr_time_sec(r->request_time);
370 if ((ims >= mtime) && (ims <= reqtime)) {
371 return HTTP_NOT_MODIFIED;
378 * Singleton registry of additional methods. This maps new method names
379 * such as "MYGET" to methnums, which are int offsets into bitmasks.
381 * This follows the same technique as standard M_GET, M_POST, etc. These
382 * are dynamically assigned when modules are loaded and <Limit GET MYGET>
383 * directives are processed.
385 static apr_hash_t *methods_registry = NULL;
386 static int cur_method_number = METHOD_NUMBER_FIRST;
388 /* internal function to register one method/number pair */
389 static void register_one_method(apr_pool_t *p, const char *methname,
392 int *pnum = apr_palloc(p, sizeof(*pnum));
395 apr_hash_set(methods_registry, methname, APR_HASH_KEY_STRING, pnum);
398 /* This internal function is used to clear the method registry
399 * and reset the cur_method_number counter.
401 static apr_status_t ap_method_registry_destroy(void *notused)
403 methods_registry = NULL;
404 cur_method_number = METHOD_NUMBER_FIRST;
408 AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p)
410 methods_registry = apr_hash_make(p);
411 apr_pool_cleanup_register(p, NULL,
412 ap_method_registry_destroy,
413 apr_pool_cleanup_null);
415 /* put all the standard methods into the registry hash to ease the
416 mapping operations between name and number */
417 register_one_method(p, "GET", M_GET);
418 register_one_method(p, "PUT", M_PUT);
419 register_one_method(p, "POST", M_POST);
420 register_one_method(p, "DELETE", M_DELETE);
421 register_one_method(p, "CONNECT", M_CONNECT);
422 register_one_method(p, "OPTIONS", M_OPTIONS);
423 register_one_method(p, "TRACE", M_TRACE);
424 register_one_method(p, "PATCH", M_PATCH);
425 register_one_method(p, "PROPFIND", M_PROPFIND);
426 register_one_method(p, "PROPPATCH", M_PROPPATCH);
427 register_one_method(p, "MKCOL", M_MKCOL);
428 register_one_method(p, "COPY", M_COPY);
429 register_one_method(p, "MOVE", M_MOVE);
430 register_one_method(p, "LOCK", M_LOCK);
431 register_one_method(p, "UNLOCK", M_UNLOCK);
432 register_one_method(p, "VERSION-CONTROL", M_VERSION_CONTROL);
433 register_one_method(p, "CHECKOUT", M_CHECKOUT);
434 register_one_method(p, "UNCHECKOUT", M_UNCHECKOUT);
435 register_one_method(p, "CHECKIN", M_CHECKIN);
436 register_one_method(p, "UPDATE", M_UPDATE);
437 register_one_method(p, "LABEL", M_LABEL);
438 register_one_method(p, "REPORT", M_REPORT);
439 register_one_method(p, "MKWORKSPACE", M_MKWORKSPACE);
440 register_one_method(p, "MKACTIVITY", M_MKACTIVITY);
441 register_one_method(p, "BASELINE-CONTROL", M_BASELINE_CONTROL);
442 register_one_method(p, "MERGE", M_MERGE);
445 AP_DECLARE(int) ap_method_register(apr_pool_t *p, const char *methname)
449 if (methods_registry == NULL) {
450 ap_method_registry_init(p);
453 if (methname == NULL) {
457 /* Check if the method was previously registered. If it was
458 * return the associated method number.
460 methnum = (int *)apr_hash_get(methods_registry, methname,
461 APR_HASH_KEY_STRING);
465 if (cur_method_number > METHOD_NUMBER_LAST) {
466 /* The method registry has run out of dynamically
467 * assignable method numbers. Log this and return M_INVALID.
469 ap_log_perror(APLOG_MARK, APLOG_ERR, 0, p,
470 "Maximum new request methods %d reached while "
471 "registering method %s.",
472 METHOD_NUMBER_LAST, methname);
476 register_one_method(p, methname, cur_method_number);
477 return cur_method_number++;
480 #define UNKNOWN_METHOD (-1)
482 static int lookup_builtin_method(const char *method, apr_size_t len)
484 /* Note: the following code was generated by the "shilka" tool from
485 the "cocom" parsing/compilation toolkit. It is an optimized lookup
486 based on analysis of the input keywords. Postprocessing was done
487 on the shilka output, but the basic structure and analysis is
488 from there. Should new HTTP methods be added, then manual insertion
489 into this code is fine, or simply re-running the shilka tool on
490 the appropriate input. */
492 /* Note: it is also quite reasonable to just use our method_registry,
493 but I'm assuming (probably incorrectly) we want more speed here
494 (based on the optimizations the previous code was doing). */
502 return (method[1] == 'U'
504 ? M_PUT : UNKNOWN_METHOD);
506 return (method[1] == 'E'
508 ? M_GET : UNKNOWN_METHOD);
510 return UNKNOWN_METHOD;
517 return (method[1] == 'E'
520 ? M_GET : UNKNOWN_METHOD);
522 return (method[1] == 'O'
525 ? M_POST : UNKNOWN_METHOD);
527 return (method[1] == 'O'
530 ? M_MOVE : UNKNOWN_METHOD);
532 return (method[1] == 'O'
535 ? M_LOCK : UNKNOWN_METHOD);
537 return (method[1] == 'O'
540 ? M_COPY : UNKNOWN_METHOD);
542 return UNKNOWN_METHOD;
549 return (memcmp(method, "PATCH", 5) == 0
550 ? M_PATCH : UNKNOWN_METHOD);
552 return (memcmp(method, "MERGE", 5) == 0
553 ? M_MERGE : UNKNOWN_METHOD);
555 return (memcmp(method, "MKCOL", 5) == 0
556 ? M_MKCOL : UNKNOWN_METHOD);
558 return (memcmp(method, "LABEL", 5) == 0
559 ? M_LABEL : UNKNOWN_METHOD);
561 return (memcmp(method, "TRACE", 5) == 0
562 ? M_TRACE : UNKNOWN_METHOD);
564 return UNKNOWN_METHOD;
574 return (memcmp(method, "UNLOCK", 6) == 0
575 ? M_UNLOCK : UNKNOWN_METHOD);
577 return (memcmp(method, "UPDATE", 6) == 0
578 ? M_UPDATE : UNKNOWN_METHOD);
580 return UNKNOWN_METHOD;
583 return (memcmp(method, "REPORT", 6) == 0
584 ? M_REPORT : UNKNOWN_METHOD);
586 return (memcmp(method, "DELETE", 6) == 0
587 ? M_DELETE : UNKNOWN_METHOD);
589 return UNKNOWN_METHOD;
596 return (memcmp(method, "OPTIONS", 7) == 0
597 ? M_OPTIONS : UNKNOWN_METHOD);
599 return (memcmp(method, "CONNECT", 7) == 0
600 ? M_CONNECT : UNKNOWN_METHOD);
602 return (memcmp(method, "CHECKIN", 7) == 0
603 ? M_CHECKIN : UNKNOWN_METHOD);
605 return UNKNOWN_METHOD;
612 return (memcmp(method, "PROPFIND", 8) == 0
613 ? M_PROPFIND : UNKNOWN_METHOD);
615 return (memcmp(method, "CHECKOUT", 8) == 0
616 ? M_CHECKOUT : UNKNOWN_METHOD);
618 return UNKNOWN_METHOD;
622 return (memcmp(method, "PROPPATCH", 9) == 0
623 ? M_PROPPATCH : UNKNOWN_METHOD);
629 return (memcmp(method, "UNCHECKOUT", 10) == 0
630 ? M_UNCHECKOUT : UNKNOWN_METHOD);
632 return (memcmp(method, "MKACTIVITY", 10) == 0
633 ? M_MKACTIVITY : UNKNOWN_METHOD);
635 return UNKNOWN_METHOD;
639 return (memcmp(method, "MKWORKSPACE", 11) == 0
640 ? M_MKWORKSPACE : UNKNOWN_METHOD);
643 return (memcmp(method, "VERSION-CONTROL", 15) == 0
644 ? M_VERSION_CONTROL : UNKNOWN_METHOD);
647 return (memcmp(method, "BASELINE-CONTROL", 16) == 0
648 ? M_BASELINE_CONTROL : UNKNOWN_METHOD);
651 return UNKNOWN_METHOD;
657 /* Get the method number associated with the given string, assumed to
658 * contain an HTTP method. Returns M_INVALID if not recognized.
660 * This is the first step toward placing method names in a configurable
661 * list. Hopefully it (and other routines) can eventually be moved to
662 * something like a mod_http_methods.c, complete with config stuff.
664 AP_DECLARE(int) ap_method_number_of(const char *method)
666 int len = strlen(method);
667 int which = lookup_builtin_method(method, len);
669 if (which != UNKNOWN_METHOD)
672 /* check if the method has been dynamically registered */
673 if (methods_registry != NULL) {
674 int *methnum = apr_hash_get(methods_registry, method, len);
676 if (methnum != NULL) {
685 * Turn a known method number into a name.
687 AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum)
689 apr_hash_index_t *hi = apr_hash_first(p, methods_registry);
691 /* scan through the hash table, looking for a value that matches
692 the provided method number. */
693 for (; hi; hi = apr_hash_next(hi)) {
697 apr_hash_this(hi, &key, NULL, &val);
698 if (*(int *)val == methnum)
702 /* it wasn't found in the hash */
706 static long get_chunk_size(char *);
708 typedef struct http_filter_ctx {
711 apr_off_t limit_used;
720 /* This is the HTTP_INPUT filter for HTTP requests and responses from
721 * proxied servers (mod_proxy). It handles chunked and content-length
722 * bodies. This can only be inserted/used after the headers
723 * are successfully parsed.
725 apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
726 ap_input_mode_t mode, apr_read_type_e block,
730 http_ctx_t *ctx = f->ctx;
734 /* just get out of the way of things we don't want. */
735 if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
736 return ap_get_brigade(f->next, b, mode, block, readbytes);
740 const char *tenc, *lenp;
741 f->ctx = ctx = apr_palloc(f->r->pool, sizeof(*ctx));
742 ctx->state = BODY_NONE;
747 /* LimitRequestBody does not apply to proxied responses.
748 * Consider implementing this check in its own filter.
749 * Would adding a directive to limit the size of proxied
750 * responses be useful?
752 if (!f->r->proxyreq) {
753 ctx->limit = ap_get_limit_req_body(f->r);
759 tenc = apr_table_get(f->r->headers_in, "Transfer-Encoding");
760 lenp = apr_table_get(f->r->headers_in, "Content-Length");
763 if (!strcasecmp(tenc, "chunked")) {
764 ctx->state = BODY_CHUNK;
768 int conversion_error = 0;
771 ctx->state = BODY_LENGTH;
773 ctx->remaining = strtol(lenp, &endstr, 10); /* we depend on ANSI */
775 /* This protects us from over/underflow (the errno check),
776 * non-digit chars in the string (excluding leading space)
777 * (the endstr checks) and a negative number. Depending
778 * on the strtol implementation, the errno check may also
779 * trigger on an all whitespace string */
780 if (errno || (endstr && *endstr) || (ctx->remaining < 0)) {
781 conversion_error = 1;
784 if (conversion_error) {
785 apr_bucket_brigade *bb;
787 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
788 "Invalid Content-Length");
790 bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
791 e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
792 f->r->pool, f->c->bucket_alloc);
793 APR_BRIGADE_INSERT_TAIL(bb, e);
794 e = apr_bucket_eos_create(f->c->bucket_alloc);
795 APR_BRIGADE_INSERT_TAIL(bb, e);
797 return ap_pass_brigade(f->r->output_filters, bb);
800 /* If we have a limit in effect and we know the C-L ahead of
801 * time, stop it here if it is invalid.
803 if (ctx->limit && ctx->limit < ctx->remaining) {
804 apr_bucket_brigade *bb;
805 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
806 "Requested content-length of %" APR_OFF_T_FMT
807 " is larger than the configured limit"
808 " of %" APR_OFF_T_FMT, ctx->remaining, ctx->limit);
809 bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
810 e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
811 f->r->pool, f->c->bucket_alloc);
812 APR_BRIGADE_INSERT_TAIL(bb, e);
813 e = apr_bucket_eos_create(f->c->bucket_alloc);
814 APR_BRIGADE_INSERT_TAIL(bb, e);
816 return ap_pass_brigade(f->r->output_filters, bb);
820 /* If we don't have a request entity indicated by the headers, EOS.
821 * (BODY_NONE is a valid intermediate state due to trailers,
822 * but it isn't a valid starting state.)
824 * RFC 2616 Section 4.4 note 5 states that connection-close
825 * is invalid for a request entity - request bodies must be
826 * denoted by C-L or T-E: chunked.
828 * Note that since the proxy uses this filter to handle the
829 * proxied *response*, proxy responses MUST be exempt.
831 if (ctx->state == BODY_NONE && f->r->proxyreq != PROXYREQ_RESPONSE) {
832 e = apr_bucket_eos_create(f->c->bucket_alloc);
833 APR_BRIGADE_INSERT_TAIL(b, e);
838 /* Since we're about to read data, send 100-Continue if needed.
839 * Only valid on chunked and C-L bodies where the C-L is > 0. */
840 if ((ctx->state == BODY_CHUNK ||
841 (ctx->state == BODY_LENGTH && ctx->remaining > 0)) &&
842 f->r->expecting_100 && f->r->proto_num >= HTTP_VERSION(1,1)) {
844 apr_bucket_brigade *bb;
846 tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL, " ",
847 status_lines[0], CRLF CRLF, NULL);
848 bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
849 e = apr_bucket_pool_create(tmp, strlen(tmp), f->r->pool,
851 APR_BRIGADE_INSERT_HEAD(bb, e);
852 e = apr_bucket_flush_create(f->c->bucket_alloc);
853 APR_BRIGADE_INSERT_TAIL(bb, e);
855 ap_pass_brigade(f->c->output_filters, bb);
858 /* We can't read the chunk until after sending 100 if required. */
859 if (ctx->state == BODY_CHUNK) {
861 apr_bucket_brigade *bb;
864 bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
866 rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
869 if (rv == APR_SUCCESS) {
870 rv = apr_brigade_flatten(bb, line, &len);
871 if (rv == APR_SUCCESS) {
872 ctx->remaining = get_chunk_size(line);
875 apr_brigade_cleanup(bb);
877 /* Detect chunksize error (such as overflow) */
878 if (rv != APR_SUCCESS || ctx->remaining < 0) {
879 ctx->remaining = 0; /* Reset it in case we have to
880 * come back here later */
881 e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
884 APR_BRIGADE_INSERT_TAIL(bb, e);
885 e = apr_bucket_eos_create(f->c->bucket_alloc);
886 APR_BRIGADE_INSERT_TAIL(bb, e);
888 return ap_pass_brigade(f->r->output_filters, bb);
891 if (!ctx->remaining) {
892 /* Handle trailers by calling ap_get_mime_headers again! */
893 ctx->state = BODY_NONE;
894 ap_get_mime_headers(f->r);
895 e = apr_bucket_eos_create(f->c->bucket_alloc);
896 APR_BRIGADE_INSERT_TAIL(b, e);
904 e = apr_bucket_eos_create(f->c->bucket_alloc);
905 APR_BRIGADE_INSERT_TAIL(b, e);
909 if (!ctx->remaining) {
910 switch (ctx->state) {
914 e = apr_bucket_eos_create(f->c->bucket_alloc);
915 APR_BRIGADE_INSERT_TAIL(b, e);
921 apr_bucket_brigade *bb;
924 bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
926 /* We need to read the CRLF after the chunk. */
927 rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
929 apr_brigade_cleanup(bb);
931 if (rv == APR_SUCCESS) {
932 /* Read the real chunk line. */
933 rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
935 if (rv == APR_SUCCESS) {
936 rv = apr_brigade_flatten(bb, line, &len);
937 if (rv == APR_SUCCESS) {
938 ctx->remaining = get_chunk_size(line);
941 apr_brigade_cleanup(bb);
944 /* Detect chunksize error (such as overflow) */
945 if (rv != APR_SUCCESS || ctx->remaining < 0) {
946 ctx->remaining = 0; /* Reset it in case we have to
947 * come back here later */
948 e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE,
951 APR_BRIGADE_INSERT_TAIL(bb, e);
952 e = apr_bucket_eos_create(f->c->bucket_alloc);
953 APR_BRIGADE_INSERT_TAIL(bb, e);
955 return ap_pass_brigade(f->r->output_filters, bb);
958 if (!ctx->remaining) {
959 /* Handle trailers by calling ap_get_mime_headers again! */
960 ctx->state = BODY_NONE;
961 ap_get_mime_headers(f->r);
962 e = apr_bucket_eos_create(f->c->bucket_alloc);
963 APR_BRIGADE_INSERT_TAIL(b, e);
972 /* Ensure that the caller can not go over our boundary point. */
973 if (ctx->state == BODY_LENGTH || ctx->state == BODY_CHUNK) {
974 if (ctx->remaining < readbytes) {
975 readbytes = ctx->remaining;
977 AP_DEBUG_ASSERT(readbytes > 0);
980 rv = ap_get_brigade(f->next, b, mode, block, readbytes);
982 if (rv != APR_SUCCESS) {
986 /* How many bytes did we just read? */
987 apr_brigade_length(b, 0, &totalread);
989 /* If this happens, we have a bucket of unknown length. Die because
990 * it means our assumptions have changed. */
991 AP_DEBUG_ASSERT(totalread >= 0);
993 if (ctx->state != BODY_NONE) {
994 ctx->remaining -= totalread;
997 /* If we have no more bytes remaining on a C-L request,
998 * save the callter a roundtrip to discover EOS.
1000 if (ctx->state == BODY_LENGTH && ctx->remaining == 0) {
1001 e = apr_bucket_eos_create(f->c->bucket_alloc);
1002 APR_BRIGADE_INSERT_TAIL(b, e);
1005 /* We have a limit in effect. */
1007 /* FIXME: Note that we might get slightly confused on chunked inputs
1008 * as we'd need to compensate for the chunk lengths which may not
1009 * really count. This seems to be up for interpretation. */
1010 ctx->limit_used += totalread;
1011 if (ctx->limit < ctx->limit_used) {
1012 apr_bucket_brigade *bb;
1013 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
1014 "Read content-length of %" APR_OFF_T_FMT
1015 " is larger than the configured limit"
1016 " of %" APR_OFF_T_FMT, ctx->limit_used, ctx->limit);
1017 bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
1018 e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
1020 f->c->bucket_alloc);
1021 APR_BRIGADE_INSERT_TAIL(bb, e);
1022 e = apr_bucket_eos_create(f->c->bucket_alloc);
1023 APR_BRIGADE_INSERT_TAIL(bb, e);
1025 return ap_pass_brigade(f->r->output_filters, bb);
1032 /* The index is found by its offset from the x00 code of each level.
1033 * Although this is fast, it will need to be replaced if some nutcase
1034 * decides to define a high-numbered code before the lower numbers.
1035 * If that sad event occurs, replace the code below with a linear search
1036 * from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1];
1038 AP_DECLARE(int) ap_index_of_response(int status)
1040 static int shortcut[6] = {0, LEVEL_200, LEVEL_300, LEVEL_400,
1041 LEVEL_500, RESPONSE_CODES};
1044 if (status < 100) { /* Below 100 is illegal for HTTP status */
1048 for (i = 0; i < 5; i++) {
1051 pos = (status + shortcut[i]);
1052 if (pos < shortcut[i + 1]) {
1056 return LEVEL_500; /* status unknown (falls in gap) */
1060 return LEVEL_500; /* 600 or above is also illegal */
1063 AP_DECLARE(const char *) ap_get_status_line(int status)
1065 return status_lines[ap_index_of_response(status)];
1068 typedef struct header_struct {
1070 apr_bucket_brigade *bb;
1073 /* Send a single HTTP header field to the client. Note that this function
1074 * is used in calls to table_do(), so their interfaces are co-dependent.
1075 * In other words, don't change this one without checking table_do in alloc.c.
1076 * It returns true unless there was a write error of some kind.
1078 static int form_header_field(header_struct *h,
1079 const char *fieldname, const char *fieldval)
1081 #if APR_CHARSET_EBCDIC
1084 apr_size_t name_len;
1088 name_len = strlen(fieldname);
1089 val_len = strlen(fieldval);
1090 len = name_len + val_len + 4; /* 4 for ": " plus CRLF */
1091 headfield = (char *)apr_palloc(h->pool, len + 1);
1092 memcpy(headfield, fieldname, name_len);
1093 next = headfield + name_len;
1096 memcpy(next, fieldval, val_len);
1101 ap_xlate_proto_to_ascii(headfield, len);
1102 apr_brigade_write(h->bb, NULL, NULL, headfield, len);
1104 struct iovec vec[4];
1105 struct iovec *v = vec;
1106 v->iov_base = (void *)fieldname;
1107 v->iov_len = strlen(fieldname);
1110 v->iov_len = sizeof(": ") - 1;
1112 v->iov_base = (void *)fieldval;
1113 v->iov_len = strlen(fieldval);
1116 v->iov_len = sizeof(CRLF) - 1;
1117 apr_brigade_writev(h->bb, NULL, NULL, vec, 4);
1118 #endif /* !APR_CHARSET_EBCDIC */
1122 /* Send a request's HTTP response headers to the client.
1124 static apr_status_t send_all_header_fields(header_struct *h,
1125 const request_rec *r)
1127 const apr_array_header_t *elts;
1128 const apr_table_entry_t *t_elt;
1129 const apr_table_entry_t *t_end;
1131 struct iovec *vec_next;
1133 elts = apr_table_elts(r->headers_out);
1134 if (elts->nelts == 0) {
1137 t_elt = (const apr_table_entry_t *)(elts->elts);
1138 t_end = t_elt + elts->nelts;
1139 vec = (struct iovec *)apr_palloc(h->pool, 4 * elts->nelts *
1140 sizeof(struct iovec));
1143 /* For each field, generate
1144 * name ": " value CRLF
1147 vec_next->iov_base = (void*)(t_elt->key);
1148 vec_next->iov_len = strlen(t_elt->key);
1150 vec_next->iov_base = ": ";
1151 vec_next->iov_len = sizeof(": ") - 1;
1153 vec_next->iov_base = (void*)(t_elt->val);
1154 vec_next->iov_len = strlen(t_elt->val);
1156 vec_next->iov_base = CRLF;
1157 vec_next->iov_len = sizeof(CRLF) - 1;
1160 } while (t_elt < t_end);
1162 #if APR_CHARSET_EBCDIC
1165 char *tmp = apr_pstrcatv(r->pool, vec, vec_next - vec, &len);
1166 ap_xlate_proto_to_ascii(tmp, len);
1167 return apr_brigade_write(h->bb, NULL, NULL, tmp, len);
1170 return apr_brigade_writev(h->bb, NULL, NULL, vec, vec_next - vec);
1174 /* Confirm that the status line is well-formed and matches r->status.
1175 * Otherwise, a filter may have negated the status line set by a
1177 * Zap r->status_line if bad.
1179 static void validate_status_line(request_rec *r)
1184 && (strlen(r->status_line) <= 4
1185 || apr_strtoi64(r->status_line, &end, 10) != r->status
1187 || (end - 3) != r->status_line)) {
1188 r->status_line = NULL;
1193 * Determine the protocol to use for the response. Potentially downgrade
1194 * to HTTP/1.0 in some situations and/or turn off keepalives.
1196 * also prepare r->status_line.
1198 static void basic_http_header_check(request_rec *r,
1199 const char **protocol)
1201 if (r->assbackwards) {
1202 /* no such thing as a response protocol */
1206 validate_status_line(r);
1208 if (!r->status_line) {
1209 r->status_line = status_lines[ap_index_of_response(r->status)];
1212 /* Note that we must downgrade before checking for force responses. */
1213 if (r->proto_num > HTTP_VERSION(1,0)
1214 && apr_table_get(r->subprocess_env, "downgrade-1.0")) {
1215 r->proto_num = HTTP_VERSION(1,0);
1218 /* kludge around broken browsers when indicated by force-response-1.0
1220 if (r->proto_num == HTTP_VERSION(1,0)
1221 && apr_table_get(r->subprocess_env, "force-response-1.0")) {
1222 *protocol = "HTTP/1.0";
1223 r->connection->keepalive = AP_CONN_CLOSE;
1226 *protocol = AP_SERVER_PROTOCOL;
1231 /* fill "bb" with a barebones/initial HTTP response header */
1232 static void basic_http_header(request_rec *r, apr_bucket_brigade *bb,
1233 const char *protocol)
1238 struct iovec vec[4];
1240 if (r->assbackwards) {
1241 /* there are no headers to send */
1245 /* Output the HTTP/1.x Status-Line and the Date and Server fields */
1247 vec[0].iov_base = (void *)protocol;
1248 vec[0].iov_len = strlen(protocol);
1249 vec[1].iov_base = (void *)" ";
1250 vec[1].iov_len = sizeof(" ") - 1;
1251 vec[2].iov_base = (void *)(r->status_line);
1252 vec[2].iov_len = strlen(r->status_line);
1253 vec[3].iov_base = (void *)CRLF;
1254 vec[3].iov_len = sizeof(CRLF) - 1;
1255 #if APR_CHARSET_EBCDIC
1259 tmp = apr_pstrcatv(r->pool, vec, 4, &len);
1260 ap_xlate_proto_to_ascii(tmp, len);
1261 apr_brigade_write(bb, NULL, NULL, tmp, len);
1264 apr_brigade_writev(bb, NULL, NULL, vec, 4);
1267 date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
1268 ap_recent_rfc822_date(date, r->request_time);
1272 form_header_field(&h, "Date", date);
1274 /* keep the set-by-proxy server header, otherwise
1275 * generate a new server header */
1276 if (r->proxyreq != PROXYREQ_NONE) {
1277 server = apr_table_get(r->headers_out, "Server");
1279 form_header_field(&h, "Server", server);
1283 form_header_field(&h, "Server", ap_get_server_version());
1286 /* unset so we don't send them again */
1287 apr_table_unset(r->headers_out, "Date"); /* Avoid bogosity */
1288 apr_table_unset(r->headers_out, "Server");
1291 AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb)
1293 const char *protocol;
1295 basic_http_header_check(r, &protocol);
1296 basic_http_header(r, bb, protocol);
1299 /* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
1300 * have a header parsing bug. If the terminating \r\n occur starting
1301 * at offset 256, 257 or 258 of output then it will not properly parse
1302 * the headers. Curiously it doesn't exhibit this problem at 512, 513.
1303 * We are guessing that this is because their initial read of a new request
1304 * uses a 256 byte buffer, and subsequent reads use a larger buffer.
1305 * So the problem might exist at different offsets as well.
1307 * This should also work on keepalive connections assuming they use the
1308 * same small buffer for the first read of each new request.
1310 * At any rate, we check the bytes written so far and, if we are about to
1311 * tickle the bug, we instead insert a bogus padding header. Since the bug
1312 * manifests as a broken image in Navigator, users blame the server. :(
1313 * It is more expensive to check the User-Agent than it is to just add the
1314 * bytes, so we haven't used the BrowserMatch feature here.
1316 static void terminate_header(apr_bucket_brigade *bb)
1318 char tmp[] = "X-Pad: avoid browser bug" CRLF;
1323 (void) apr_brigade_length(bb, 1, &len);
1325 if (len >= 255 && len <= 257) {
1326 buflen = strlen(tmp);
1327 ap_xlate_proto_to_ascii(tmp, buflen);
1328 apr_brigade_write(bb, NULL, NULL, tmp, buflen);
1330 buflen = strlen(crlf);
1331 ap_xlate_proto_to_ascii(crlf, buflen);
1332 apr_brigade_write(bb, NULL, NULL, crlf, buflen);
1335 /* Build the Allow field-value from the request handler method mask.
1336 * Note that we always allow TRACE, since it is handled below.
1338 static char *make_allow(request_rec *r)
1342 apr_array_header_t *allow = apr_array_make(r->pool, 10, sizeof(char *));
1343 apr_hash_index_t *hi = apr_hash_first(r->pool, methods_registry);
1344 /* For TRACE below */
1345 core_server_config *conf =
1346 ap_get_module_config(r->server->module_config, &core_module);
1348 mask = r->allowed_methods->method_mask;
1350 for (; hi; hi = apr_hash_next(hi)) {
1354 apr_hash_this(hi, &key, NULL, &val);
1355 if ((mask & (AP_METHOD_BIT << *(int *)val)) != 0) {
1356 *(const char **)apr_array_push(allow) = key;
1358 /* the M_GET method actually refers to two methods */
1359 if (*(int *)val == M_GET)
1360 *(const char **)apr_array_push(allow) = "HEAD";
1364 /* TRACE is tested on a per-server basis */
1365 if (conf->trace_enable != AP_TRACE_DISABLE)
1366 *(const char **)apr_array_push(allow) = "TRACE";
1368 list = apr_array_pstrcat(r->pool, allow, ',');
1370 /* ### this is rather annoying. we should enforce registration of
1371 ### these methods */
1372 if ((mask & (AP_METHOD_BIT << M_INVALID))
1373 && (r->allowed_methods->method_list != NULL)
1374 && (r->allowed_methods->method_list->nelts != 0)) {
1376 char **xmethod = (char **) r->allowed_methods->method_list->elts;
1379 * Append all of the elements of r->allowed_methods->method_list
1381 for (i = 0; i < r->allowed_methods->method_list->nelts; ++i) {
1382 list = apr_pstrcat(r->pool, list, ",", xmethod[i], NULL);
1389 AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r)
1391 core_server_config *conf;
1393 apr_bucket_brigade *bb;
1397 char *bodyread = NULL, *bodyoff;
1398 apr_size_t bodylen = 0;
1402 if (r->method_number != M_TRACE) {
1406 /* Get the original request */
1410 conf = (core_server_config *)ap_get_module_config(r->server->module_config,
1413 if (conf->trace_enable == AP_TRACE_DISABLE) {
1414 apr_table_setn(r->notes, "error-notes",
1415 "TRACE denied by server configuration");
1416 return HTTP_FORBIDDEN;
1419 if (conf->trace_enable == AP_TRACE_EXTENDED)
1420 /* XX should be = REQUEST_CHUNKED_PASS */
1421 body = REQUEST_CHUNKED_DECHUNK;
1423 body = REQUEST_NO_BODY;
1425 if ((rv = ap_setup_client_block(r, body))) {
1426 if (rv == HTTP_REQUEST_ENTITY_TOO_LARGE)
1427 apr_table_setn(r->notes, "error-notes",
1428 "TRACE with a request body is not allowed");
1432 if (ap_should_client_block(r)) {
1434 if (r->remaining > 0) {
1435 if (r->remaining > 65536) {
1436 apr_table_setn(r->notes, "error-notes",
1437 "Extended TRACE request bodies cannot exceed 64k");
1438 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1440 /* always 32 extra bytes to catch chunk header exceptions */
1441 bodybuf = (apr_size_t)r->remaining + 32;
1444 /* Add an extra 8192 for chunk headers */
1448 bodyoff = bodyread = apr_palloc(r->pool, bodybuf);
1450 /* only while we have enough for a chunked header */
1451 while ((!bodylen || bodybuf >= 32) &&
1452 (res = ap_get_client_block(r, bodyoff, bodybuf)) > 0) {
1457 if (res > 0 && bodybuf < 32) {
1458 /* discard_rest_of_request_body into our buffer */
1459 while (ap_get_client_block(r, bodyread, bodylen) > 0)
1461 apr_table_setn(r->notes, "error-notes",
1462 "Extended TRACE request bodies cannot exceed 64k");
1463 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1467 return HTTP_BAD_REQUEST;
1471 ap_set_content_type(r, "message/http");
1473 /* Now we recreate the request, and echo it back */
1475 bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1476 apr_brigade_putstrs(bb, NULL, NULL, r->the_request, CRLF, NULL);
1479 apr_table_do((int (*) (void *, const char *, const char *))
1480 form_header_field, (void *) &h, r->headers_in, NULL);
1481 apr_brigade_puts(bb, NULL, NULL, CRLF);
1483 /* If configured to accept a body, echo the body */
1485 b = apr_bucket_pool_create(bodyread, bodylen,
1486 r->pool, bb->bucket_alloc);
1487 APR_BRIGADE_INSERT_TAIL(bb, b);
1490 ap_pass_brigade(r->output_filters, bb);
1495 AP_DECLARE(int) ap_send_http_options(request_rec *r)
1497 if (r->assbackwards) {
1501 apr_table_setn(r->headers_out, "Allow", make_allow(r));
1503 /* the request finalization will send an EOS, which will flush all
1504 * the headers out (including the Allow header)
1510 /* This routine is called by apr_table_do and merges all instances of
1511 * the passed field values into a single array that will be further
1512 * processed by some later routine. Originally intended to help split
1513 * and recombine multiple Vary fields, though it is generic to any field
1514 * consisting of comma/space-separated tokens.
1516 static int uniq_field_values(void *d, const char *key, const char *val)
1518 apr_array_header_t *values;
1524 values = (apr_array_header_t *)d;
1526 e = apr_pstrdup(values->pool, val);
1529 /* Find a non-empty fieldname */
1531 while (*e == ',' || apr_isspace(*e)) {
1538 while (*e != '\0' && *e != ',' && !apr_isspace(*e)) {
1545 /* Now add it to values if it isn't already represented.
1546 * Could be replaced by a ap_array_strcasecmp() if we had one.
1548 for (i = 0, strpp = (char **) values->elts; i < values->nelts;
1550 if (*strpp && strcasecmp(*strpp, start) == 0) {
1554 if (i == values->nelts) { /* if not found */
1555 *(char **)apr_array_push(values) = start;
1557 } while (*e != '\0');
1563 * Since some clients choke violently on multiple Vary fields, or
1564 * Vary fields with duplicate tokens, combine any multiples and remove
1567 static void fixup_vary(request_rec *r)
1569 apr_array_header_t *varies;
1571 varies = apr_array_make(r->pool, 5, sizeof(char *));
1573 /* Extract all Vary fields from the headers_out, separate each into
1574 * its comma-separated fieldname values, and then add them to varies
1575 * if not already present in the array.
1577 apr_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
1578 (void *) varies, r->headers_out, "Vary", NULL);
1580 /* If we found any, replace old Vary fields with unique-ified value */
1582 if (varies->nelts > 0) {
1583 apr_table_setn(r->headers_out, "Vary",
1584 apr_array_pstrcat(r->pool, varies, ','));
1588 AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct)
1591 r->content_type = NULL;
1593 else if (!r->content_type || strcmp(r->content_type, ct)) {
1594 r->content_type = ct;
1596 /* Insert filters requested by the AddOutputFiltersByType
1597 * configuration directive. Content-type filters must be
1598 * inserted after the content handlers have run because
1599 * only then, do we reliably know the content-type.
1601 ap_add_output_filters_by_type(r);
1605 typedef struct header_filter_ctx {
1607 } header_filter_ctx;
1609 AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
1610 apr_bucket_brigade *b)
1612 request_rec *r = f->r;
1613 conn_rec *c = r->connection;
1614 const char *clheader;
1615 const char *protocol;
1617 apr_bucket_brigade *b2;
1619 header_filter_ctx *ctx = f->ctx;
1621 AP_DEBUG_ASSERT(!r->main);
1623 if (r->header_only) {
1625 ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx));
1627 else if (ctx->headers_sent) {
1628 apr_brigade_destroy(b);
1633 APR_BRIGADE_FOREACH(e, b) {
1634 if (e->type == &ap_bucket_type_error) {
1635 ap_bucket_error *eb = e->data;
1637 ap_die(eb->status, r);
1638 return AP_FILTER_ERROR;
1642 if (r->assbackwards) {
1644 ap_remove_output_filter(f);
1645 return ap_pass_brigade(f->next, b);
1649 * Now that we are ready to send a response, we need to combine the two
1650 * header field tables into a single table. If we don't do this, our
1651 * later attempts to set or unset a given fieldname might be bypassed.
1653 if (!apr_is_empty_table(r->err_headers_out)) {
1654 r->headers_out = apr_table_overlay(r->pool, r->err_headers_out,
1659 * Remove the 'Vary' header field if the client can't handle it.
1660 * Since this will have nasty effects on HTTP/1.1 caches, force
1661 * the response into HTTP/1.0 mode.
1663 * Note: the force-response-1.0 should come before the call to
1664 * basic_http_header_check()
1666 if (apr_table_get(r->subprocess_env, "force-no-vary") != NULL) {
1667 apr_table_unset(r->headers_out, "Vary");
1668 r->proto_num = HTTP_VERSION(1,0);
1669 apr_table_set(r->subprocess_env, "force-response-1.0", "1");
1676 * Now remove any ETag response header field if earlier processing
1677 * says so (such as a 'FileETag None' directive).
1679 if (apr_table_get(r->notes, "no-etag") != NULL) {
1680 apr_table_unset(r->headers_out, "ETag");
1683 /* determine the protocol and whether we should use keepalives. */
1684 basic_http_header_check(r, &protocol);
1685 ap_set_keepalive(r);
1688 apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
1689 apr_table_unset(r->headers_out, "Content-Length");
1692 apr_table_setn(r->headers_out, "Content-Type",
1693 ap_make_content_type(r, r->content_type));
1695 if (r->content_encoding) {
1696 apr_table_setn(r->headers_out, "Content-Encoding",
1697 r->content_encoding);
1700 if (!apr_is_empty_array(r->content_languages)) {
1702 char **languages = (char **)(r->content_languages->elts);
1703 for (i = 0; i < r->content_languages->nelts; ++i) {
1704 apr_table_mergen(r->headers_out, "Content-Language", languages[i]);
1709 * Control cachability for non-cachable responses if not already set by
1710 * some other part of the server configuration.
1712 if (r->no_cache && !apr_table_get(r->headers_out, "Expires")) {
1713 char *date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
1714 ap_recent_rfc822_date(date, r->request_time);
1715 apr_table_addn(r->headers_out, "Expires", date);
1718 /* This is a hack, but I can't find anyway around it. The idea is that
1719 * we don't want to send out 0 Content-Lengths if it is a head request.
1720 * This happens when modules try to outsmart the server, and return
1721 * if they see a HEAD request. Apache 1.3 handlers were supposed to
1722 * just return in that situation, and the core handled the HEAD. In
1723 * 2.0, if a handler returns, then the core sends an EOS bucket down
1724 * the filter stack, and the content-length filter computes a C-L of
1725 * zero and that gets put in the headers, and we end up sending a
1726 * zero C-L to the client. We can't just remove the C-L filter,
1727 * because well behaved 2.0 handlers will send their data down the stack,
1728 * and we will compute a real C-L for the head request. RBB
1731 && (clheader = apr_table_get(r->headers_out, "Content-Length"))
1732 && !strcmp(clheader, "0")) {
1733 apr_table_unset(r->headers_out, "Content-Length");
1736 b2 = apr_brigade_create(r->pool, c->bucket_alloc);
1737 basic_http_header(r, b2, protocol);
1742 if (r->status == HTTP_NOT_MODIFIED) {
1743 apr_table_do((int (*)(void *, const char *, const char *)) form_header_field,
1744 (void *) &h, r->headers_out,
1754 "Proxy-Authenticate",
1760 send_all_header_fields(&h, r);
1763 terminate_header(b2);
1765 ap_pass_brigade(f->next, b2);
1767 if (r->header_only) {
1768 apr_brigade_destroy(b);
1769 ctx->headers_sent = 1;
1773 r->sent_bodyct = 1; /* Whatever follows is real body stuff... */
1776 /* We can't add this filter until we have already sent the headers.
1777 * If we add it before this point, then the headers will be chunked
1778 * as well, and that is just wrong.
1780 ap_add_output_filter("CHUNK", NULL, r, r->connection);
1783 /* Don't remove this filter until after we have added the CHUNK filter.
1784 * Otherwise, f->next won't be the CHUNK filter and thus the first
1785 * brigade won't be chunked properly.
1787 ap_remove_output_filter(f);
1788 return ap_pass_brigade(f->next, b);
1791 /* Here we deal with getting the request message body from the client.
1792 * Whether or not the request contains a body is signaled by the presence
1793 * of a non-zero Content-Length or by a Transfer-Encoding: chunked.
1795 * Note that this is more complicated than it was in Apache 1.1 and prior
1796 * versions, because chunked support means that the module does less.
1798 * The proper procedure is this:
1800 * 1. Call setup_client_block() near the beginning of the request
1801 * handler. This will set up all the necessary properties, and will
1802 * return either OK, or an error code. If the latter, the module should
1803 * return that error code. The second parameter selects the policy to
1804 * apply if the request message indicates a body, and how a chunked
1805 * transfer-coding should be interpreted. Choose one of
1807 * REQUEST_NO_BODY Send 413 error if message has any body
1808 * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
1809 * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
1811 * In order to use the last two options, the caller MUST provide a buffer
1812 * large enough to hold a chunk-size line, including any extensions.
1814 * 2. When you are ready to read a body (if any), call should_client_block().
1815 * This will tell the module whether or not to read input. If it is 0,
1816 * the module should assume that there is no message body to read.
1817 * This step also sends a 100 Continue response to HTTP/1.1 clients,
1818 * so should not be called until the module is *definitely* ready to
1819 * read content. (otherwise, the point of the 100 response is defeated).
1820 * Never call this function more than once.
1822 * 3. Finally, call get_client_block in a loop. Pass it a buffer and its size.
1823 * It will put data into the buffer (not necessarily a full buffer), and
1824 * return the length of the input block. When it is done reading, it will
1825 * return 0 if EOF, or -1 if there was an error.
1826 * If an error occurs on input, we force an end to keepalive.
1829 AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy)
1831 const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
1832 const char *lenp = apr_table_get(r->headers_in, "Content-Length");
1834 r->read_body = read_policy;
1835 r->read_chunked = 0;
1839 if (strcasecmp(tenc, "chunked")) {
1840 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1841 "Unknown Transfer-Encoding %s", tenc);
1842 return HTTP_NOT_IMPLEMENTED;
1844 if (r->read_body == REQUEST_CHUNKED_ERROR) {
1845 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1846 "chunked Transfer-Encoding forbidden: %s", r->uri);
1847 return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
1850 r->read_chunked = 1;
1853 int conversion_error = 0;
1857 r->remaining = strtol(lenp, &endstr, 10); /* depend on ANSI */
1859 /* See comments in ap_http_filter() */
1860 if (errno || (endstr && *endstr) || (r->remaining < 0)) {
1861 conversion_error = 1;
1864 if (conversion_error) {
1865 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1866 "Invalid Content-Length");
1867 return HTTP_BAD_REQUEST;
1871 if ((r->read_body == REQUEST_NO_BODY)
1872 && (r->read_chunked || (r->remaining > 0))) {
1873 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1874 "%s with body is not allowed for %s", r->method, r->uri);
1875 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1880 /* Make sure ap_getline() didn't leave any droppings. */
1881 core_request_config *req_cfg =
1882 (core_request_config *)ap_get_module_config(r->request_config,
1884 AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(req_cfg->bb));
1891 AP_DECLARE(int) ap_should_client_block(request_rec *r)
1893 /* First check if we have already read the request body */
1895 if (r->read_length || (!r->read_chunked && (r->remaining <= 0))) {
1903 * Parse a chunk extension, detect overflow.
1904 * There are two error cases:
1905 * 1) If the conversion would require too many bits, a -1 is returned.
1906 * 2) If the conversion used the correct number of bits, but an overflow
1907 * caused only the sign bit to flip, then that negative number is
1909 * In general, any negative number can be considered an overflow error.
1911 static long get_chunk_size(char *b)
1914 size_t chunkbits = sizeof(long) * 8;
1916 ap_xlate_proto_from_ascii(b, strlen(b));
1918 /* Skip leading zeros */
1923 while (apr_isxdigit(*b) && (chunkbits > 0)) {
1926 if (*b >= '0' && *b <= '9') {
1929 else if (*b >= 'A' && *b <= 'F') {
1930 xvalue = *b - 'A' + 0xa;
1932 else if (*b >= 'a' && *b <= 'f') {
1933 xvalue = *b - 'a' + 0xa;
1936 chunksize = (chunksize << 4) | xvalue;
1940 if (apr_isxdigit(*b) && (chunkbits <= 0)) {
1948 /* get_client_block is called in a loop to get the request message body.
1949 * This is quite simple if the client includes a content-length
1950 * (the normal case), but gets messy if the body is chunked. Note that
1951 * r->remaining is used to maintain state across calls and that
1952 * r->read_length is the total number of bytes given to the caller
1953 * across all invocations. It is messy because we have to be careful not
1954 * to read past the data provided by the client, since these reads block.
1955 * Returns 0 on End-of-body, -1 on error or premature chunk end.
1958 AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer,
1962 apr_bucket_brigade *bb;
1964 if (r->remaining < 0 || (!r->read_chunked && r->remaining == 0)) {
1968 bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1970 r->connection->keepalive = AP_CONN_CLOSE;
1974 rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
1975 APR_BLOCK_READ, bufsiz);
1977 /* We lose the failure code here. This is why ap_get_client_block should
1980 if (rv != APR_SUCCESS) {
1981 /* if we actually fail here, we want to just return and
1982 * stop trying to read data from the client.
1984 r->connection->keepalive = AP_CONN_CLOSE;
1985 apr_brigade_destroy(bb);
1989 /* If this fails, it means that a filter is written incorrectly and that
1990 * it needs to learn how to properly handle APR_BLOCK_READ requests by
1991 * returning data when requested.
1993 AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(bb));
1995 /* Check to see if EOS in the brigade.
1997 * If so, we have to leave a nugget for the *next* ap_get_client_block
2000 if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
2001 if (r->read_chunked) {
2009 rv = apr_brigade_flatten(bb, buffer, &bufsiz);
2010 if (rv != APR_SUCCESS) {
2011 apr_brigade_destroy(bb);
2016 r->read_length += bufsiz;
2018 apr_brigade_destroy(bb);
2022 /* In HTTP/1.1, any method can have a body. However, most GET handlers
2023 * wouldn't know what to do with a request body if they received one.
2024 * This helper routine tests for and reads any message body in the request,
2025 * simply discarding whatever it receives. We need to do this because
2026 * failing to read the request body would cause it to be interpreted
2027 * as the next request on a persistent connection.
2029 * Since we return an error status if the request is malformed, this
2030 * routine should be called at the beginning of a no-body handler, e.g.,
2032 * if ((retval = ap_discard_request_body(r)) != OK) {
2036 AP_DECLARE(int) ap_discard_request_body(request_rec *r)
2038 apr_bucket_brigade *bb;
2041 /* Sometimes we'll get in a state where the input handling has
2042 * detected an error where we want to drop the connection, so if
2043 * that's the case, don't read the data as that is what we're trying
2046 * This function is also a no-op on a subrequest.
2048 if (r->main || r->connection->keepalive == AP_CONN_CLOSE ||
2049 ap_status_drops_connection(r->status)) {
2053 bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
2058 rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
2059 APR_BLOCK_READ, HUGE_STRING_LEN);
2061 if (rv != APR_SUCCESS) {
2062 /* FIXME: If we ever have a mapping from filters (apr_status_t)
2063 * to HTTP error codes, this would be a good place for them.
2065 * If we received the special case AP_FILTER_ERROR, it means
2066 * that the filters have already handled this error.
2067 * Otherwise, we should assume we have a bad request.
2069 if (rv == AP_FILTER_ERROR) {
2070 apr_brigade_destroy(bb);
2074 apr_brigade_destroy(bb);
2075 return HTTP_BAD_REQUEST;
2079 APR_BRIGADE_FOREACH(bucket, bb) {
2083 if (APR_BUCKET_IS_EOS(bucket)) {
2088 /* These are metadata buckets. */
2089 if (bucket->length == 0) {
2093 /* We MUST read because in case we have an unknown-length
2094 * bucket or one that morphs, we want to exhaust it.
2096 rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
2097 if (rv != APR_SUCCESS) {
2098 apr_brigade_destroy(bb);
2099 return HTTP_BAD_REQUEST;
2102 apr_brigade_cleanup(bb);
2103 } while (!seen_eos);
2108 static const char *add_optional_notes(request_rec *r,
2113 const char *notes, *result;
2115 if ((notes = apr_table_get(r->notes, key)) == NULL) {
2116 result = apr_pstrcat(r->pool, prefix, suffix, NULL);
2119 result = apr_pstrcat(r->pool, prefix, notes, suffix, NULL);
2125 /* construct and return the default error message for a given
2126 * HTTP defined error code
2128 static const char *get_canned_error_string(int status,
2130 const char *location)
2132 apr_pool_t *p = r->pool;
2133 const char *error_notes, *h1, *s1;
2136 case HTTP_MOVED_PERMANENTLY:
2137 case HTTP_MOVED_TEMPORARILY:
2138 case HTTP_TEMPORARY_REDIRECT:
2139 return(apr_pstrcat(p,
2140 "<p>The document has moved <a href=\"",
2141 ap_escape_html(r->pool, location),
2142 "\">here</a>.</p>\n",
2144 case HTTP_SEE_OTHER:
2145 return(apr_pstrcat(p,
2146 "<p>The answer to your request is located "
2148 ap_escape_html(r->pool, location),
2149 "\">here</a>.</p>\n",
2151 case HTTP_USE_PROXY:
2152 return(apr_pstrcat(p,
2153 "<p>This resource is only accessible "
2154 "through the proxy\n",
2155 ap_escape_html(r->pool, location),
2156 "<br />\nYou will need to configure "
2157 "your client to use that proxy.</p>\n",
2159 case HTTP_PROXY_AUTHENTICATION_REQUIRED:
2160 case HTTP_UNAUTHORIZED:
2161 return("<p>This server could not verify that you\n"
2162 "are authorized to access the document\n"
2163 "requested. Either you supplied the wrong\n"
2164 "credentials (e.g., bad password), or your\n"
2165 "browser doesn't understand how to supply\n"
2166 "the credentials required.</p>\n");
2167 case HTTP_BAD_REQUEST:
2168 return(add_optional_notes(r,
2169 "<p>Your browser sent a request that "
2170 "this server could not understand.<br />\n",
2173 case HTTP_FORBIDDEN:
2174 return(apr_pstrcat(p,
2175 "<p>You don't have permission to access ",
2176 ap_escape_html(r->pool, r->uri),
2177 "\non this server.</p>\n",
2179 case HTTP_NOT_FOUND:
2180 return(apr_pstrcat(p,
2181 "<p>The requested URL ",
2182 ap_escape_html(r->pool, r->uri),
2183 " was not found on this server.</p>\n",
2185 case HTTP_METHOD_NOT_ALLOWED:
2186 return(apr_pstrcat(p,
2187 "<p>The requested method ",
2188 ap_escape_html(r->pool, r->method),
2189 " is not allowed for the URL ",
2190 ap_escape_html(r->pool, r->uri),
2193 case HTTP_NOT_ACCEPTABLE:
2195 "<p>An appropriate representation of the "
2196 "requested resource ",
2197 ap_escape_html(r->pool, r->uri),
2198 " could not be found on this server.</p>\n",
2200 return(add_optional_notes(r, s1, "variant-list", ""));
2201 case HTTP_MULTIPLE_CHOICES:
2202 return(add_optional_notes(r, "", "variant-list", ""));
2203 case HTTP_LENGTH_REQUIRED:
2205 "<p>A request of the requested method ",
2206 ap_escape_html(r->pool, r->method),
2207 " requires a valid Content-length.<br />\n",
2209 return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
2210 case HTTP_PRECONDITION_FAILED:
2211 return(apr_pstrcat(p,
2212 "<p>The precondition on the request "
2214 ap_escape_html(r->pool, r->uri),
2215 " evaluated to false.</p>\n",
2217 case HTTP_NOT_IMPLEMENTED:
2220 ap_escape_html(r->pool, r->method), " to ",
2221 ap_escape_html(r->pool, r->uri),
2222 " not supported.<br />\n",
2224 return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
2225 case HTTP_BAD_GATEWAY:
2226 s1 = "<p>The proxy server received an invalid" CRLF
2227 "response from an upstream server.<br />" CRLF;
2228 return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
2229 case HTTP_VARIANT_ALSO_VARIES:
2230 return(apr_pstrcat(p,
2231 "<p>A variant for the requested "
2232 "resource\n<pre>\n",
2233 ap_escape_html(r->pool, r->uri),
2234 "\n</pre>\nis itself a negotiable resource. "
2235 "This indicates a configuration error.</p>\n",
2237 case HTTP_REQUEST_TIME_OUT:
2238 return("<p>Server timeout waiting for the HTTP request from the client.</p>\n");
2240 return(apr_pstrcat(p,
2241 "<p>The requested resource<br />",
2242 ap_escape_html(r->pool, r->uri),
2243 "<br />\nis no longer available on this server "
2244 "and there is no forwarding address.\n"
2245 "Please remove all references to this "
2248 case HTTP_REQUEST_ENTITY_TOO_LARGE:
2249 return(apr_pstrcat(p,
2250 "The requested resource<br />",
2251 ap_escape_html(r->pool, r->uri), "<br />\n",
2252 "does not allow request data with ",
2253 ap_escape_html(r->pool, r->method),
2254 " requests, or the amount of data provided in\n"
2255 "the request exceeds the capacity limit.\n",
2257 case HTTP_REQUEST_URI_TOO_LARGE:
2258 s1 = "<p>The requested URL's length exceeds the capacity\n"
2259 "limit for this server.<br />\n";
2260 return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
2261 case HTTP_UNSUPPORTED_MEDIA_TYPE:
2262 return("<p>The supplied request data is not in a format\n"
2263 "acceptable for processing by this resource.</p>\n");
2264 case HTTP_RANGE_NOT_SATISFIABLE:
2265 return("<p>None of the range-specifier values in the Range\n"
2266 "request-header field overlap the current extent\n"
2267 "of the selected resource.</p>\n");
2268 case HTTP_EXPECTATION_FAILED:
2269 return(apr_pstrcat(p,
2270 "<p>The expectation given in the Expect "
2272 "\nfield could not be met by this server.</p>\n"
2273 "<p>The client sent<pre>\n Expect: ",
2274 ap_escape_html(r->pool, apr_table_get(r->headers_in, "Expect")),
2276 "but we only allow the 100-continue "
2277 "expectation.</p>\n",
2279 case HTTP_UNPROCESSABLE_ENTITY:
2280 return("<p>The server understands the media type of the\n"
2281 "request entity, but was unable to process the\n"
2282 "contained instructions.</p>\n");
2284 return("<p>The requested resource is currently locked.\n"
2285 "The lock must be released or proper identification\n"
2286 "given before the method can be applied.</p>\n");
2287 case HTTP_FAILED_DEPENDENCY:
2288 return("<p>The method could not be performed on the resource\n"
2289 "because the requested action depended on another\n"
2290 "action and that other action failed.</p>\n");
2291 case HTTP_UPGRADE_REQUIRED:
2292 return("<p>The requested resource can only be retrieved\n"
2293 "using SSL. The server is willing to upgrade the current\n"
2294 "connection to SSL, but your client doesn't support it.\n"
2295 "Either upgrade your client, or try requesting the page\n"
2296 "using https://\n");
2297 case HTTP_INSUFFICIENT_STORAGE:
2298 return("<p>The method could not be performed on the resource\n"
2299 "because the server is unable to store the\n"
2300 "representation needed to successfully complete the\n"
2301 "request. There is insufficient free space left in\n"
2302 "your storage allocation.</p>\n");
2303 case HTTP_SERVICE_UNAVAILABLE:
2304 return("<p>The server is temporarily unable to service your\n"
2305 "request due to maintenance downtime or capacity\n"
2306 "problems. Please try again later.</p>\n");
2307 case HTTP_GATEWAY_TIME_OUT:
2308 return("<p>The proxy server did not receive a timely response\n"
2309 "from the upstream server.</p>\n");
2310 case HTTP_NOT_EXTENDED:
2311 return("<p>A mandatory extension policy in the request is not\n"
2312 "accepted by the server for this resource.</p>\n");
2313 default: /* HTTP_INTERNAL_SERVER_ERROR */
2315 * This comparison to expose error-notes could be modified to
2316 * use a configuration directive and export based on that
2317 * directive. For now "*" is used to designate an error-notes
2318 * that is totally safe for any user to see (ie lacks paths,
2319 * database passwords, etc.)
2321 if (((error_notes = apr_table_get(r->notes,
2322 "error-notes")) != NULL)
2323 && (h1 = apr_table_get(r->notes, "verbose-error-to")) != NULL
2324 && (strcmp(h1, "*") == 0)) {
2325 return(apr_pstrcat(p, error_notes, "<p />\n", NULL));
2328 return(apr_pstrcat(p,
2329 "<p>The server encountered an internal "
2331 "misconfiguration and was unable to complete\n"
2332 "your request.</p>\n"
2333 "<p>Please contact the server "
2334 "administrator,\n ",
2335 ap_escape_html(r->pool,
2336 r->server->server_admin),
2337 " and inform them of the time the "
2339 "and anything you might have done that "
2341 "caused the error.</p>\n"
2342 "<p>More information about this error "
2343 "may be available\n"
2344 "in the server error log.</p>\n",
2348 * It would be nice to give the user the information they need to
2349 * fix the problem directly since many users don't have access to
2350 * the error_log (think University sites) even though they can easily
2351 * get this error by misconfiguring an htaccess file. However, the
2352 * e error notes tend to include the real file pathname in this case,
2353 * which some people consider to be a breach of privacy. Until we
2354 * can figure out a way to remove the pathname, leave this commented.
2356 * if ((error_notes = apr_table_get(r->notes,
2357 * "error-notes")) != NULL) {
2358 * return(apr_pstrcat(p, error_notes, "<p />\n", NULL);
2367 /* We should have named this send_canned_response, since it is used for any
2368 * response that can be generated by the server from the request record.
2369 * This includes all 204 (no content), 3xx (redirect), 4xx (client error),
2370 * and 5xx (server error) messages that have not been redirected to another
2371 * handler via the ErrorDocument feature.
2373 AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error)
2375 int status = r->status;
2376 int idx = ap_index_of_response(status);
2377 char *custom_response;
2378 const char *location = apr_table_get(r->headers_out, "Location");
2380 /* At this point, we are starting the response over, so we have to reset
2385 /* and we need to get rid of any RESOURCE filters that might be lurking
2386 * around, thinking they are in the middle of the original request
2389 r->output_filters = r->proto_output_filters;
2391 ap_run_insert_error_filter(r);
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 = apr_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 ap_finalize_request_protocol(r);
2410 if (status == HTTP_NO_CONTENT) {
2411 ap_finalize_request_protocol(r);
2415 if (!r->assbackwards) {
2416 apr_table_t *tmp = r->headers_out;
2418 /* For all HTTP/1.x responses for which we generate the message,
2419 * we need to avoid inheriting the "normal status" header fields
2420 * that may have been set by the request handler before the
2421 * error or redirect, except for Location on external redirects.
2423 r->headers_out = r->err_headers_out;
2424 r->err_headers_out = tmp;
2425 apr_table_clear(r->err_headers_out);
2427 if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) {
2428 if ((location != NULL) && *location) {
2429 apr_table_setn(r->headers_out, "Location", location);
2432 location = ""; /* avoids coredump when printing, below */
2436 r->content_languages = NULL;
2437 r->content_encoding = NULL;
2440 if (apr_table_get(r->subprocess_env,
2441 "suppress-error-charset") != NULL) {
2442 core_request_config *request_conf =
2443 ap_get_module_config(r->request_config, &core_module);
2444 request_conf->suppress_charset = 1; /* avoid adding default
2447 ap_set_content_type(r, "text/html");
2450 ap_set_content_type(r, "text/html; charset=iso-8859-1");
2453 if ((status == HTTP_METHOD_NOT_ALLOWED)
2454 || (status == HTTP_NOT_IMPLEMENTED)) {
2455 apr_table_setn(r->headers_out, "Allow", make_allow(r));
2458 if (r->header_only) {
2459 ap_finalize_request_protocol(r);
2464 if ((custom_response = ap_response_code_string(r, idx))) {
2466 * We have a custom response output. This should only be
2467 * a text-string to write back. But if the ErrorDocument
2468 * was a local redirect and the requested resource failed
2469 * for any reason, the custom_response will still hold the
2470 * redirect URL. We don't really want to output this URL
2471 * as a text message, so first check the custom response
2472 * string to ensure that it is a text-string (using the
2473 * same test used in ap_die(), i.e. does it start with a ").
2475 * If it's not a text string, we've got a recursive error or
2476 * an external redirect. If it's a recursive error, ap_die passes
2477 * us the second error code so we can write both, and has already
2478 * backed up to the original error. If it's an external redirect,
2479 * it hasn't happened yet; we may never know if it fails.
2481 if (custom_response[0] == '\"') {
2482 ap_rputs(custom_response + 1, r);
2483 ap_finalize_request_protocol(r);
2488 const char *title = status_lines[idx];
2491 /* Accept a status_line set by a module, but only if it begins
2492 * with the 3 digit status code
2494 if (r->status_line != NULL
2495 && strlen(r->status_line) > 4 /* long enough */
2496 && apr_isdigit(r->status_line[0])
2497 && apr_isdigit(r->status_line[1])
2498 && apr_isdigit(r->status_line[2])
2499 && apr_isspace(r->status_line[3])
2500 && apr_isalnum(r->status_line[4])) {
2501 title = r->status_line;
2504 /* folks decided they didn't want the error code in the H1 text */
2507 /* can't count on a charset filter being in place here,
2508 * so do ebcdic->ascii translation explicitly (if needed)
2511 ap_rvputs_proto_in_ascii(r,
2513 "<html><head>\n<title>", title,
2514 "</title>\n</head><body>\n<h1>", h1, "</h1>\n",
2517 ap_rvputs_proto_in_ascii(r,
2518 get_canned_error_string(status, r, location),
2521 if (recursive_error) {
2522 ap_rvputs_proto_in_ascii(r, "<p>Additionally, a ",
2523 status_lines[ap_index_of_response(recursive_error)],
2524 "\nerror was encountered while trying to use an "
2525 "ErrorDocument to handle the request.</p>\n", NULL);
2527 ap_rvputs_proto_in_ascii(r, ap_psignature("<hr>\n", r), NULL);
2528 ap_rvputs_proto_in_ascii(r, "</body></html>\n", NULL);
2530 ap_finalize_request_protocol(r);
2534 * Create a new method list with the specified number of preallocated
2537 AP_DECLARE(ap_method_list_t *) ap_make_method_list(apr_pool_t *p, int nelts)
2539 ap_method_list_t *ml;
2541 ml = (ap_method_list_t *) apr_palloc(p, sizeof(ap_method_list_t));
2542 ml->method_mask = 0;
2543 ml->method_list = apr_array_make(p, nelts, sizeof(char *));
2548 * Make a copy of a method list (primarily for subrequests that may
2549 * subsequently change it; don't want them changing the parent's, too!).
2551 AP_DECLARE(void) ap_copy_method_list(ap_method_list_t *dest,
2552 ap_method_list_t *src)
2558 dest->method_mask = src->method_mask;
2559 imethods = (char **) src->method_list->elts;
2560 for (i = 0; i < src->method_list->nelts; ++i) {
2561 omethods = (char **) apr_array_push(dest->method_list);
2562 *omethods = apr_pstrdup(dest->method_list->pool, imethods[i]);
2567 * Invoke a callback routine for each method in the specified list.
2569 AP_DECLARE_NONSTD(void) ap_method_list_do(int (*comp) (void *urec,
2573 const ap_method_list_t *ml, ...)
2577 ap_method_list_vdo(comp, rec, ml, vp);
2581 AP_DECLARE(void) ap_method_list_vdo(int (*comp) (void *mrec,
2584 void *rec, const ap_method_list_t *ml,
2591 * Return true if the specified HTTP method is in the provided
2594 AP_DECLARE(int) ap_method_in_list(ap_method_list_t *l, const char *method)
2601 * If it's one of our known methods, use the shortcut and check the
2604 methnum = ap_method_number_of(method);
2605 if (methnum != M_INVALID) {
2606 return !!(l->method_mask & (AP_METHOD_BIT << methnum));
2609 * Otherwise, see if the method name is in the array or string names
2611 if ((l->method_list == NULL) || (l->method_list->nelts == 0)) {
2614 methods = (char **)l->method_list->elts;
2615 for (i = 0; i < l->method_list->nelts; ++i) {
2616 if (strcmp(method, methods[i]) == 0) {
2624 * Add the specified method to a method list (if it isn't already there).
2626 AP_DECLARE(void) ap_method_list_add(ap_method_list_t *l, const char *method)
2630 const char **xmethod;
2634 * If it's one of our known methods, use the shortcut and use the
2637 methnum = ap_method_number_of(method);
2638 l->method_mask |= (AP_METHOD_BIT << methnum);
2639 if (methnum != M_INVALID) {
2643 * Otherwise, see if the method name is in the array of string names.
2645 if (l->method_list->nelts != 0) {
2646 methods = (char **)l->method_list->elts;
2647 for (i = 0; i < l->method_list->nelts; ++i) {
2648 if (strcmp(method, methods[i]) == 0) {
2653 xmethod = (const char **) apr_array_push(l->method_list);
2658 * Remove the specified method from a method list.
2660 AP_DECLARE(void) ap_method_list_remove(ap_method_list_t *l,
2667 * If it's a known methods, either builtin or registered
2668 * by a module, use the bitmask.
2670 methnum = ap_method_number_of(method);
2671 l->method_mask |= ~(AP_METHOD_BIT << methnum);
2672 if (methnum != M_INVALID) {
2676 * Otherwise, see if the method name is in the array of string names.
2678 if (l->method_list->nelts != 0) {
2679 register int i, j, k;
2680 methods = (char **)l->method_list->elts;
2681 for (i = 0; i < l->method_list->nelts; ) {
2682 if (strcmp(method, methods[i]) == 0) {
2683 for (j = i, k = i + 1; k < l->method_list->nelts; ++j, ++k) {
2684 methods[j] = methods[k];
2686 --l->method_list->nelts;
2696 * Reset a method list to be completely empty.
2698 AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l)
2701 l->method_list->nelts = 0;
2704 /* Generate the human-readable hex representation of an unsigned long
2705 * (basically a faster version of 'sprintf("%lx")')
2707 #define HEX_DIGITS "0123456789abcdef"
2708 static char *etag_ulong_to_hex(char *next, unsigned long u)
2711 int shift = sizeof(unsigned long) * 8 - 4;
2713 unsigned long next_digit = ((u >> shift) & (unsigned long)0xf);
2715 *next++ = HEX_DIGITS[next_digit];
2718 else if (printing) {
2719 *next++ = HEX_DIGITS[next_digit];
2723 *next++ = HEX_DIGITS[u & (unsigned long)0xf];
2727 #define ETAG_WEAK "W/"
2728 #define CHARS_PER_UNSIGNED_LONG (sizeof(unsigned long) * 2)
2730 * Construct an entity tag (ETag) from resource information. If it's a real
2731 * file, build in some of the file characteristics. If the modification time
2732 * is newer than (request-time minus 1 second), mark the ETag as weak - it
2733 * could be modified again in as short an interval. We rationalize the
2734 * modification time we're given to keep it from being in the future.
2736 AP_DECLARE(char *) ap_make_etag(request_rec *r, int force_weak)
2739 apr_size_t weak_len;
2742 core_dir_config *cfg;
2743 etag_components_t etag_bits;
2744 etag_components_t bits_added;
2746 cfg = (core_dir_config *)ap_get_module_config(r->per_dir_config,
2748 etag_bits = (cfg->etag_bits & (~ cfg->etag_remove)) | cfg->etag_add;
2751 * If it's a file (or we wouldn't be here) and no ETags
2752 * should be set for files, return an empty string and
2753 * note it for the header-sender to ignore.
2755 if (etag_bits & ETAG_NONE) {
2756 apr_table_setn(r->notes, "no-etag", "omit");
2760 if (etag_bits == ETAG_UNSET) {
2761 etag_bits = ETAG_BACKWARD;
2764 * Make an ETag header out of various pieces of information. We use
2765 * the last-modified date and, if we have a real file, the
2766 * length and inode number - note that this doesn't have to match
2767 * the content-length (i.e. includes), it just has to be unique
2770 * If the request was made within a second of the last-modified date,
2771 * we send a weak tag instead of a strong one, since it could
2772 * be modified again later in the second, and the validation
2773 * would be incorrect.
2775 if ((r->request_time - r->mtime > (1 * APR_USEC_PER_SEC)) &&
2782 weak_len = sizeof(ETAG_WEAK);
2785 if (r->finfo.filetype != 0) {
2787 * ETag gets set to [W/]"inode-size-mtime", modulo any
2788 * FileETag keywords.
2790 etag = apr_palloc(r->pool, weak_len + sizeof("\"--\"") +
2791 3 * CHARS_PER_UNSIGNED_LONG + 1);
2800 if (etag_bits & ETAG_INODE) {
2801 next = etag_ulong_to_hex(next, (unsigned long)r->finfo.inode);
2802 bits_added |= ETAG_INODE;
2804 if (etag_bits & ETAG_SIZE) {
2805 if (bits_added != 0) {
2808 next = etag_ulong_to_hex(next, (unsigned long)r->finfo.size);
2809 bits_added |= ETAG_SIZE;
2811 if (etag_bits & ETAG_MTIME) {
2812 if (bits_added != 0) {
2815 next = etag_ulong_to_hex(next, (unsigned long)r->mtime);
2822 * Not a file document, so just use the mtime: [W/]"mtime"
2824 etag = apr_palloc(r->pool, weak_len + sizeof("\"\"") +
2825 CHARS_PER_UNSIGNED_LONG + 1);
2833 next = etag_ulong_to_hex(next, (unsigned long)r->mtime);
2841 AP_DECLARE(void) ap_set_etag(request_rec *r)
2844 char *variant_etag, *vlv;
2847 if (!r->vlist_validator) {
2848 etag = ap_make_etag(r, 0);
2850 /* If we get a blank etag back, don't set the header. */
2856 /* If we have a variant list validator (vlv) due to the
2857 * response being negotiated, then we create a structured
2858 * entity tag which merges the variant etag with the variant
2859 * list validator (vlv). This merging makes revalidation
2860 * somewhat safer, ensures that caches which can deal with
2861 * Vary will (eventually) be updated if the set of variants is
2862 * changed, and is also a protocol requirement for transparent
2863 * content negotiation.
2866 /* if the variant list validator is weak, we make the whole
2867 * structured etag weak. If we would not, then clients could
2868 * have problems merging range responses if we have different
2869 * variants with the same non-globally-unique strong etag.
2872 vlv = r->vlist_validator;
2873 vlv_weak = (vlv[0] == 'W');
2875 variant_etag = ap_make_etag(r, vlv_weak);
2877 /* If we get a blank etag back, don't append vlv and stop now. */
2878 if (!variant_etag[0]) {
2882 /* merge variant_etag and vlv into a structured etag */
2883 variant_etag[strlen(variant_etag) - 1] = '\0';
2890 etag = apr_pstrcat(r->pool, variant_etag, ";", vlv, NULL);
2893 apr_table_setn(r->headers_out, "ETag", etag);
2896 static int parse_byterange(char *range, apr_off_t clength,
2897 apr_off_t *start, apr_off_t *end)
2899 char *dash = strchr(range, '-');
2905 if ((dash == range)) {
2906 /* In the form "-5" */
2907 *start = clength - apr_atoi64(dash + 1);
2913 *start = apr_atoi64(range);
2915 *end = apr_atoi64(dash);
2926 if (*end >= clength) {
2930 if (*start > *end) {
2934 return (*start > 0 || *end < clength);
2937 static int ap_set_byterange(request_rec *r);
2939 typedef struct byterange_ctx {
2940 apr_bucket_brigade *bb;
2947 * Here we try to be compatible with clients that want multipart/x-byteranges
2948 * instead of multipart/byteranges (also see above), as per HTTP/1.1. We
2949 * look for the Request-Range header (e.g. Netscape 2 and 3) as an indication
2950 * that the browser supports an older protocol. We also check User-Agent
2951 * for Microsoft Internet Explorer 3, which needs this as well.
2953 static int use_range_x(request_rec *r)
2956 return (apr_table_get(r->headers_in, "Request-Range")
2957 || ((ua = apr_table_get(r->headers_in, "User-Agent"))
2958 && ap_strstr_c(ua, "MSIE 3")));
2961 #define BYTERANGE_FMT "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT "/%" APR_OFF_T_FMT
2962 #define PARTITION_ERR_FMT "apr_brigade_partition() failed " \
2963 "[%" APR_OFF_T_FMT ",%" APR_OFF_T_FMT "]"
2965 AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f,
2966 apr_bucket_brigade *bb)
2968 #define MIN_LENGTH(len1, len2) ((len1 > len2) ? len2 : len1)
2969 request_rec *r = f->r;
2970 conn_rec *c = r->connection;
2973 apr_bucket_brigade *bsend;
2974 apr_off_t range_start;
2975 apr_off_t range_end;
2977 apr_off_t clength = 0;
2981 /* Iterate through the brigade until reaching EOS or a bucket with
2982 * unknown length. */
2983 for (e = APR_BRIGADE_FIRST(bb);
2984 (e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e)
2985 && e->length != (apr_size_t)-1);
2986 e = APR_BUCKET_NEXT(e)) {
2987 clength += e->length;
2990 /* Don't attempt to do byte range work if this brigade doesn't
2991 * contain an EOS, or if any of the buckets has an unknown length;
2992 * this avoids the cases where it is expensive to perform
2993 * byteranging (i.e. may require arbitrary amounts of memory). */
2994 if (!APR_BUCKET_IS_EOS(e) || clength <= 0) {
2995 ap_remove_output_filter(f);
2996 return ap_pass_brigade(f->next, bb);
3000 int num_ranges = ap_set_byterange(r);
3002 /* We have nothing to do, get out of the way. */
3003 if (num_ranges == 0) {
3004 ap_remove_output_filter(f);
3005 return ap_pass_brigade(f->next, bb);
3008 ctx = apr_pcalloc(r->pool, sizeof(*ctx));
3009 ctx->num_ranges = num_ranges;
3010 /* create a brigade in case we never call ap_save_brigade() */
3011 ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc);
3013 if (ctx->num_ranges > 1) {
3014 /* Is ap_make_content_type required here? */
3015 const char *orig_ct = ap_make_content_type(r, r->content_type);
3016 /* need APR_TIME_T_FMT_HEX */
3017 ctx->boundary = apr_psprintf(r->pool, "%qx%lx",
3018 r->request_time, (long) getpid());
3020 ap_set_content_type(r, apr_pstrcat(r->pool, "multipart",
3021 use_range_x(r) ? "/x-" : "/",
3022 "byteranges; boundary=",
3023 ctx->boundary, NULL));
3025 ctx->bound_head = apr_pstrcat(r->pool,
3026 CRLF "--", ctx->boundary,
3027 CRLF "Content-type: ",
3029 CRLF "Content-range: bytes ",
3031 ap_xlate_proto_to_ascii(ctx->bound_head, strlen(ctx->bound_head));
3035 /* this brigade holds what we will be sending */
3036 bsend = apr_brigade_create(r->pool, c->bucket_alloc);
3038 while ((current = ap_getword(r->pool, &r->range, ','))
3039 && (rv = parse_byterange(current, clength, &range_start,
3048 /* these calls to apr_brigade_partition() should theoretically
3049 * never fail because of the above call to apr_brigade_length(),
3050 * but what the heck, we'll check for an error anyway */
3051 if ((rv = apr_brigade_partition(bb, range_start, &ec)) != APR_SUCCESS) {
3052 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
3053 PARTITION_ERR_FMT, range_start, clength);
3056 if ((rv = apr_brigade_partition(bb, range_end+1, &e2)) != APR_SUCCESS) {
3057 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
3058 PARTITION_ERR_FMT, range_end+1, clength);
3064 /* For single range requests, we must produce Content-Range header.
3065 * Otherwise, we need to produce the multipart boundaries.
3067 if (ctx->num_ranges == 1) {
3068 apr_table_setn(r->headers_out, "Content-Range",
3069 apr_psprintf(r->pool, "bytes " BYTERANGE_FMT,
3070 range_start, range_end, clength));
3075 e = apr_bucket_pool_create(ctx->bound_head, strlen(ctx->bound_head),
3076 r->pool, c->bucket_alloc);
3077 APR_BRIGADE_INSERT_TAIL(bsend, e);
3079 ts = apr_psprintf(r->pool, BYTERANGE_FMT CRLF CRLF,
3080 range_start, range_end, clength);
3081 ap_xlate_proto_to_ascii(ts, strlen(ts));
3082 e = apr_bucket_pool_create(ts, strlen(ts), r->pool,
3084 APR_BRIGADE_INSERT_TAIL(bsend, e);
3092 if (apr_bucket_copy(ec, &foo) != APR_SUCCESS) {
3093 /* this shouldn't ever happen due to the call to
3094 * apr_brigade_length() above which normalizes
3095 * indeterminate-length buckets. just to be sure,
3096 * though, this takes care of uncopyable buckets that
3097 * do somehow manage to slip through.
3099 /* XXX: check for failure? */
3100 apr_bucket_read(ec, &str, &len, APR_BLOCK_READ);
3101 apr_bucket_copy(ec, &foo);
3103 APR_BRIGADE_INSERT_TAIL(bsend, foo);
3104 ec = APR_BUCKET_NEXT(ec);
3109 ap_remove_output_filter(f);
3110 r->status = HTTP_OK;
3111 /* bsend is assumed to be empty if we get here. */
3112 e = ap_bucket_error_create(HTTP_RANGE_NOT_SATISFIABLE, NULL,
3113 r->pool, c->bucket_alloc);
3114 APR_BRIGADE_INSERT_TAIL(bsend, e);
3115 e = apr_bucket_eos_create(c->bucket_alloc);
3116 APR_BRIGADE_INSERT_TAIL(bsend, e);
3117 return ap_pass_brigade(f->next, bsend);
3120 if (ctx->num_ranges > 1) {
3123 /* add the final boundary */
3124 end = apr_pstrcat(r->pool, CRLF "--", ctx->boundary, "--" CRLF, NULL);
3125 ap_xlate_proto_to_ascii(end, strlen(end));
3126 e = apr_bucket_pool_create(end, strlen(end), r->pool, c->bucket_alloc);
3127 APR_BRIGADE_INSERT_TAIL(bsend, e);
3130 e = apr_bucket_eos_create(c->bucket_alloc);
3131 APR_BRIGADE_INSERT_TAIL(bsend, e);
3133 /* we're done with the original content - all of our data is in bsend. */
3134 apr_brigade_destroy(bb);
3136 /* send our multipart output */
3137 return ap_pass_brigade(f->next, bsend);
3140 static int ap_set_byterange(request_rec *r)
3143 const char *if_range;
3148 if (r->assbackwards) {
3152 /* Check for Range request-header (HTTP/1.1) or Request-Range for
3153 * backwards-compatibility with second-draft Luotonen/Franks
3154 * byte-ranges (e.g. Netscape Navigator 2-3).
3156 * We support this form, with Request-Range, and (farther down) we
3157 * send multipart/x-byteranges instead of multipart/byteranges for
3158 * Request-Range based requests to work around a bug in Netscape
3159 * Navigator 2-3 and MSIE 3.
3162 if (!(range = apr_table_get(r->headers_in, "Range"))) {
3163 range = apr_table_get(r->headers_in, "Request-Range");
3166 if (!range || strncasecmp(range, "bytes=", 6) || r->status != HTTP_OK) {
3170 /* is content already a single range? */
3171 if (apr_table_get(r->headers_out, "Content-Range")) {
3175 /* is content already a multiple range? */
3176 if ((ct = apr_table_get(r->headers_out, "Content-Type"))
3177 && (!strncasecmp(ct, "multipart/byteranges", 20)
3178 || !strncasecmp(ct, "multipart/x-byteranges", 22))) {
3182 /* Check the If-Range header for Etag or Date.
3183 * Note that this check will return false (as required) if either
3184 * of the two etags are weak.
3186 if ((if_range = apr_table_get(r->headers_in, "If-Range"))) {
3187 if (if_range[0] == '"') {
3188 if (!(match = apr_table_get(r->headers_out, "Etag"))
3189 || (strcmp(if_range, match) != 0)) {
3193 else if (!(match = apr_table_get(r->headers_out, "Last-Modified"))
3194 || (strcmp(if_range, match) != 0)) {
3199 if (!ap_strchr_c(range, ',')) {
3200 /* a single range */
3204 /* a multiple range */
3208 r->status = HTTP_PARTIAL_CONTENT;
3209 r->range = range + 6;