upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / modules / http / http_protocol.c
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /*
18  * http_protocol.c --- routines which directly communicate with the client.
19  *
20  * Code originally by Rob McCool; much redone by Robert S. Thau
21  * and the Apache Software Foundation.
22  */
23
24 #include "apr.h"
25 #include "apr_strings.h"
26 #include "apr_buckets.h"
27 #include "apr_lib.h"
28 #include "apr_signal.h"
29
30 #define APR_WANT_STDIO          /* for sscanf */
31 #define APR_WANT_STRFUNC
32 #define APR_WANT_MEMFUNC
33 #include "apr_want.h"
34
35 #define CORE_PRIVATE
36 #include "util_filter.h"
37 #include "ap_config.h"
38 #include "httpd.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
46                                  * support code... */
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"
51
52 #include "mod_core.h"
53
54 #if APR_HAVE_STDARG_H
55 #include <stdarg.h>
56 #endif
57 #if APR_HAVE_UNISTD_H
58 #include <unistd.h>
59 #endif
60
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.
65  */
66
67 #ifdef UTS21
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
71  */
72 static const char * status_lines[RESPONSE_CODES] =
73 #else
74 static const char * const status_lines[RESPONSE_CODES] =
75 #endif
76 {
77     "100 Continue",
78     "101 Switching Protocols",
79     "102 Processing",
80 #define LEVEL_200  3
81     "200 OK",
82     "201 Created",
83     "202 Accepted",
84     "203 Non-Authoritative Information",
85     "204 No Content",
86     "205 Reset Content",
87     "206 Partial Content",
88     "207 Multi-Status",
89 #define LEVEL_300 11
90     "300 Multiple Choices",
91     "301 Moved Permanently",
92     "302 Found",
93     "303 See Other",
94     "304 Not Modified",
95     "305 Use Proxy",
96     "306 unused",
97     "307 Temporary Redirect",
98 #define LEVEL_400 19
99     "400 Bad Request",
100     "401 Authorization Required",
101     "402 Payment Required",
102     "403 Forbidden",
103     "404 Not Found",
104     "405 Method Not Allowed",
105     "406 Not Acceptable",
106     "407 Proxy Authentication Required",
107     "408 Request Time-out",
108     "409 Conflict",
109     "410 Gone",
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",
117     "418 unused",
118     "419 unused",
119     "420 unused",
120     "421 unused",
121     "422 Unprocessable Entity",
122     "423 Locked",
123     "424 Failed Dependency",
124     /* This is a hack, but it is required for ap_index_of_response
125      * to work with 426.
126      */
127     "425 No code",
128     "426 Upgrade Required",
129 #define LEVEL_500 46
130     "500 Internal Server Error",
131     "501 Method Not Implemented",
132     "502 Bad Gateway",
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",
138     "508 unused",
139     "509 unused",
140     "510 Not Extended"
141 };
142
143 APR_HOOK_STRUCT(
144     APR_HOOK_LINK(insert_error_filter)
145 )
146
147 AP_IMPLEMENT_HOOK_VOID(insert_error_filter, (request_rec *r), (r))
148
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.
151  */
152 #define METHOD_NUMBER_FIRST (M_INVALID + 1)
153
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.
157  */
158 #define METHOD_NUMBER_LAST  62
159
160
161 AP_DECLARE(int) ap_set_keepalive(request_rec *r)
162 {
163     int ka_sent = 0;
164     int wimpy = ap_find_token(r->pool,
165                               apr_table_get(r->headers_out, "Connection"),
166                               "close");
167     const char *conn = apr_table_get(r->headers_in, "Connection");
168
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,
173      *
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.
191      *
192      * Note that the condition evaluation order is extremely important.
193      */
194     if ((r->connection->keepalive != AP_CONN_CLOSE)
195         && ((r->status == HTTP_NOT_MODIFIED)
196             || (r->status == HTTP_NO_CONTENT)
197             || r->header_only
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"),
202                                   "chunked")
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)
210         && !wimpy
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;
217
218         r->connection->keepalive = AP_CONN_KEEPALIVE;
219         r->connection->keepalives++;
220
221         /* If they sent a Keep-Alive token, send one back */
222         if (ka_sent) {
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),
227                             left));
228             }
229             else {
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)));
233             }
234             apr_table_mergen(r->headers_out, "Connection", "Keep-Alive");
235         }
236
237         return 1;
238     }
239
240     /* Otherwise, we need to indicate that we will be closing this
241      * connection immediately after the current response.
242      *
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.
247      */
248     if (!wimpy) {
249         apr_table_mergen(r->headers_out, "Connection", "close");
250     }
251
252     r->connection->keepalive = AP_CONN_CLOSE;
253
254     return 0;
255 }
256
257 AP_DECLARE(int) ap_meets_conditions(request_rec *r)
258 {
259     const char *etag;
260     const char *if_match, *if_modified_since, *if_unmodified, *if_nonematch;
261     apr_time_t tmp_time;
262     apr_int64_t mtime;
263
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.
267      *
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
272      * complicated.
273      */
274
275     if (!ap_is_HTTP_SUCCESS(r->status) || r->no_local_copy) {
276         return OK;
277     }
278
279     etag = apr_table_get(r->headers_out, "ETag");
280
281     /* All of our comparisons must be in seconds, because that's the
282      * highest time resolution the HTTP specification allows.
283      */
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);
287
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).
292      */
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;
298         }
299     }
300     else {
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).
305          */
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);
309
310             if ((ius != APR_DATE_BAD) && (mtime > apr_time_sec(ius))) {
311                 return HTTP_PRECONDITION_FAILED;
312             }
313         }
314     }
315
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.
319      *
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).
324      *
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.
327      */
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;
333             }
334             if (etag != NULL) {
335                 if (apr_table_get(r->headers_in, "Range")) {
336                     if (etag[0] != 'W'
337                         && ap_find_list_item(r->pool, if_nonematch, etag)) {
338                         return HTTP_NOT_MODIFIED;
339                     }
340                 }
341                 else if (ap_strstr_c(if_nonematch, etag)) {
342                     return HTTP_NOT_MODIFIED;
343                 }
344             }
345         }
346         else if (if_nonematch[0] == '*'
347                  || (etag != NULL
348                      && ap_find_list_item(r->pool, if_nonematch, etag))) {
349             return HTTP_PRECONDITION_FAILED;
350         }
351     }
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.
358      */
359     else if ((r->method_number == M_GET)
360              && ((if_modified_since =
361                   apr_table_get(r->headers_in,
362                                 "If-Modified-Since")) != NULL)) {
363         apr_time_t ims_time;
364         apr_int64_t ims, reqtime;
365
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);
369
370         if ((ims >= mtime) && (ims <= reqtime)) {
371             return HTTP_NOT_MODIFIED;
372         }
373     }
374     return OK;
375 }
376
377 /**
378  * Singleton registry of additional methods. This maps new method names
379  * such as "MYGET" to methnums, which are int offsets into bitmasks.
380  *
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.
384  */
385 static apr_hash_t *methods_registry = NULL;
386 static int cur_method_number = METHOD_NUMBER_FIRST;
387
388 /* internal function to register one method/number pair */
389 static void register_one_method(apr_pool_t *p, const char *methname,
390                                 int methnum)
391 {
392     int *pnum = apr_palloc(p, sizeof(*pnum));
393
394     *pnum = methnum;
395     apr_hash_set(methods_registry, methname, APR_HASH_KEY_STRING, pnum);
396 }
397
398 /* This internal function is used to clear the method registry
399  * and reset the cur_method_number counter.
400  */
401 static apr_status_t ap_method_registry_destroy(void *notused)
402 {
403     methods_registry = NULL;
404     cur_method_number = METHOD_NUMBER_FIRST;
405     return APR_SUCCESS;
406 }
407
408 AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p)
409 {
410     methods_registry = apr_hash_make(p);
411     apr_pool_cleanup_register(p, NULL,
412                               ap_method_registry_destroy,
413                               apr_pool_cleanup_null);
414
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);
443 }
444
445 AP_DECLARE(int) ap_method_register(apr_pool_t *p, const char *methname)
446 {
447     int *methnum;
448
449     if (methods_registry == NULL) {
450         ap_method_registry_init(p);
451     }
452
453     if (methname == NULL) {
454         return M_INVALID;
455     }
456     
457     /* Check if the method was previously registered.  If it was
458      * return the associated method number.
459      */
460     methnum = (int *)apr_hash_get(methods_registry, methname,
461                                   APR_HASH_KEY_STRING);
462     if (methnum != NULL)
463         return *methnum;
464         
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.
468          */
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);
473         return M_INVALID;
474     }
475
476     register_one_method(p, methname, cur_method_number);
477     return cur_method_number++;
478 }
479
480 #define UNKNOWN_METHOD (-1)
481
482 static int lookup_builtin_method(const char *method, apr_size_t len)
483 {
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. */
491
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). */
495
496     switch (len)
497     {
498     case 3:
499         switch (method[0])
500         {
501         case 'P':
502             return (method[1] == 'U'
503                     && method[2] == 'T'
504                     ? M_PUT : UNKNOWN_METHOD);
505         case 'G':
506             return (method[1] == 'E'
507                     && method[2] == 'T'
508                     ? M_GET : UNKNOWN_METHOD);
509         default:
510             return UNKNOWN_METHOD;
511         }
512
513     case 4:
514         switch (method[0])
515         {
516         case 'H':
517             return (method[1] == 'E'
518                     && method[2] == 'A'
519                     && method[3] == 'D'
520                     ? M_GET : UNKNOWN_METHOD);
521         case 'P':
522             return (method[1] == 'O'
523                     && method[2] == 'S'
524                     && method[3] == 'T'
525                     ? M_POST : UNKNOWN_METHOD);
526         case 'M':
527             return (method[1] == 'O'
528                     && method[2] == 'V'
529                     && method[3] == 'E'
530                     ? M_MOVE : UNKNOWN_METHOD);
531         case 'L':
532             return (method[1] == 'O'
533                     && method[2] == 'C'
534                     && method[3] == 'K'
535                     ? M_LOCK : UNKNOWN_METHOD);
536         case 'C':
537             return (method[1] == 'O'
538                     && method[2] == 'P'
539                     && method[3] == 'Y'
540                     ? M_COPY : UNKNOWN_METHOD);
541         default:
542             return UNKNOWN_METHOD;
543         }
544
545     case 5:
546         switch (method[2])
547         {
548         case 'T':
549             return (memcmp(method, "PATCH", 5) == 0
550                     ? M_PATCH : UNKNOWN_METHOD);
551         case 'R':
552             return (memcmp(method, "MERGE", 5) == 0
553                     ? M_MERGE : UNKNOWN_METHOD);
554         case 'C':
555             return (memcmp(method, "MKCOL", 5) == 0
556                     ? M_MKCOL : UNKNOWN_METHOD);
557         case 'B':
558             return (memcmp(method, "LABEL", 5) == 0
559                     ? M_LABEL : UNKNOWN_METHOD);
560         case 'A':
561             return (memcmp(method, "TRACE", 5) == 0
562                     ? M_TRACE : UNKNOWN_METHOD);
563         default:
564             return UNKNOWN_METHOD;
565         }
566
567     case 6:
568         switch (method[0])
569         {
570         case 'U':
571             switch (method[5])
572             {
573             case 'K':
574                 return (memcmp(method, "UNLOCK", 6) == 0
575                         ? M_UNLOCK : UNKNOWN_METHOD);
576             case 'E':
577                 return (memcmp(method, "UPDATE", 6) == 0
578                         ? M_UPDATE : UNKNOWN_METHOD);
579             default:
580                 return UNKNOWN_METHOD;
581             }
582         case 'R':
583             return (memcmp(method, "REPORT", 6) == 0
584                     ? M_REPORT : UNKNOWN_METHOD);
585         case 'D':
586             return (memcmp(method, "DELETE", 6) == 0
587                     ? M_DELETE : UNKNOWN_METHOD);
588         default:
589             return UNKNOWN_METHOD;
590         }
591
592     case 7:
593         switch (method[1])
594         {
595         case 'P':
596             return (memcmp(method, "OPTIONS", 7) == 0
597                     ? M_OPTIONS : UNKNOWN_METHOD);
598         case 'O':
599             return (memcmp(method, "CONNECT", 7) == 0
600                     ? M_CONNECT : UNKNOWN_METHOD);
601         case 'H':
602             return (memcmp(method, "CHECKIN", 7) == 0
603                     ? M_CHECKIN : UNKNOWN_METHOD);
604         default:
605             return UNKNOWN_METHOD;
606         }
607
608     case 8:
609         switch (method[0])
610         {
611         case 'P':
612             return (memcmp(method, "PROPFIND", 8) == 0
613                     ? M_PROPFIND : UNKNOWN_METHOD);
614         case 'C':
615             return (memcmp(method, "CHECKOUT", 8) == 0
616                     ? M_CHECKOUT : UNKNOWN_METHOD);
617         default:
618             return UNKNOWN_METHOD;
619         }
620
621     case 9:
622         return (memcmp(method, "PROPPATCH", 9) == 0
623                 ? M_PROPPATCH : UNKNOWN_METHOD);
624
625     case 10:
626         switch (method[0])
627         {
628         case 'U':
629             return (memcmp(method, "UNCHECKOUT", 10) == 0
630                     ? M_UNCHECKOUT : UNKNOWN_METHOD);
631         case 'M':
632             return (memcmp(method, "MKACTIVITY", 10) == 0
633                     ? M_MKACTIVITY : UNKNOWN_METHOD);
634         default:
635             return UNKNOWN_METHOD;
636         }
637
638     case 11:
639         return (memcmp(method, "MKWORKSPACE", 11) == 0
640                 ? M_MKWORKSPACE : UNKNOWN_METHOD);
641
642     case 15:
643         return (memcmp(method, "VERSION-CONTROL", 15) == 0
644                 ? M_VERSION_CONTROL : UNKNOWN_METHOD);
645
646     case 16:
647         return (memcmp(method, "BASELINE-CONTROL", 16) == 0
648                 ? M_BASELINE_CONTROL : UNKNOWN_METHOD);
649
650     default:
651         return UNKNOWN_METHOD;
652     }
653
654     /* NOTREACHED */
655 }
656
657 /* Get the method number associated with the given string, assumed to
658  * contain an HTTP method.  Returns M_INVALID if not recognized.
659  *
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.
663  */
664 AP_DECLARE(int) ap_method_number_of(const char *method)
665 {
666     int len = strlen(method);
667     int which = lookup_builtin_method(method, len);
668
669     if (which != UNKNOWN_METHOD)
670         return which;
671
672     /* check if the method has been dynamically registered */
673     if (methods_registry != NULL) {
674         int *methnum = apr_hash_get(methods_registry, method, len);
675
676         if (methnum != NULL) {
677             return *methnum;
678         }
679     }
680
681     return M_INVALID;
682 }
683
684 /*
685  * Turn a known method number into a name.
686  */
687 AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum)
688 {
689     apr_hash_index_t *hi = apr_hash_first(p, methods_registry);
690
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)) {
694         const void *key;
695         void *val;
696
697         apr_hash_this(hi, &key, NULL, &val);
698         if (*(int *)val == methnum)
699             return key;
700     }
701
702     /* it wasn't found in the hash */
703     return NULL;
704 }
705
706 static long get_chunk_size(char *);
707
708 typedef struct http_filter_ctx {
709     apr_off_t remaining;
710     apr_off_t limit;
711     apr_off_t limit_used;
712     enum {
713         BODY_NONE,
714         BODY_LENGTH,
715         BODY_CHUNK
716     } state;
717     int eos_sent;
718 } http_ctx_t;
719
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. 
724  */
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,
727                             apr_off_t readbytes)
728 {
729     apr_bucket *e;
730     http_ctx_t *ctx = f->ctx;
731     apr_status_t rv;
732     apr_off_t totalread;
733
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);
737     }
738
739     if (!ctx) {
740         const char *tenc, *lenp;
741         f->ctx = ctx = apr_palloc(f->r->pool, sizeof(*ctx));
742         ctx->state = BODY_NONE;
743         ctx->remaining = 0;
744         ctx->limit_used = 0;
745         ctx->eos_sent = 0;
746
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?
751          */
752         if (!f->r->proxyreq) {
753             ctx->limit = ap_get_limit_req_body(f->r);
754         }
755         else {
756             ctx->limit = 0;
757         }
758
759         tenc = apr_table_get(f->r->headers_in, "Transfer-Encoding");
760         lenp = apr_table_get(f->r->headers_in, "Content-Length");
761
762         if (tenc) {
763             if (!strcasecmp(tenc, "chunked")) {
764                 ctx->state = BODY_CHUNK;
765             }
766         }
767         else if (lenp) {
768             int conversion_error = 0;
769             char *endstr;
770
771             ctx->state = BODY_LENGTH;
772             errno = 0;
773             ctx->remaining = strtol(lenp, &endstr, 10); /* we depend on ANSI */
774
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; 
782             }
783
784             if (conversion_error) {
785                 apr_bucket_brigade *bb;
786
787                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
788                               "Invalid Content-Length");
789
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);
796                 ctx->eos_sent = 1;
797                 return ap_pass_brigade(f->r->output_filters, bb);
798             }
799             
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. 
802              */ 
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);
815                 ctx->eos_sent = 1;
816                 return ap_pass_brigade(f->r->output_filters, bb);
817             }
818         }
819
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.)
823          *
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.
827          *
828          * Note that since the proxy uses this filter to handle the
829          * proxied *response*, proxy responses MUST be exempt.
830          */
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);
834             ctx->eos_sent = 1;
835             return APR_SUCCESS;
836         }
837
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)) {
843             char *tmp;
844             apr_bucket_brigade *bb;
845
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,
850                                        f->c->bucket_alloc);
851             APR_BRIGADE_INSERT_HEAD(bb, e);
852             e = apr_bucket_flush_create(f->c->bucket_alloc);
853             APR_BRIGADE_INSERT_TAIL(bb, e);
854
855             ap_pass_brigade(f->c->output_filters, bb);
856         }
857
858         /* We can't read the chunk until after sending 100 if required. */
859         if (ctx->state == BODY_CHUNK) {
860             char line[30];
861             apr_bucket_brigade *bb;
862             apr_size_t len = 30;
863
864             bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
865
866             rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
867                                 APR_BLOCK_READ, 0);
868
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);
873                 }
874             }
875             apr_brigade_cleanup(bb);
876
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,
882                                            f->r->pool,
883                                            f->c->bucket_alloc);
884                 APR_BRIGADE_INSERT_TAIL(bb, e);
885                 e = apr_bucket_eos_create(f->c->bucket_alloc);
886                 APR_BRIGADE_INSERT_TAIL(bb, e);
887                 ctx->eos_sent = 1;
888                 return ap_pass_brigade(f->r->output_filters, bb);
889             }
890
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);
897                 ctx->eos_sent = 1;
898                 return APR_SUCCESS;
899             }
900         } 
901     }
902
903     if (ctx->eos_sent) {
904         e = apr_bucket_eos_create(f->c->bucket_alloc);
905         APR_BRIGADE_INSERT_TAIL(b, e);
906         return APR_SUCCESS;
907     }
908         
909     if (!ctx->remaining) {
910         switch (ctx->state) {
911         case BODY_NONE:
912             break;
913         case BODY_LENGTH:
914             e = apr_bucket_eos_create(f->c->bucket_alloc);
915             APR_BRIGADE_INSERT_TAIL(b, e);
916             ctx->eos_sent = 1;
917             return APR_SUCCESS;
918         case BODY_CHUNK:
919             {
920                 char line[30];
921                 apr_bucket_brigade *bb;
922                 apr_size_t len = 30;
923
924                 bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
925
926                 /* We need to read the CRLF after the chunk.  */
927                 rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
928                                     APR_BLOCK_READ, 0);
929                 apr_brigade_cleanup(bb);
930
931                 if (rv == APR_SUCCESS) {
932                     /* Read the real chunk line. */
933                     rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
934                                         APR_BLOCK_READ, 0);
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);
939                         }
940                     }
941                     apr_brigade_cleanup(bb);
942                 }
943
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,
949                                                NULL, f->r->pool,
950                                                f->c->bucket_alloc);
951                     APR_BRIGADE_INSERT_TAIL(bb, e);
952                     e = apr_bucket_eos_create(f->c->bucket_alloc);
953                     APR_BRIGADE_INSERT_TAIL(bb, e);
954                     ctx->eos_sent = 1;
955                     return ap_pass_brigade(f->r->output_filters, bb);
956                 }
957
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);
964                     ctx->eos_sent = 1;
965                     return APR_SUCCESS;
966                 }
967             }
968             break;
969         }
970     }
971
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;
976         }
977         AP_DEBUG_ASSERT(readbytes > 0);
978     }
979
980     rv = ap_get_brigade(f->next, b, mode, block, readbytes);
981
982     if (rv != APR_SUCCESS) {
983         return rv;
984     }
985
986     /* How many bytes did we just read? */
987     apr_brigade_length(b, 0, &totalread);
988
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);
992
993     if (ctx->state != BODY_NONE) {
994         ctx->remaining -= totalread;
995     }
996
997     /* If we have no more bytes remaining on a C-L request, 
998      * save the callter a roundtrip to discover EOS.
999      */
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);
1003     }
1004
1005     /* We have a limit in effect. */
1006     if (ctx->limit) {
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,
1019                                        f->r->pool,
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);
1024             ctx->eos_sent = 1;
1025             return ap_pass_brigade(f->r->output_filters, bb);
1026         }
1027     }
1028
1029     return APR_SUCCESS;
1030 }
1031
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];
1037  */
1038 AP_DECLARE(int) ap_index_of_response(int status)
1039 {
1040     static int shortcut[6] = {0, LEVEL_200, LEVEL_300, LEVEL_400,
1041     LEVEL_500, RESPONSE_CODES};
1042     int i, pos;
1043
1044     if (status < 100) {               /* Below 100 is illegal for HTTP status */
1045         return LEVEL_500;
1046     }
1047
1048     for (i = 0; i < 5; i++) {
1049         status -= 100;
1050         if (status < 100) {
1051             pos = (status + shortcut[i]);
1052             if (pos < shortcut[i + 1]) {
1053                 return pos;
1054             }
1055             else {
1056                 return LEVEL_500;            /* status unknown (falls in gap) */
1057             }
1058         }
1059     }
1060     return LEVEL_500;                         /* 600 or above is also illegal */
1061 }
1062
1063 AP_DECLARE(const char *) ap_get_status_line(int status)
1064 {
1065     return status_lines[ap_index_of_response(status)];
1066 }
1067
1068 typedef struct header_struct {
1069     apr_pool_t *pool;
1070     apr_bucket_brigade *bb;
1071 } header_struct;
1072
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.
1077  */
1078 static int form_header_field(header_struct *h,
1079                              const char *fieldname, const char *fieldval)
1080 {
1081 #if APR_CHARSET_EBCDIC
1082     char *headfield;
1083     apr_size_t len;
1084     apr_size_t name_len;
1085     apr_size_t val_len;
1086     char *next;
1087
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;
1094     *next++ = ':';
1095     *next++ = ' ';
1096     memcpy(next, fieldval, val_len);
1097     next += val_len;
1098     *next++ = CR;
1099     *next++ = LF;
1100     *next = 0;
1101     ap_xlate_proto_to_ascii(headfield, len);
1102     apr_brigade_write(h->bb, NULL, NULL, headfield, len);
1103 #else
1104     struct iovec vec[4];
1105     struct iovec *v = vec;
1106     v->iov_base = (void *)fieldname;
1107     v->iov_len = strlen(fieldname);
1108     v++;
1109     v->iov_base = ": ";
1110     v->iov_len = sizeof(": ") - 1;
1111     v++;
1112     v->iov_base = (void *)fieldval;
1113     v->iov_len = strlen(fieldval);
1114     v++;
1115     v->iov_base = CRLF;
1116     v->iov_len = sizeof(CRLF) - 1;
1117     apr_brigade_writev(h->bb, NULL, NULL, vec, 4);
1118 #endif /* !APR_CHARSET_EBCDIC */
1119     return 1;
1120 }
1121
1122 /* Send a request's HTTP response headers to the client.
1123  */
1124 static apr_status_t send_all_header_fields(header_struct *h,
1125                                            const request_rec *r)
1126 {
1127     const apr_array_header_t *elts;
1128     const apr_table_entry_t *t_elt;
1129     const apr_table_entry_t *t_end;
1130     struct iovec *vec;
1131     struct iovec *vec_next;
1132
1133     elts = apr_table_elts(r->headers_out);
1134     if (elts->nelts == 0) {
1135         return APR_SUCCESS;
1136     }
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));
1141     vec_next = vec;
1142
1143     /* For each field, generate
1144      *    name ": " value CRLF
1145      */
1146     do {
1147         vec_next->iov_base = (void*)(t_elt->key);
1148         vec_next->iov_len = strlen(t_elt->key);
1149         vec_next++;
1150         vec_next->iov_base = ": ";
1151         vec_next->iov_len = sizeof(": ") - 1;
1152         vec_next++;
1153         vec_next->iov_base = (void*)(t_elt->val);
1154         vec_next->iov_len = strlen(t_elt->val);
1155         vec_next++;
1156         vec_next->iov_base = CRLF;
1157         vec_next->iov_len = sizeof(CRLF) - 1;
1158         vec_next++;
1159         t_elt++;
1160     } while (t_elt < t_end);
1161
1162 #if APR_CHARSET_EBCDIC
1163     {
1164         apr_size_t len;
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);
1168     }
1169 #else
1170     return apr_brigade_writev(h->bb, NULL, NULL, vec, vec_next - vec);
1171 #endif
1172 }
1173
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
1176  * handler.
1177  * Zap r->status_line if bad.
1178  */
1179 static void validate_status_line(request_rec *r)
1180 {
1181     char *end;
1182
1183     if (r->status_line
1184         && (strlen(r->status_line) <= 4
1185             || apr_strtoi64(r->status_line, &end, 10) != r->status
1186             || *end != ' '
1187             || (end - 3) != r->status_line)) {
1188         r->status_line = NULL;
1189     }
1190 }
1191
1192 /*
1193  * Determine the protocol to use for the response. Potentially downgrade
1194  * to HTTP/1.0 in some situations and/or turn off keepalives.
1195  *
1196  * also prepare r->status_line.
1197  */
1198 static void basic_http_header_check(request_rec *r,
1199                                     const char **protocol)
1200 {
1201     if (r->assbackwards) {
1202         /* no such thing as a response protocol */
1203         return;
1204     }
1205
1206     validate_status_line(r);
1207
1208     if (!r->status_line) {
1209         r->status_line = status_lines[ap_index_of_response(r->status)];
1210     }
1211
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);
1216     }
1217
1218     /* kludge around broken browsers when indicated by force-response-1.0
1219      */
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;
1224     }
1225     else {
1226         *protocol = AP_SERVER_PROTOCOL;
1227     }
1228
1229 }
1230
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)
1234 {
1235     char *date;
1236     const char *server;
1237     header_struct h;
1238     struct iovec vec[4];
1239
1240     if (r->assbackwards) {
1241         /* there are no headers to send */
1242         return;
1243     }
1244
1245     /* Output the HTTP/1.x Status-Line and the Date and Server fields */
1246
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
1256     {
1257         char *tmp;
1258         apr_size_t len;
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);
1262     }
1263 #else
1264     apr_brigade_writev(bb, NULL, NULL, vec, 4);
1265 #endif
1266
1267     date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
1268     ap_recent_rfc822_date(date, r->request_time);
1269
1270     h.pool = r->pool;
1271     h.bb = bb;
1272     form_header_field(&h, "Date", date);
1273
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");
1278         if (server) {
1279             form_header_field(&h, "Server", server);
1280         }
1281     }
1282     else {
1283         form_header_field(&h, "Server", ap_get_server_version());
1284     }
1285
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");
1289 }
1290
1291 AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb)
1292 {
1293     const char *protocol;
1294
1295     basic_http_header_check(r, &protocol);
1296     basic_http_header(r, bb, protocol);
1297 }
1298
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.
1306  *
1307  * This should also work on keepalive connections assuming they use the
1308  * same small buffer for the first read of each new request.
1309  *
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.
1315  */
1316 static void terminate_header(apr_bucket_brigade *bb)
1317 {
1318     char tmp[] = "X-Pad: avoid browser bug" CRLF;
1319     char crlf[] = CRLF;
1320     apr_off_t len;
1321     apr_size_t buflen;
1322
1323     (void) apr_brigade_length(bb, 1, &len);
1324
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);
1329     }
1330     buflen = strlen(crlf);
1331     ap_xlate_proto_to_ascii(crlf, buflen);
1332     apr_brigade_write(bb, NULL, NULL, crlf, buflen);
1333 }
1334
1335 /* Build the Allow field-value from the request handler method mask.
1336  * Note that we always allow TRACE, since it is handled below.
1337  */
1338 static char *make_allow(request_rec *r)
1339 {
1340     char *list;
1341     apr_int64_t mask;
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);
1347
1348     mask = r->allowed_methods->method_mask;
1349
1350     for (; hi; hi = apr_hash_next(hi)) {
1351         const void *key;
1352         void *val;
1353
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;
1357
1358             /* the M_GET method actually refers to two methods */
1359             if (*(int *)val == M_GET)
1360                 *(const char **)apr_array_push(allow) = "HEAD";
1361         }
1362     }
1363
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";
1367
1368     list = apr_array_pstrcat(r->pool, allow, ',');
1369
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)) {
1375         int i;
1376         char **xmethod = (char **) r->allowed_methods->method_list->elts;
1377
1378         /*
1379          * Append all of the elements of r->allowed_methods->method_list
1380          */
1381         for (i = 0; i < r->allowed_methods->method_list->nelts; ++i) {
1382             list = apr_pstrcat(r->pool, list, ",", xmethod[i], NULL);
1383         }
1384     }
1385
1386     return list;
1387 }
1388
1389 AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r)
1390 {
1391     core_server_config *conf;
1392     int rv;
1393     apr_bucket_brigade *bb;
1394     header_struct h;
1395     apr_bucket *b;
1396     int body;
1397     char *bodyread = NULL, *bodyoff;
1398     apr_size_t bodylen = 0;
1399     apr_size_t bodybuf;
1400     long res;
1401
1402     if (r->method_number != M_TRACE) {
1403         return DECLINED;
1404     }
1405
1406     /* Get the original request */
1407     while (r->prev) {
1408         r = r->prev;
1409     }
1410     conf = (core_server_config *)ap_get_module_config(r->server->module_config,
1411                                                       &core_module);
1412
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;
1417     }
1418
1419     if (conf->trace_enable == AP_TRACE_EXTENDED)
1420         /* XX should be = REQUEST_CHUNKED_PASS */
1421         body = REQUEST_CHUNKED_DECHUNK;
1422     else
1423         body = REQUEST_NO_BODY;
1424
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");
1429         return rv;
1430     }
1431
1432     if (ap_should_client_block(r)) {
1433
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;
1439             }
1440             /* always 32 extra bytes to catch chunk header exceptions */
1441             bodybuf = (apr_size_t)r->remaining + 32;
1442         }
1443         else {
1444             /* Add an extra 8192 for chunk headers */
1445             bodybuf = 73730;
1446         }
1447
1448         bodyoff = bodyread = apr_palloc(r->pool, bodybuf);
1449
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) {
1453             bodylen += res;
1454             bodybuf -= res;
1455             bodyoff += res;
1456         }
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)
1460                 ;
1461             apr_table_setn(r->notes, "error-notes",
1462                    "Extended TRACE request bodies cannot exceed 64k");
1463             return HTTP_REQUEST_ENTITY_TOO_LARGE;
1464         }
1465
1466         if (res < 0) {
1467             return HTTP_BAD_REQUEST;
1468         }
1469     }
1470
1471     ap_set_content_type(r, "message/http");
1472
1473     /* Now we recreate the request, and echo it back */
1474
1475     bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1476     apr_brigade_putstrs(bb, NULL, NULL, r->the_request, CRLF, NULL);
1477     h.pool = r->pool;
1478     h.bb = bb;
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);
1482
1483     /* If configured to accept a body, echo the body */
1484     if (bodylen) {
1485         b = apr_bucket_pool_create(bodyread, bodylen, 
1486                                    r->pool, bb->bucket_alloc);
1487         APR_BRIGADE_INSERT_TAIL(bb, b);
1488     }
1489     
1490     ap_pass_brigade(r->output_filters,  bb);
1491
1492     return DONE;
1493 }
1494
1495 AP_DECLARE(int) ap_send_http_options(request_rec *r)
1496 {
1497     if (r->assbackwards) {
1498         return DECLINED;
1499     }
1500
1501     apr_table_setn(r->headers_out, "Allow", make_allow(r));
1502
1503     /* the request finalization will send an EOS, which will flush all
1504      * the headers out (including the Allow header)
1505      */
1506
1507     return OK;
1508 }
1509
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.
1515  */
1516 static int uniq_field_values(void *d, const char *key, const char *val)
1517 {
1518     apr_array_header_t *values;
1519     char *start;
1520     char *e;
1521     char **strpp;
1522     int  i;
1523
1524     values = (apr_array_header_t *)d;
1525
1526     e = apr_pstrdup(values->pool, val);
1527
1528     do {
1529         /* Find a non-empty fieldname */
1530
1531         while (*e == ',' || apr_isspace(*e)) {
1532             ++e;
1533         }
1534         if (*e == '\0') {
1535             break;
1536         }
1537         start = e;
1538         while (*e != '\0' && *e != ',' && !apr_isspace(*e)) {
1539             ++e;
1540         }
1541         if (*e != '\0') {
1542             *e++ = '\0';
1543         }
1544
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.
1547          */
1548         for (i = 0, strpp = (char **) values->elts; i < values->nelts;
1549              ++i, ++strpp) {
1550             if (*strpp && strcasecmp(*strpp, start) == 0) {
1551                 break;
1552             }
1553         }
1554         if (i == values->nelts) {  /* if not found */
1555             *(char **)apr_array_push(values) = start;
1556         }
1557     } while (*e != '\0');
1558
1559     return 1;
1560 }
1561
1562 /*
1563  * Since some clients choke violently on multiple Vary fields, or
1564  * Vary fields with duplicate tokens, combine any multiples and remove
1565  * any duplicates.
1566  */
1567 static void fixup_vary(request_rec *r)
1568 {
1569     apr_array_header_t *varies;
1570
1571     varies = apr_array_make(r->pool, 5, sizeof(char *));
1572
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.
1576      */
1577     apr_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
1578                  (void *) varies, r->headers_out, "Vary", NULL);
1579
1580     /* If we found any, replace old Vary fields with unique-ified value */
1581
1582     if (varies->nelts > 0) {
1583         apr_table_setn(r->headers_out, "Vary",
1584                        apr_array_pstrcat(r->pool, varies, ','));
1585     }
1586 }
1587
1588 AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct)
1589 {
1590     if (!ct) {
1591         r->content_type = NULL;
1592     }
1593     else if (!r->content_type || strcmp(r->content_type, ct)) {
1594         r->content_type = ct;
1595
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.
1600          */
1601         ap_add_output_filters_by_type(r);
1602     }
1603 }
1604
1605 typedef struct header_filter_ctx {
1606     int headers_sent;
1607 } header_filter_ctx;
1608
1609 AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
1610                                                            apr_bucket_brigade *b)
1611 {
1612     request_rec *r = f->r;
1613     conn_rec *c = r->connection;
1614     const char *clheader;
1615     const char *protocol;
1616     apr_bucket *e;
1617     apr_bucket_brigade *b2;
1618     header_struct h;
1619     header_filter_ctx *ctx = f->ctx;
1620
1621     AP_DEBUG_ASSERT(!r->main);
1622
1623     if (r->header_only) {
1624         if (!ctx) {
1625             ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx));
1626         }
1627         else if (ctx->headers_sent) {
1628             apr_brigade_destroy(b);
1629             return OK;
1630         }
1631     }
1632
1633     APR_BRIGADE_FOREACH(e, b) {
1634         if (e->type == &ap_bucket_type_error) {
1635             ap_bucket_error *eb = e->data;
1636
1637             ap_die(eb->status, r);
1638             return AP_FILTER_ERROR;
1639         }
1640     }
1641
1642     if (r->assbackwards) {
1643         r->sent_bodyct = 1;
1644         ap_remove_output_filter(f);
1645         return ap_pass_brigade(f->next, b);
1646     }
1647
1648     /*
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.
1652      */
1653     if (!apr_is_empty_table(r->err_headers_out)) {
1654         r->headers_out = apr_table_overlay(r->pool, r->err_headers_out,
1655                                            r->headers_out);
1656     }
1657
1658     /*
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.
1662      *
1663      * Note: the force-response-1.0 should come before the call to
1664      *       basic_http_header_check()
1665      */
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");
1670     }
1671     else {
1672         fixup_vary(r);
1673     }
1674
1675     /*
1676      * Now remove any ETag response header field if earlier processing
1677      * says so (such as a 'FileETag None' directive).
1678      */
1679     if (apr_table_get(r->notes, "no-etag") != NULL) {
1680         apr_table_unset(r->headers_out, "ETag");
1681     }
1682
1683     /* determine the protocol and whether we should use keepalives. */
1684     basic_http_header_check(r, &protocol);
1685     ap_set_keepalive(r);
1686
1687     if (r->chunked) {
1688         apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
1689         apr_table_unset(r->headers_out, "Content-Length");
1690     }
1691
1692     apr_table_setn(r->headers_out, "Content-Type", 
1693                    ap_make_content_type(r, r->content_type));
1694
1695     if (r->content_encoding) {
1696         apr_table_setn(r->headers_out, "Content-Encoding",
1697                        r->content_encoding);
1698     }
1699
1700     if (!apr_is_empty_array(r->content_languages)) {
1701         int i;
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]);
1705         }
1706     }
1707
1708     /*
1709      * Control cachability for non-cachable responses if not already set by
1710      * some other part of the server configuration.
1711      */
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);
1716     }
1717
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
1729      */
1730     if (r->header_only
1731         && (clheader = apr_table_get(r->headers_out, "Content-Length"))
1732         && !strcmp(clheader, "0")) {
1733         apr_table_unset(r->headers_out, "Content-Length");
1734     }
1735
1736     b2 = apr_brigade_create(r->pool, c->bucket_alloc);
1737     basic_http_header(r, b2, protocol);
1738
1739     h.pool = r->pool;
1740     h.bb = b2;
1741
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,
1745                      "Connection",
1746                      "Keep-Alive",
1747                      "ETag",
1748                      "Content-Location",
1749                      "Expires",
1750                      "Cache-Control",
1751                      "Vary",
1752                      "Warning",
1753                      "WWW-Authenticate",
1754                      "Proxy-Authenticate",
1755                      "Set-Cookie",
1756                      "Set-Cookie2",
1757                      NULL);
1758     }
1759     else {
1760         send_all_header_fields(&h, r);
1761     }
1762
1763     terminate_header(b2);
1764
1765     ap_pass_brigade(f->next, b2);
1766
1767     if (r->header_only) {
1768         apr_brigade_destroy(b);
1769         ctx->headers_sent = 1;
1770         return OK;
1771     }
1772
1773     r->sent_bodyct = 1;         /* Whatever follows is real body stuff... */
1774
1775     if (r->chunked) {
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.
1779          */
1780         ap_add_output_filter("CHUNK", NULL, r, r->connection);
1781     }
1782
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.
1786      */
1787     ap_remove_output_filter(f);
1788     return ap_pass_brigade(f->next, b);
1789 }
1790
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.
1794  *
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.
1797  *
1798  * The proper procedure is this:
1799  *
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
1806  *
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.
1810  *
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.
1813  *
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.
1821  *
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.
1827  */
1828
1829 AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy)
1830 {
1831     const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
1832     const char *lenp = apr_table_get(r->headers_in, "Content-Length");
1833
1834     r->read_body = read_policy;
1835     r->read_chunked = 0;
1836     r->remaining = 0;
1837
1838     if (tenc) {
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;
1843         }
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;
1848         }
1849
1850         r->read_chunked = 1;
1851     }
1852     else if (lenp) {
1853         int conversion_error = 0;
1854         char *endstr;
1855
1856         errno = 0;
1857         r->remaining = strtol(lenp, &endstr, 10); /* depend on ANSI */
1858
1859         /* See comments in ap_http_filter() */
1860         if (errno || (endstr && *endstr) || (r->remaining < 0)) {
1861             conversion_error = 1; 
1862         }
1863
1864         if (conversion_error) {
1865             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1866                           "Invalid Content-Length");
1867             return HTTP_BAD_REQUEST;
1868         }
1869     }
1870
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;
1876     }
1877
1878 #ifdef AP_DEBUG
1879     {
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,
1883                                                         &core_module);
1884         AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(req_cfg->bb));
1885     }
1886 #endif
1887
1888     return OK;
1889 }
1890
1891 AP_DECLARE(int) ap_should_client_block(request_rec *r)
1892 {
1893     /* First check if we have already read the request body */
1894
1895     if (r->read_length || (!r->read_chunked && (r->remaining <= 0))) {
1896         return 0;
1897     }
1898
1899     return 1;
1900 }
1901
1902 /**
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
1908  *     returned.
1909  * In general, any negative number can be considered an overflow error.
1910  */
1911 static long get_chunk_size(char *b)
1912 {
1913     long chunksize = 0;
1914     size_t chunkbits = sizeof(long) * 8;
1915
1916     ap_xlate_proto_from_ascii(b, strlen(b));
1917
1918     /* Skip leading zeros */
1919     while (*b == '0') {
1920         ++b;
1921     }
1922
1923     while (apr_isxdigit(*b) && (chunkbits > 0)) {
1924         int xvalue = 0;
1925
1926         if (*b >= '0' && *b <= '9') {
1927             xvalue = *b - '0';
1928         }
1929         else if (*b >= 'A' && *b <= 'F') {
1930             xvalue = *b - 'A' + 0xa;
1931         }
1932         else if (*b >= 'a' && *b <= 'f') {
1933             xvalue = *b - 'a' + 0xa;
1934         }
1935
1936         chunksize = (chunksize << 4) | xvalue;
1937         chunkbits -= 4;
1938         ++b;
1939     }
1940     if (apr_isxdigit(*b) && (chunkbits <= 0)) {
1941         /* overflow */
1942         return -1;
1943     }
1944
1945     return chunksize;
1946 }
1947
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.
1956  *
1957  */
1958 AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer,
1959                                      apr_size_t bufsiz)
1960 {
1961     apr_status_t rv;
1962     apr_bucket_brigade *bb;
1963
1964     if (r->remaining < 0 || (!r->read_chunked && r->remaining == 0)) {
1965         return 0;
1966     }
1967
1968     bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1969     if (bb == NULL) {
1970         r->connection->keepalive = AP_CONN_CLOSE;
1971         return -1;
1972     }
1973
1974     rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
1975                         APR_BLOCK_READ, bufsiz);
1976   
1977     /* We lose the failure code here.  This is why ap_get_client_block should
1978      * not be used.
1979      */
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.
1983          */
1984         r->connection->keepalive = AP_CONN_CLOSE;
1985         apr_brigade_destroy(bb);
1986         return -1;
1987     }
1988
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.
1992      */
1993     AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(bb));
1994
1995     /* Check to see if EOS in the brigade.
1996      *
1997      * If so, we have to leave a nugget for the *next* ap_get_client_block
1998      * call to return 0.
1999      */
2000     if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
2001         if (r->read_chunked) {
2002             r->remaining = -1;
2003         }
2004         else {
2005             r->remaining = 0;
2006         }
2007     }
2008
2009     rv = apr_brigade_flatten(bb, buffer, &bufsiz);
2010     if (rv != APR_SUCCESS) {
2011         apr_brigade_destroy(bb);
2012         return -1;
2013     }
2014
2015     /* XXX yank me? */
2016     r->read_length += bufsiz;
2017
2018     apr_brigade_destroy(bb);
2019     return bufsiz;
2020 }
2021
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.
2028  *
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.,
2031  *
2032  *    if ((retval = ap_discard_request_body(r)) != OK) {
2033  *        return retval;
2034  *    }
2035  */
2036 AP_DECLARE(int) ap_discard_request_body(request_rec *r)
2037 {
2038     apr_bucket_brigade *bb;
2039     int rv, seen_eos;
2040
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
2044      * to avoid.
2045      *
2046      * This function is also a no-op on a subrequest.
2047      */
2048     if (r->main || r->connection->keepalive == AP_CONN_CLOSE ||
2049         ap_status_drops_connection(r->status)) {
2050         return OK;
2051     }
2052
2053     bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
2054     seen_eos = 0;
2055     do {
2056         apr_bucket *bucket;
2057
2058         rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
2059                             APR_BLOCK_READ, HUGE_STRING_LEN);
2060
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.
2064              * 
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.
2068              */
2069             if (rv == AP_FILTER_ERROR) {
2070                 apr_brigade_destroy(bb);
2071                 return rv;
2072             }
2073             else {
2074                 apr_brigade_destroy(bb);
2075                 return HTTP_BAD_REQUEST;
2076             }
2077         }
2078
2079         APR_BRIGADE_FOREACH(bucket, bb) {
2080             const char *data;
2081             apr_size_t len;
2082
2083             if (APR_BUCKET_IS_EOS(bucket)) {
2084                 seen_eos = 1;
2085                 break;
2086             }
2087
2088             /* These are metadata buckets. */
2089             if (bucket->length == 0) {
2090                 continue;
2091             }
2092
2093             /* We MUST read because in case we have an unknown-length
2094              * bucket or one that morphs, we want to exhaust it.
2095              */
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;
2100             }
2101         }
2102         apr_brigade_cleanup(bb);
2103     } while (!seen_eos);
2104
2105     return OK;
2106 }
2107
2108 static const char *add_optional_notes(request_rec *r,
2109                                       const char *prefix,
2110                                       const char *key,
2111                                       const char *suffix)
2112 {
2113     const char *notes, *result;
2114
2115     if ((notes = apr_table_get(r->notes, key)) == NULL) {
2116         result = apr_pstrcat(r->pool, prefix, suffix, NULL);
2117     }
2118     else {
2119         result = apr_pstrcat(r->pool, prefix, notes, suffix, NULL);
2120     }
2121
2122     return result;
2123 }
2124
2125 /* construct and return the default error message for a given
2126  * HTTP defined error code
2127  */
2128 static const char *get_canned_error_string(int status,
2129                                            request_rec *r,
2130                                            const char *location)
2131 {
2132     apr_pool_t *p = r->pool;
2133     const char *error_notes, *h1, *s1;
2134
2135     switch (status) {
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",
2143                            NULL));
2144     case HTTP_SEE_OTHER:
2145         return(apr_pstrcat(p,
2146                            "<p>The answer to your request is located "
2147                            "<a href=\"",
2148                            ap_escape_html(r->pool, location),
2149                            "\">here</a>.</p>\n",
2150                            NULL));
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",
2158                            NULL));
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",
2171                                   "error-notes",
2172                                   "</p>\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",
2178                            NULL));
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",
2184                            NULL));
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),
2191                            ".</p>\n",
2192                            NULL));
2193     case HTTP_NOT_ACCEPTABLE:
2194         s1 = apr_pstrcat(p,
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",
2199                          NULL);
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:
2204         s1 = apr_pstrcat(p,
2205                          "<p>A request of the requested method ",
2206                          ap_escape_html(r->pool, r->method),
2207                          " requires a valid Content-length.<br />\n",
2208                          NULL);
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 "
2213                            "for the URL ",
2214                            ap_escape_html(r->pool, r->uri),
2215                            " evaluated to false.</p>\n",
2216                            NULL));
2217     case HTTP_NOT_IMPLEMENTED:
2218         s1 = apr_pstrcat(p,
2219                          "<p>",
2220                          ap_escape_html(r->pool, r->method), " to ",
2221                          ap_escape_html(r->pool, r->uri),
2222                          " not supported.<br />\n",
2223                          NULL);
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",
2236                            NULL));
2237     case HTTP_REQUEST_TIME_OUT:
2238         return("<p>Server timeout waiting for the HTTP request from the client.</p>\n");
2239     case HTTP_GONE:
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 "
2246                            "resource.</p>\n",
2247                            NULL));
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",
2256                            NULL));
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 "
2271                            "request-header"
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")),
2275                            "\n</pre>\n"
2276                            "but we only allow the 100-continue "
2277                            "expectation.</p>\n",
2278                            NULL));
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");
2283     case HTTP_LOCKED:
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 */
2314         /*
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.)
2320          */
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));
2326         }
2327         else {
2328             return(apr_pstrcat(p,
2329                                "<p>The server encountered an internal "
2330                                "error or\n"
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 "
2338                                "error occurred,\n"
2339                                "and anything you might have done that "
2340                                "may have\n"
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",
2345                                NULL));
2346         }
2347         /*
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.
2355          *
2356          * if ((error_notes = apr_table_get(r->notes,
2357          *                                  "error-notes")) != NULL) {
2358          *     return(apr_pstrcat(p, error_notes, "<p />\n", NULL);
2359          * }
2360          * else {
2361          *     return "";
2362          * }
2363          */
2364     }
2365 }
2366
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.
2372  */
2373 AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error)
2374 {
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");
2379
2380     /* At this point, we are starting the response over, so we have to reset
2381      * this value.
2382      */
2383     r->eos_sent = 0;
2384
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
2387      */
2388
2389     r->output_filters = r->proto_output_filters;
2390
2391     ap_run_insert_error_filter(r);
2392
2393     /*
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
2396      * former.
2397      */
2398     if (location == NULL) {
2399         location = apr_table_get(r->err_headers_out, "Location");
2400     }
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.
2404      */
2405     if (status == HTTP_NOT_MODIFIED) {
2406         ap_finalize_request_protocol(r);
2407         return;
2408     }
2409
2410     if (status == HTTP_NO_CONTENT) {
2411         ap_finalize_request_protocol(r);
2412         return;
2413     }
2414
2415     if (!r->assbackwards) {
2416         apr_table_t *tmp = r->headers_out;
2417
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.
2422          */
2423         r->headers_out = r->err_headers_out;
2424         r->err_headers_out = tmp;
2425         apr_table_clear(r->err_headers_out);
2426
2427         if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) {
2428             if ((location != NULL) && *location) {
2429                 apr_table_setn(r->headers_out, "Location", location);
2430             }
2431             else {
2432                 location = "";   /* avoids coredump when printing, below */
2433             }
2434         }
2435
2436         r->content_languages = NULL;
2437         r->content_encoding = NULL;
2438         r->clength = 0;
2439
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
2445                                                  * charset later
2446                                                  */
2447             ap_set_content_type(r, "text/html");
2448         }
2449         else {
2450             ap_set_content_type(r, "text/html; charset=iso-8859-1");
2451         }
2452
2453         if ((status == HTTP_METHOD_NOT_ALLOWED)
2454             || (status == HTTP_NOT_IMPLEMENTED)) {
2455             apr_table_setn(r->headers_out, "Allow", make_allow(r));
2456         }
2457
2458         if (r->header_only) {
2459             ap_finalize_request_protocol(r);
2460             return;
2461         }
2462     }
2463
2464     if ((custom_response = ap_response_code_string(r, idx))) {
2465         /*
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 ").
2474          * 
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.
2480          */
2481         if (custom_response[0] == '\"') {
2482             ap_rputs(custom_response + 1, r);
2483             ap_finalize_request_protocol(r);
2484             return;
2485         }
2486     }
2487     {
2488         const char *title = status_lines[idx];
2489         const char *h1;
2490
2491         /* Accept a status_line set by a module, but only if it begins
2492          * with the 3 digit status code
2493          */
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;
2502         }
2503
2504         /* folks decided they didn't want the error code in the H1 text */
2505         h1 = &title[4];
2506
2507         /* can't count on a charset filter being in place here,
2508          * so do ebcdic->ascii translation explicitly (if needed)
2509          */
2510
2511         ap_rvputs_proto_in_ascii(r,
2512                   DOCTYPE_HTML_2_0
2513                   "<html><head>\n<title>", title,
2514                   "</title>\n</head><body>\n<h1>", h1, "</h1>\n",
2515                   NULL);
2516
2517         ap_rvputs_proto_in_ascii(r,
2518                                  get_canned_error_string(status, r, location),
2519                                  NULL);
2520
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);
2526         }
2527         ap_rvputs_proto_in_ascii(r, ap_psignature("<hr>\n", r), NULL);
2528         ap_rvputs_proto_in_ascii(r, "</body></html>\n", NULL);
2529     }
2530     ap_finalize_request_protocol(r);
2531 }
2532
2533 /*
2534  * Create a new method list with the specified number of preallocated
2535  * extension slots.
2536  */
2537 AP_DECLARE(ap_method_list_t *) ap_make_method_list(apr_pool_t *p, int nelts)
2538 {
2539     ap_method_list_t *ml;
2540
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 *));
2544     return ml;
2545 }
2546
2547 /*
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!).
2550  */
2551 AP_DECLARE(void) ap_copy_method_list(ap_method_list_t *dest,
2552                                      ap_method_list_t *src)
2553 {
2554     int i;
2555     char **imethods;
2556     char **omethods;
2557
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]);
2563     }
2564 }
2565
2566 /*
2567  * Invoke a callback routine for each method in the specified list.
2568  */
2569 AP_DECLARE_NONSTD(void) ap_method_list_do(int (*comp) (void *urec,
2570                                                        const char *mname,
2571                                                        int mnum),
2572                                           void *rec,
2573                                           const ap_method_list_t *ml, ...)
2574 {
2575     va_list vp;
2576     va_start(vp, ml);
2577     ap_method_list_vdo(comp, rec, ml, vp);
2578     va_end(vp);
2579 }
2580
2581 AP_DECLARE(void) ap_method_list_vdo(int (*comp) (void *mrec,
2582                                                  const char *mname,
2583                                                  int mnum),
2584                                     void *rec, const ap_method_list_t *ml,
2585                                     va_list vp)
2586 {
2587
2588 }
2589
2590 /*
2591  * Return true if the specified HTTP method is in the provided
2592  * method list.
2593  */
2594 AP_DECLARE(int) ap_method_in_list(ap_method_list_t *l, const char *method)
2595 {
2596     int methnum;
2597     int i;
2598     char **methods;
2599
2600     /*
2601      * If it's one of our known methods, use the shortcut and check the
2602      * bitmask.
2603      */
2604     methnum = ap_method_number_of(method);
2605     if (methnum != M_INVALID) {
2606         return !!(l->method_mask & (AP_METHOD_BIT << methnum));
2607     }
2608     /*
2609      * Otherwise, see if the method name is in the array or string names
2610      */
2611     if ((l->method_list == NULL) || (l->method_list->nelts == 0)) {
2612         return 0;
2613     }
2614     methods = (char **)l->method_list->elts;
2615     for (i = 0; i < l->method_list->nelts; ++i) {
2616         if (strcmp(method, methods[i]) == 0) {
2617             return 1;
2618         }
2619     }
2620     return 0;
2621 }
2622
2623 /*
2624  * Add the specified method to a method list (if it isn't already there).
2625  */
2626 AP_DECLARE(void) ap_method_list_add(ap_method_list_t *l, const char *method)
2627 {
2628     int methnum;
2629     int i;
2630     const char **xmethod;
2631     char **methods;
2632
2633     /*
2634      * If it's one of our known methods, use the shortcut and use the
2635      * bitmask.
2636      */
2637     methnum = ap_method_number_of(method);
2638     l->method_mask |= (AP_METHOD_BIT << methnum);
2639     if (methnum != M_INVALID) {
2640         return;
2641     }
2642     /*
2643      * Otherwise, see if the method name is in the array of string names.
2644      */
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) {
2649                 return;
2650             }
2651         }
2652     }
2653     xmethod = (const char **) apr_array_push(l->method_list);
2654     *xmethod = method;
2655 }
2656
2657 /*
2658  * Remove the specified method from a method list.
2659  */
2660 AP_DECLARE(void) ap_method_list_remove(ap_method_list_t *l,
2661                                        const char *method)
2662 {
2663     int methnum;
2664     char **methods;
2665
2666     /*
2667      * If it's a known methods, either builtin or registered
2668      * by a module, use the bitmask.
2669      */
2670     methnum = ap_method_number_of(method);
2671     l->method_mask |= ~(AP_METHOD_BIT << methnum);
2672     if (methnum != M_INVALID) {
2673         return;
2674     }
2675     /*
2676      * Otherwise, see if the method name is in the array of string names.
2677      */
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];
2685                 }
2686                 --l->method_list->nelts;
2687             }
2688             else {
2689                 ++i;
2690             }
2691         }
2692     }
2693 }
2694
2695 /*
2696  * Reset a method list to be completely empty.
2697  */
2698 AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l)
2699 {
2700     l->method_mask = 0;
2701     l->method_list->nelts = 0;
2702 }
2703
2704 /* Generate the human-readable hex representation of an unsigned long
2705  * (basically a faster version of 'sprintf("%lx")')
2706  */
2707 #define HEX_DIGITS "0123456789abcdef"
2708 static char *etag_ulong_to_hex(char *next, unsigned long u)
2709 {
2710     int printing = 0;
2711     int shift = sizeof(unsigned long) * 8 - 4;
2712     do {
2713         unsigned long next_digit = ((u >> shift) & (unsigned long)0xf);
2714         if (next_digit) {
2715             *next++ = HEX_DIGITS[next_digit];
2716             printing = 1;
2717         }
2718         else if (printing) {
2719             *next++ = HEX_DIGITS[next_digit];
2720         }
2721         shift -= 4;
2722     } while (shift);
2723     *next++ = HEX_DIGITS[u & (unsigned long)0xf];
2724     return next;
2725 }
2726
2727 #define ETAG_WEAK "W/"
2728 #define CHARS_PER_UNSIGNED_LONG (sizeof(unsigned long) * 2)
2729 /*
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.
2735  */
2736 AP_DECLARE(char *) ap_make_etag(request_rec *r, int force_weak)
2737 {
2738     char *weak;
2739     apr_size_t weak_len;
2740     char *etag;
2741     char *next;
2742     core_dir_config *cfg;
2743     etag_components_t etag_bits;
2744     etag_components_t bits_added;
2745
2746     cfg = (core_dir_config *)ap_get_module_config(r->per_dir_config,
2747                                                   &core_module);
2748     etag_bits = (cfg->etag_bits & (~ cfg->etag_remove)) | cfg->etag_add;
2749     
2750     /*
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.
2754      */
2755     if (etag_bits & ETAG_NONE) {
2756         apr_table_setn(r->notes, "no-etag", "omit");
2757         return "";
2758     }
2759
2760     if (etag_bits == ETAG_UNSET) {
2761         etag_bits = ETAG_BACKWARD;
2762     }
2763     /*
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
2768      * for the file.
2769      *
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.
2774      */
2775     if ((r->request_time - r->mtime > (1 * APR_USEC_PER_SEC)) &&
2776         !force_weak) {
2777         weak = NULL;
2778         weak_len = 0;
2779     }
2780     else {
2781         weak = ETAG_WEAK;
2782         weak_len = sizeof(ETAG_WEAK);
2783     }
2784
2785     if (r->finfo.filetype != 0) {
2786         /*
2787          * ETag gets set to [W/]"inode-size-mtime", modulo any
2788          * FileETag keywords.
2789          */
2790         etag = apr_palloc(r->pool, weak_len + sizeof("\"--\"") +
2791                           3 * CHARS_PER_UNSIGNED_LONG + 1);
2792         next = etag;
2793         if (weak) {
2794             while (*weak) {
2795                 *next++ = *weak++;
2796             }
2797         }
2798         *next++ = '"';
2799         bits_added = 0;
2800         if (etag_bits & ETAG_INODE) {
2801             next = etag_ulong_to_hex(next, (unsigned long)r->finfo.inode);
2802             bits_added |= ETAG_INODE;
2803         }
2804         if (etag_bits & ETAG_SIZE) {
2805             if (bits_added != 0) {
2806                 *next++ = '-';
2807             }
2808             next = etag_ulong_to_hex(next, (unsigned long)r->finfo.size);
2809             bits_added |= ETAG_SIZE;
2810         }
2811         if (etag_bits & ETAG_MTIME) {
2812             if (bits_added != 0) {
2813                 *next++ = '-';
2814             }
2815             next = etag_ulong_to_hex(next, (unsigned long)r->mtime);
2816         }
2817         *next++ = '"';
2818         *next = '\0';
2819     }
2820     else {
2821         /*
2822          * Not a file document, so just use the mtime: [W/]"mtime"
2823          */
2824         etag = apr_palloc(r->pool, weak_len + sizeof("\"\"") +
2825                           CHARS_PER_UNSIGNED_LONG + 1);
2826         next = etag;
2827         if (weak) {
2828             while (*weak) {
2829                 *next++ = *weak++;
2830             }
2831         }
2832         *next++ = '"';
2833         next = etag_ulong_to_hex(next, (unsigned long)r->mtime);
2834         *next++ = '"';
2835         *next = '\0';
2836     }
2837
2838     return etag;
2839 }
2840
2841 AP_DECLARE(void) ap_set_etag(request_rec *r)
2842 {
2843     char *etag;
2844     char *variant_etag, *vlv;
2845     int vlv_weak;
2846
2847     if (!r->vlist_validator) {
2848         etag = ap_make_etag(r, 0);
2849     
2850         /* If we get a blank etag back, don't set the header. */
2851         if (!etag[0]) {
2852             return;
2853         }
2854     }
2855     else {
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.
2864          */
2865
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.
2870          */
2871
2872         vlv = r->vlist_validator;
2873         vlv_weak = (vlv[0] == 'W');
2874
2875         variant_etag = ap_make_etag(r, vlv_weak);
2876
2877         /* If we get a blank etag back, don't append vlv and stop now. */
2878         if (!variant_etag[0]) {
2879             return;
2880         }
2881
2882         /* merge variant_etag and vlv into a structured etag */
2883         variant_etag[strlen(variant_etag) - 1] = '\0';
2884         if (vlv_weak) {
2885             vlv += 3;
2886         }
2887         else {
2888             vlv++;
2889         }
2890         etag = apr_pstrcat(r->pool, variant_etag, ";", vlv, NULL);
2891     }
2892
2893     apr_table_setn(r->headers_out, "ETag", etag);
2894 }
2895
2896 static int parse_byterange(char *range, apr_off_t clength,
2897                            apr_off_t *start, apr_off_t *end)
2898 {
2899     char *dash = strchr(range, '-');
2900
2901     if (!dash) {
2902         return 0;
2903     }
2904
2905     if ((dash == range)) {
2906         /* In the form "-5" */
2907         *start = clength - apr_atoi64(dash + 1);
2908         *end = clength - 1;
2909     }
2910     else {
2911         *dash = '\0';
2912         dash++;
2913         *start = apr_atoi64(range);
2914         if (*dash) {
2915             *end = apr_atoi64(dash);
2916         }
2917         else {                  /* "5-" */
2918             *end = clength - 1;
2919         }
2920     }
2921
2922     if (*start < 0) {
2923         *start = 0;
2924     }
2925
2926     if (*end >= clength) {
2927         *end = clength - 1;
2928     }
2929
2930     if (*start > *end) {
2931         return -1;
2932     }
2933
2934     return (*start > 0 || *end < clength);
2935 }
2936
2937 static int ap_set_byterange(request_rec *r);
2938
2939 typedef struct byterange_ctx {
2940     apr_bucket_brigade *bb;
2941     int num_ranges;
2942     char *boundary;
2943     char *bound_head;
2944 } byterange_ctx;
2945
2946 /*
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.
2952  */
2953 static int use_range_x(request_rec *r)
2954 {
2955     const char *ua;
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")));
2959 }
2960
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 "]"
2964
2965 AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f,
2966                                                          apr_bucket_brigade *bb)
2967 {
2968 #define MIN_LENGTH(len1, len2) ((len1 > len2) ? len2 : len1)
2969     request_rec *r = f->r;
2970     conn_rec *c = r->connection;
2971     byterange_ctx *ctx;
2972     apr_bucket *e;
2973     apr_bucket_brigade *bsend;
2974     apr_off_t range_start;
2975     apr_off_t range_end;
2976     char *current;
2977     apr_off_t clength = 0;
2978     apr_status_t rv;
2979     int found = 0;
2980
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;
2988     }
2989
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);
2997     }
2998
2999     {
3000         int num_ranges = ap_set_byterange(r);
3001
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);
3006         }
3007
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);
3012
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());
3019
3020             ap_set_content_type(r, apr_pstrcat(r->pool, "multipart",
3021                                                use_range_x(r) ? "/x-" : "/",
3022                                                "byteranges; boundary=",
3023                                                ctx->boundary, NULL));
3024
3025             ctx->bound_head = apr_pstrcat(r->pool,
3026                                     CRLF "--", ctx->boundary,
3027                                     CRLF "Content-type: ",
3028                                     orig_ct,
3029                                     CRLF "Content-range: bytes ",
3030                                     NULL);
3031             ap_xlate_proto_to_ascii(ctx->bound_head, strlen(ctx->bound_head));
3032         }
3033     }
3034
3035     /* this brigade holds what we will be sending */
3036     bsend = apr_brigade_create(r->pool, c->bucket_alloc);
3037
3038     while ((current = ap_getword(r->pool, &r->range, ','))
3039            && (rv = parse_byterange(current, clength, &range_start,
3040                                     &range_end))) {
3041         apr_bucket *e2;
3042         apr_bucket *ec;
3043
3044         if (rv == -1) {
3045             continue;
3046         }
3047
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);
3054             continue;
3055         }
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);
3059             continue;
3060         }
3061
3062         found = 1;
3063
3064         /* For single range requests, we must produce Content-Range header.
3065          * Otherwise, we need to produce the multipart boundaries.
3066          */
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));
3071         }
3072         else {
3073             char *ts;
3074
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);
3078
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,
3083                                        c->bucket_alloc);
3084             APR_BRIGADE_INSERT_TAIL(bsend, e);
3085         }
3086
3087         do {
3088             apr_bucket *foo;
3089             const char *str;
3090             apr_size_t len;
3091
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.
3098                  */
3099                 /* XXX: check for failure? */
3100                 apr_bucket_read(ec, &str, &len, APR_BLOCK_READ);
3101                 apr_bucket_copy(ec, &foo);
3102             }
3103             APR_BRIGADE_INSERT_TAIL(bsend, foo);
3104             ec = APR_BUCKET_NEXT(ec);
3105         } while (ec != e2);
3106     }
3107
3108     if (found == 0) {
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);
3118     }
3119
3120     if (ctx->num_ranges > 1) {
3121         char *end;
3122
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);
3128     }
3129
3130     e = apr_bucket_eos_create(c->bucket_alloc);
3131     APR_BRIGADE_INSERT_TAIL(bsend, e);
3132
3133     /* we're done with the original content - all of our data is in bsend. */
3134     apr_brigade_destroy(bb);
3135
3136     /* send our multipart output */
3137     return ap_pass_brigade(f->next, bsend);
3138 }
3139
3140 static int ap_set_byterange(request_rec *r)
3141 {
3142     const char *range;
3143     const char *if_range;
3144     const char *match;
3145     const char *ct;
3146     int num_ranges;
3147
3148     if (r->assbackwards) {
3149         return 0;
3150     }
3151
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).
3155      *
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.
3160      */
3161
3162     if (!(range = apr_table_get(r->headers_in, "Range"))) {
3163         range = apr_table_get(r->headers_in, "Request-Range");
3164     }
3165
3166     if (!range || strncasecmp(range, "bytes=", 6) || r->status != HTTP_OK) {
3167         return 0;
3168     }
3169
3170     /* is content already a single range? */
3171     if (apr_table_get(r->headers_out, "Content-Range")) {
3172        return 0;
3173     }
3174
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))) {
3179        return 0;
3180     }
3181
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.
3185      */
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)) {
3190                 return 0;
3191             }
3192         }
3193         else if (!(match = apr_table_get(r->headers_out, "Last-Modified"))
3194                  || (strcmp(if_range, match) != 0)) {
3195             return 0;
3196         }
3197     }
3198
3199     if (!ap_strchr_c(range, ',')) {
3200         /* a single range */
3201         num_ranges = 1;
3202     }
3203     else {
3204         /* a multiple range */
3205         num_ranges = 2;
3206     }
3207
3208     r->status = HTTP_PARTIAL_CONTENT;
3209     r->range = range + 6;
3210
3211     return num_ranges;
3212 }