upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / server / 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 #include "apr_strmatch.h"
30
31 #define APR_WANT_STDIO          /* for sscanf */
32 #define APR_WANT_STRFUNC
33 #define APR_WANT_MEMFUNC
34 #include "apr_want.h"
35
36 #define CORE_PRIVATE
37 #include "util_filter.h"
38 #include "ap_config.h"
39 #include "httpd.h"
40 #include "http_config.h"
41 #include "http_core.h"
42 #include "http_protocol.h"
43 #include "http_main.h"
44 #include "http_request.h"
45 #include "http_vhost.h"
46 #include "http_log.h"           /* For errors detected in basic auth common
47                                  * support code... */
48 #include "mod_core.h"
49 #include "util_charset.h"
50 #include "util_ebcdic.h"
51 #include "scoreboard.h"
52
53 #if APR_HAVE_STDARG_H
54 #include <stdarg.h>
55 #endif
56 #if APR_HAVE_UNISTD_H
57 #include <unistd.h>
58 #endif
59
60
61 APR_HOOK_STRUCT(
62     APR_HOOK_LINK(post_read_request)
63     APR_HOOK_LINK(log_transaction)
64     APR_HOOK_LINK(http_method)
65     APR_HOOK_LINK(default_port)
66 )
67
68 AP_DECLARE_DATA ap_filter_rec_t *ap_old_write_func = NULL;
69
70
71 /* Patterns to match in ap_make_content_type() */
72 static const char *needcset[] = {
73     "text/plain",
74     "text/html",
75     NULL
76 };
77 static const apr_strmatch_pattern **needcset_patterns;
78 static const apr_strmatch_pattern *charset_pattern;
79
80 AP_DECLARE(void) ap_setup_make_content_type(apr_pool_t *pool)
81 {
82     int i;
83     for (i = 0; needcset[i]; i++) {
84         continue;
85     }
86     needcset_patterns = (const apr_strmatch_pattern **)
87         apr_palloc(pool, (i + 1) * sizeof(apr_strmatch_pattern *));
88     for (i = 0; needcset[i]; i++) {
89         needcset_patterns[i] = apr_strmatch_precompile(pool, needcset[i], 0);
90     }
91     needcset_patterns[i] = NULL;
92     charset_pattern = apr_strmatch_precompile(pool, "charset=", 0);
93 }
94
95 /*
96  * Builds the content-type that should be sent to the client from the
97  * content-type specified.  The following rules are followed:
98  *    - if type is NULL, type is set to ap_default_type(r)
99  *    - if charset adding is disabled, stop processing and return type.
100  *    - then, if there are no parameters on type, add the default charset
101  *    - return type
102  */
103 AP_DECLARE(const char *)ap_make_content_type(request_rec *r, const char *type)
104 {
105     const apr_strmatch_pattern **pcset;
106     core_dir_config *conf =
107         (core_dir_config *)ap_get_module_config(r->per_dir_config,
108                                                 &core_module);
109     core_request_config *request_conf;
110     apr_size_t type_len;
111
112     if (!type) {
113         type = ap_default_type(r);
114     }
115
116     if (conf->add_default_charset != ADD_DEFAULT_CHARSET_ON) {
117         return type;
118     }
119
120     request_conf =
121         ap_get_module_config(r->request_config, &core_module);
122     if (request_conf->suppress_charset) {
123         return type;
124     }
125
126     type_len = strlen(type);
127
128     if (apr_strmatch(charset_pattern, type, type_len) != NULL) {
129         /* already has parameter, do nothing */
130         /* XXX we don't check the validity */
131         ;
132     }
133     else {
134         /* see if it makes sense to add the charset. At present,
135          * we only add it if the Content-type is one of needcset[]
136          */
137         for (pcset = needcset_patterns; *pcset ; pcset++) {
138             if (apr_strmatch(*pcset, type, type_len) != NULL) {
139                 struct iovec concat[3];
140                 concat[0].iov_base = (void *)type;
141                 concat[0].iov_len = type_len;
142                 concat[1].iov_base = (void *)"; charset=";
143                 concat[1].iov_len = sizeof("; charset=") - 1;
144                 concat[2].iov_base = (void *)(conf->add_default_charset_name);
145                 concat[2].iov_len = strlen(conf->add_default_charset_name);
146                 type = apr_pstrcatv(r->pool, concat, 3, NULL);
147                 break;
148             }
149         }
150     }
151
152     return type;
153 }
154
155 AP_DECLARE(void) ap_set_content_length(request_rec *r, apr_off_t clength)
156 {
157     r->clength = clength;
158     apr_table_setn(r->headers_out, "Content-Length",
159                    apr_off_t_toa(r->pool, clength));
160 }
161
162 /*
163  * Return the latest rational time from a request/mtime (modification time)
164  * pair.  We return the mtime unless it's in the future, in which case we
165  * return the current time.  We use the request time as a reference in order
166  * to limit the number of calls to time().  We don't check for futurosity
167  * unless the mtime is at least as new as the reference.
168  */
169 AP_DECLARE(apr_time_t) ap_rationalize_mtime(request_rec *r, apr_time_t mtime)
170 {
171     apr_time_t now;
172
173     /* For all static responses, it's almost certain that the file was
174      * last modified before the beginning of the request.  So there's
175      * no reason to call time(NULL) again.  But if the response has been
176      * created on demand, then it might be newer than the time the request
177      * started.  In this event we really have to call time(NULL) again
178      * so that we can give the clients the most accurate Last-Modified.  If we
179      * were given a time in the future, we return the current time - the
180      * Last-Modified can't be in the future.
181      */
182     now = (mtime < r->request_time) ? r->request_time : apr_time_now();
183     return (mtime > now) ? now : mtime;
184 }
185
186 /* Min # of bytes to allocate when reading a request line */
187 #define MIN_LINE_ALLOC 80
188
189 /* Get a line of protocol input, including any continuation lines
190  * caused by MIME folding (or broken clients) if fold != 0, and place it
191  * in the buffer s, of size n bytes, without the ending newline.
192  *
193  * If s is NULL, ap_rgetline_core will allocate necessary memory from r->pool.
194  *
195  * Returns APR_SUCCESS if there are no problems and sets *read to be
196  * the full length of s.
197  *
198  * APR_ENOSPC is returned if there is not enough buffer space.
199  * Other errors may be returned on other errors.
200  *
201  * The LF is *not* returned in the buffer.  Therefore, a *read of 0
202  * indicates that an empty line was read.
203  *
204  * Notes: Because the buffer uses 1 char for NUL, the most we can return is
205  *        (n - 1) actual characters.
206  *
207  *        If no LF is detected on the last line due to a dropped connection
208  *        or a full buffer, that's considered an error.
209  */
210 AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n,
211                                           apr_size_t *read, request_rec *r,
212                                           int fold, apr_bucket_brigade *bb)
213 {
214     apr_status_t rv;
215     apr_bucket *e;
216     apr_size_t bytes_handled = 0, current_alloc = 0;
217     char *pos, *last_char = *s;
218     int do_alloc = (*s == NULL), saw_eos = 0;
219
220     /*
221      * Initialize last_char as otherwise a random value will be compared
222      * against APR_ASCII_LF at the end of the loop if bb only contains 
223      * zero-length buckets.
224      */
225     if (last_char)
226         *last_char = '\0';
227
228     for (;;) {
229     apr_brigade_cleanup(bb);
230     rv = ap_get_brigade(r->input_filters, bb, AP_MODE_GETLINE,
231                         APR_BLOCK_READ, 0);
232
233     if (rv != APR_SUCCESS) {
234         return rv;
235     }
236
237     /* Something horribly wrong happened.  Someone didn't block! */
238     if (APR_BRIGADE_EMPTY(bb)) {
239         return APR_EGENERAL;
240     }
241
242     APR_BRIGADE_FOREACH(e, bb) {
243         const char *str;
244         apr_size_t len;
245
246         /* If we see an EOS, don't bother doing anything more. */
247         if (APR_BUCKET_IS_EOS(e)) {
248             saw_eos = 1;
249             break;
250         }
251
252         rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
253
254         if (rv != APR_SUCCESS) {
255             return rv;
256         }
257
258         if (len == 0) {
259             /* no use attempting a zero-byte alloc (hurts when
260              * using --with-efence --enable-pool-debug) or
261              * doing any of the other logic either
262              */
263             continue;
264         }
265
266         /* Would this overrun our buffer?  If so, we'll die. */
267         if (n < bytes_handled + len) {
268             *read = bytes_handled;
269             if (*s) {
270                 /* ensure this string is NUL terminated */
271                 if (bytes_handled > 0) {
272                     (*s)[bytes_handled-1] = '\0';
273                 }
274                 else {
275                     (*s)[0] = '\0';
276                 }
277             }
278             return APR_ENOSPC;
279         }
280
281         /* Do we have to handle the allocation ourselves? */
282         if (do_alloc) {
283             /* We'll assume the common case where one bucket is enough. */
284             if (!*s) {
285                 current_alloc = len;
286                 if (current_alloc < MIN_LINE_ALLOC) {
287                     current_alloc = MIN_LINE_ALLOC;
288                 }
289                 *s = apr_palloc(r->pool, current_alloc);
290             }
291             else if (bytes_handled + len > current_alloc) {
292                 /* Increase the buffer size */
293                 apr_size_t new_size = current_alloc * 2;
294                 char *new_buffer;
295
296                 if (bytes_handled + len > new_size) {
297                     new_size = (bytes_handled + len) * 2;
298                 }
299
300                 new_buffer = apr_palloc(r->pool, new_size);
301
302                 /* Copy what we already had. */
303                 memcpy(new_buffer, *s, bytes_handled);
304                 current_alloc = new_size;
305                 *s = new_buffer;
306             }
307         }
308
309         /* Just copy the rest of the data to the end of the old buffer. */
310         pos = *s + bytes_handled;
311         memcpy(pos, str, len);
312         last_char = pos + len - 1;
313
314         /* We've now processed that new data - update accordingly. */
315         bytes_handled += len;
316     }
317
318         /* If we got a full line of input, stop reading */
319         if (last_char && (*last_char == APR_ASCII_LF)) {
320             break;
321         }
322     }
323
324     /* Now NUL-terminate the string at the end of the line; 
325      * if the last-but-one character is a CR, terminate there */
326     if (last_char > *s && last_char[-1] == APR_ASCII_CR) {
327         last_char--;
328     }
329     *last_char = '\0';
330     bytes_handled = last_char - *s;
331
332     /* If we're folding, we have more work to do.
333      *
334      * Note that if an EOS was seen, we know we can't have another line.
335      */
336     if (fold && bytes_handled && !saw_eos) {
337         for (;;) {
338         const char *str;
339         apr_size_t len;
340         char c;
341
342         /* Clear the temp brigade for this filter read. */
343         apr_brigade_cleanup(bb);
344
345         /* We only care about the first byte. */
346         rv = ap_get_brigade(r->input_filters, bb, AP_MODE_SPECULATIVE,
347                             APR_BLOCK_READ, 1);
348
349         if (rv != APR_SUCCESS) {
350             return rv;
351         }
352
353         if (APR_BRIGADE_EMPTY(bb)) {
354                 break;
355         }
356
357         e = APR_BRIGADE_FIRST(bb);
358
359         /* If we see an EOS, don't bother doing anything more. */
360         if (APR_BUCKET_IS_EOS(e)) {
361                 break;
362         }
363
364         rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
365
366         if (rv != APR_SUCCESS) {
367                 apr_brigade_cleanup(bb);
368             return rv;
369         }
370
371         /* Found one, so call ourselves again to get the next line.
372          *
373          * FIXME: If the folding line is completely blank, should we
374          * stop folding?  Does that require also looking at the next
375          * char?
376          */
377             /* When we call destroy, the buckets are deleted, so save that
378              * one character we need.  This simplifies our execution paths
379              * at the cost of one character read.
380              */
381             c = *str;
382         if (c == APR_ASCII_BLANK || c == APR_ASCII_TAB) {
383             /* Do we have enough space? We may be full now. */
384                 if (bytes_handled >= n) {
385                     *read = n;
386                     /* ensure this string is terminated */
387                     (*s)[n-1] = '\0';
388                     return APR_ENOSPC;
389                 }
390                 else {
391                 apr_size_t next_size, next_len;
392                 char *tmp;
393
394                 /* If we're doing the allocations for them, we have to
395                  * give ourselves a NULL and copy it on return.
396                  */
397                 if (do_alloc) {
398                     tmp = NULL;
399                 } else {
400                     /* We're null terminated. */
401                     tmp = last_char;
402                 }
403
404                 next_size = n - bytes_handled;
405
406                     rv = ap_rgetline_core(&tmp, next_size,
407                                           &next_len, r, 0, bb);
408
409                 if (rv != APR_SUCCESS) {
410                     return rv;
411                 }
412
413                 if (do_alloc && next_len > 0) {
414                     char *new_buffer;
415                     apr_size_t new_size = bytes_handled + next_len + 1;
416
417                     /* we need to alloc an extra byte for a null */
418                     new_buffer = apr_palloc(r->pool, new_size);
419
420                     /* Copy what we already had. */
421                     memcpy(new_buffer, *s, bytes_handled);
422
423                     /* copy the new line, including the trailing null */
424                     memcpy(new_buffer + bytes_handled, tmp, next_len + 1);
425                     *s = new_buffer;
426                 }
427
428                     bytes_handled += next_len;
429             }
430             }
431             else { /* next character is not tab or space */
432                 break;
433             }
434         }
435     }
436
437     *read = bytes_handled;
438     return APR_SUCCESS;
439 }
440
441 #if APR_CHARSET_EBCDIC
442 AP_DECLARE(apr_status_t) ap_rgetline(char **s, apr_size_t n,
443                                      apr_size_t *read, request_rec *r,
444                                      int fold, apr_bucket_brigade *bb)
445 {
446     /* on ASCII boxes, ap_rgetline is a macro which simply invokes
447      * ap_rgetline_core with the same parms
448      *
449      * on EBCDIC boxes, each complete http protocol input line needs to be
450      * translated into the code page used by the compiler.  Since
451      * ap_rgetline_core uses recursion, we do the translation in a wrapper
452      * function to insure that each input character gets translated only once.
453      */
454     apr_status_t rv;
455
456     rv = ap_rgetline_core(s, n, read, r, fold, bb);
457     if (rv == APR_SUCCESS) {
458         ap_xlate_proto_from_ascii(*s, *read);
459     }
460     return rv;
461 }
462 #endif
463
464 AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold)
465 {
466     char *tmp_s = s;
467     apr_status_t rv;
468     apr_size_t len;
469     apr_bucket_brigade *tmp_bb;
470
471     tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
472     rv = ap_rgetline(&tmp_s, n, &len, r, fold, tmp_bb);
473     apr_brigade_destroy(tmp_bb);
474
475     /* Map the out-of-space condition to the old API. */
476     if (rv == APR_ENOSPC) {
477         return n;
478     }
479
480     /* Anything else is just bad. */
481     if (rv != APR_SUCCESS) {
482         return -1;
483     }
484
485     return (int)len;
486 }
487
488 /* parse_uri: break apart the uri
489  * Side Effects:
490  * - sets r->args to rest after '?' (or NULL if no '?')
491  * - sets r->uri to request uri (without r->args part)
492  * - sets r->hostname (if not set already) from request (scheme://host:port)
493  */
494 AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri)
495 {
496     int status = HTTP_OK;
497
498     r->unparsed_uri = apr_pstrdup(r->pool, uri);
499
500     if (r->method_number == M_CONNECT) {
501         status = apr_uri_parse_hostinfo(r->pool, uri, &r->parsed_uri);
502     }
503     else {
504         /* Simple syntax Errors in URLs are trapped by
505          * parse_uri_components().
506          */
507         status = apr_uri_parse(r->pool, uri, &r->parsed_uri);
508     }
509
510     if (status == APR_SUCCESS) {
511         /* if it has a scheme we may need to do absoluteURI vhost stuff */
512         if (r->parsed_uri.scheme
513             && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r))) {
514             r->hostname = r->parsed_uri.hostname;
515         }
516         else if (r->method_number == M_CONNECT) {
517             r->hostname = r->parsed_uri.hostname;
518         }
519
520         r->args = r->parsed_uri.query;
521         r->uri = r->parsed_uri.path ? r->parsed_uri.path
522                  : apr_pstrdup(r->pool, "/");
523
524 #if defined(OS2) || defined(WIN32)
525         /* Handle path translations for OS/2 and plug security hole.
526          * This will prevent "http://www.wherever.com/..\..\/" from
527          * returning a directory for the root drive.
528          */
529         {
530             char *x;
531
532             for (x = r->uri; (x = strchr(x, '\\')) != NULL; )
533                 *x = '/';
534         }
535 #endif /* OS2 || WIN32 */
536     }
537     else {
538         r->args = NULL;
539         r->hostname = NULL;
540         r->status = HTTP_BAD_REQUEST;             /* set error status */
541         r->uri = apr_pstrdup(r->pool, uri);
542     }
543 }
544
545 static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
546 {
547     const char *ll;
548     const char *uri;
549     const char *pro;
550
551 #if 0
552     conn_rec *conn = r->connection;
553 #endif
554     int major = 1, minor = 0;   /* Assume HTTP/1.0 if non-"HTTP" protocol */
555     char http[5];
556     apr_size_t len;
557     int num_blank_lines = 0;
558     int max_blank_lines = r->server->limit_req_fields;
559
560     if (max_blank_lines <= 0) {
561         max_blank_lines = DEFAULT_LIMIT_REQUEST_FIELDS;
562     }
563
564     /* Read past empty lines until we get a real request line,
565      * a read error, the connection closes (EOF), or we timeout.
566      *
567      * We skip empty lines because browsers have to tack a CRLF on to the end
568      * of POSTs to support old CERN webservers.  But note that we may not
569      * have flushed any previous response completely to the client yet.
570      * We delay the flush as long as possible so that we can improve
571      * performance for clients that are pipelining requests.  If a request
572      * is pipelined then we won't block during the (implicit) read() below.
573      * If the requests aren't pipelined, then the client is still waiting
574      * for the final buffer flush from us, and we will block in the implicit
575      * read().  B_SAFEREAD ensures that the BUFF layer flushes if it will
576      * have to block during a read.
577      */
578
579     do {
580         apr_status_t rv;
581
582         /* insure ap_rgetline allocates memory each time thru the loop
583          * if there are empty lines
584          */
585         r->the_request = NULL;
586         rv = ap_rgetline(&(r->the_request), (apr_size_t)(r->server->limit_req_line + 2),
587                          &len, r, 0, bb);
588
589         if (rv != APR_SUCCESS) {
590             r->request_time = apr_time_now();
591
592             /* ap_rgetline returns APR_ENOSPC if it fills up the
593              * buffer before finding the end-of-line.  This is only going to
594              * happen if it exceeds the configured limit for a request-line.
595              */
596             if (rv == APR_ENOSPC) {
597                 r->status    = HTTP_REQUEST_URI_TOO_LARGE;
598                 r->proto_num = HTTP_VERSION(1,0);
599                 r->protocol  = apr_pstrdup(r->pool, "HTTP/1.0");
600             }
601
602             return 0;
603         }
604     } while ((len <= 0) && (++num_blank_lines < max_blank_lines));
605
606     /* we've probably got something to do, ignore graceful restart requests */
607
608     r->request_time = apr_time_now();
609     ll = r->the_request;
610     r->method = ap_getword_white(r->pool, &ll);
611
612 #if 0
613 /* XXX If we want to keep track of the Method, the protocol module should do
614  * it.  That support isn't in the scoreboard yet.  Hopefully next week
615  * sometime.   rbb */
616     ap_update_connection_status(AP_CHILD_THREAD_FROM_ID(conn->id), "Method",
617                                 r->method);
618 #endif
619
620     uri = ap_getword_white(r->pool, &ll);
621
622     /* Provide quick information about the request method as soon as known */
623
624     r->method_number = ap_method_number_of(r->method);
625     if (r->method_number == M_GET && r->method[0] == 'H') {
626         r->header_only = 1;
627     }
628
629     ap_parse_uri(r, uri);
630
631     if (ll[0]) {
632         r->assbackwards = 0;
633         pro = ll;
634         len = strlen(ll);
635     } else {
636         r->assbackwards = 1;
637         pro = "HTTP/0.9";
638         len = 8;
639     }
640     r->protocol = apr_pstrmemdup(r->pool, pro, len);
641
642     /* XXX ap_update_connection_status(conn->id, "Protocol", r->protocol); */
643
644     /* Avoid sscanf in the common case */
645     if (len == 8
646         && pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' && pro[3] == 'P'
647         && pro[4] == '/' && apr_isdigit(pro[5]) && pro[6] == '.'
648         && apr_isdigit(pro[7])) {
649         r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0');
650     }
651     else if (3 == sscanf(r->protocol, "%4s/%u.%u", http, &major, &minor)
652              && (strcasecmp("http", http) == 0)
653              && (minor < HTTP_VERSION(1, 0)) ) /* don't allow HTTP/0.1000 */
654         r->proto_num = HTTP_VERSION(major, minor);
655     else
656         r->proto_num = HTTP_VERSION(1, 0);
657
658     return 1;
659 }
660
661 AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb)
662 {
663     char *last_field = NULL;
664     apr_size_t last_len = 0;
665     apr_size_t alloc_len = 0;
666     char *field;
667     char *value;
668     apr_size_t len;
669     int fields_read = 0;
670     char *tmp_field;
671
672     /*
673      * Read header lines until we get the empty separator line, a read error,
674      * the connection closes (EOF), reach the server limit, or we timeout.
675      */
676     while(1) {
677         apr_status_t rv;
678         int folded = 0;
679
680         field = NULL;
681         rv = ap_rgetline(&field, r->server->limit_req_fieldsize + 2,
682                          &len, r, 0, bb);
683
684         /* ap_rgetline returns APR_ENOSPC if it fills up the buffer before
685          * finding the end-of-line.  This is only going to happen if it
686          * exceeds the configured limit for a field size.
687          */
688         if (rv == APR_ENOSPC && field) {
689             r->status = HTTP_BAD_REQUEST;
690             /* insure ap_escape_html will terminate correctly */
691             field[len - 1] = '\0';
692             apr_table_setn(r->notes, "error-notes",
693                            apr_pstrcat(r->pool,
694                                        "Size of a request header field "
695                                        "exceeds server limit.<br />\n"
696                                        "<pre>\n",
697                                        ap_escape_html(r->pool, field),
698                                        "</pre>\n", NULL));
699             return;
700         }
701
702         if (rv != APR_SUCCESS) {
703             r->status = HTTP_BAD_REQUEST;
704             return;
705         }
706
707         if (last_field != NULL) {
708             if ((len > 0) && ((*field == '\t') || *field == ' ')) {
709                 /* This line is a continuation of the preceding line(s),
710                  * so append it to the line that we've set aside.
711                  * Note: this uses a power-of-two allocator to avoid
712                  * doing O(n) allocs and using O(n^2) space for
713                  * continuations that span many many lines.
714                  */
715                 apr_size_t fold_len = last_len + len + 1; /* trailing null */
716
717                 if ((fold_len - 1) > r->server->limit_req_fieldsize) {
718                     r->status = HTTP_BAD_REQUEST;
719                     /* report what we have accumulated so far before the
720                      * overflow (last_field) as the field with the problem
721                      */
722                     apr_table_setn(r->notes, "error-notes",
723                                    apr_pstrcat(r->pool,
724                                                "Size of a request header field " 
725                                                "after folding "
726                                                "exceeds server limit.<br />\n"
727                                                "<pre>\n",
728                                                ap_escape_html(r->pool, last_field),
729                                                "</pre>\n", NULL));
730                     return;
731                 }
732
733                 if (fold_len > alloc_len) {
734                     char *fold_buf;
735                     alloc_len += alloc_len;
736                     if (fold_len > alloc_len) {
737                         alloc_len = fold_len;
738                     }
739                     fold_buf = (char *)apr_palloc(r->pool, alloc_len);
740                     memcpy(fold_buf, last_field, last_len);
741                     last_field = fold_buf;
742                 }
743                 memcpy(last_field + last_len, field, len +1); /* +1 for nul */
744                 last_len += len;
745                 folded = 1;
746             }
747             else /* not a continuation line */ {
748
749                 if (r->server->limit_req_fields
750                     && (++fields_read > r->server->limit_req_fields)) {
751                     r->status = HTTP_BAD_REQUEST;
752                     apr_table_setn(r->notes, "error-notes",
753                                    "The number of request header fields "
754                                    "exceeds this server's limit.");
755                     return;
756                 }
757
758                 if (!(value = strchr(last_field, ':'))) { /* Find ':' or    */
759                     r->status = HTTP_BAD_REQUEST;      /* abort bad request */
760                     apr_table_setn(r->notes, "error-notes",
761                                    apr_pstrcat(r->pool,
762                                                "Request header field is "
763                                                "missing ':' separator.<br />\n"
764                                                "<pre>\n",
765                                                ap_escape_html(r->pool,
766                                                               last_field),
767                                                "</pre>\n", NULL));
768                     return;
769                 }
770                 
771                 tmp_field = value - 1; /* last character of field-name */
772
773                 *value++ = '\0'; /* NUL-terminate at colon */
774
775                 while (*value == ' ' || *value == '\t') {
776                     ++value;            /* Skip to start of value   */
777                 }
778
779                 /* Strip LWS after field-name: */
780                 while (tmp_field > last_field 
781                        && (*tmp_field == ' ' || *tmp_field == '\t')) {
782                     *tmp_field-- = '\0';
783                 }
784                 
785                 /* Strip LWS after field-value: */
786                 tmp_field = last_field + last_len - 1;
787                 while (tmp_field > value
788                        && (*tmp_field == ' ' || *tmp_field == '\t')) {
789                     *tmp_field-- = '\0';
790                 }
791
792                 apr_table_addn(r->headers_in, last_field, value);
793                 
794                 /* reset the alloc_len so that we'll allocate a new
795                  * buffer if we have to do any more folding: we can't
796                  * use the previous buffer because its contents are
797                  * now part of r->headers_in
798                  */
799                 alloc_len = 0;
800
801             } /* end if current line is not a continuation starting with tab */
802         }
803
804         /* Found a blank line, stop. */
805         if (len == 0) {
806             break;
807         }
808
809         /* Keep track of this line so that we can parse it on
810          * the next loop iteration.  (In the folded case, last_field
811          * has been updated already.)
812          */
813         if (!folded) {
814             last_field = field;
815             last_len = len;
816         }
817     }
818
819     apr_table_compress(r->headers_in, APR_OVERLAP_TABLES_MERGE);
820 }
821
822 AP_DECLARE(void) ap_get_mime_headers(request_rec *r)
823 {
824     apr_bucket_brigade *tmp_bb;
825     tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
826     ap_get_mime_headers_core(r, tmp_bb);
827     apr_brigade_destroy(tmp_bb);
828 }
829
830 request_rec *ap_read_request(conn_rec *conn)
831 {
832     request_rec *r;
833     apr_pool_t *p;
834     const char *expect;
835     int access_status;
836     apr_bucket_brigade *tmp_bb;
837
838     apr_pool_create(&p, conn->pool);
839     apr_pool_tag(p, "request");
840     r = apr_pcalloc(p, sizeof(request_rec));
841     r->pool            = p;
842     r->connection      = conn;
843     r->server          = conn->base_server;
844
845     r->user            = NULL;
846     r->ap_auth_type    = NULL;
847
848     r->allowed_methods = ap_make_method_list(p, 2);
849
850     r->headers_in      = apr_table_make(r->pool, 25);
851     r->subprocess_env  = apr_table_make(r->pool, 25);
852     r->headers_out     = apr_table_make(r->pool, 12);
853     r->err_headers_out = apr_table_make(r->pool, 5);
854     r->notes           = apr_table_make(r->pool, 5);
855
856     r->request_config  = ap_create_request_config(r->pool);
857     /* Must be set before we run create request hook */
858
859     r->proto_output_filters = conn->output_filters;
860     r->output_filters  = r->proto_output_filters;
861     r->proto_input_filters = conn->input_filters;
862     r->input_filters   = r->proto_input_filters;
863     ap_run_create_request(r);
864     r->per_dir_config  = r->server->lookup_defaults;
865
866     r->sent_bodyct     = 0;                      /* bytect isn't for body */
867
868     r->read_length     = 0;
869     r->read_body       = REQUEST_NO_BODY;
870
871     r->status          = HTTP_REQUEST_TIME_OUT;  /* Until we get a request */
872     r->the_request     = NULL;
873
874     tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
875
876     /* Get the request... */
877     if (!read_request_line(r, tmp_bb)) {
878         if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
879             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
880                           "request failed: URI too long (longer than %d)", r->server->limit_req_line);
881             ap_send_error_response(r, 0);
882             ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
883             ap_run_log_transaction(r);
884             apr_brigade_destroy(tmp_bb);
885             return r;
886         }
887
888         apr_brigade_destroy(tmp_bb);
889         return NULL;
890     }
891
892     if (!r->assbackwards) {
893         ap_get_mime_headers_core(r, tmp_bb);
894         if (r->status != HTTP_REQUEST_TIME_OUT) {
895             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
896                           "request failed: error reading the headers");
897             ap_send_error_response(r, 0);
898             ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
899             ap_run_log_transaction(r);
900             apr_brigade_destroy(tmp_bb);
901             return r;
902         }
903
904         if (apr_table_get(r->headers_in, "Transfer-Encoding")
905             && apr_table_get(r->headers_in, "Content-Length")) {
906             /* 2616 section 4.4, point 3: "if both Transfer-Encoding
907              * and Content-Length are received, the latter MUST be
908              * ignored"; so unset it here to prevent any confusion
909              * later. */
910             apr_table_unset(r->headers_in, "Content-Length");
911         }
912     }
913     else {
914         if (r->header_only) {
915             /*
916              * Client asked for headers only with HTTP/0.9, which doesn't send
917              * headers! Have to dink things just to make sure the error message
918              * comes through...
919              */
920             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
921                           "client sent invalid HTTP/0.9 request: HEAD %s",
922                           r->uri);
923             r->header_only = 0;
924             r->status = HTTP_BAD_REQUEST;
925             ap_send_error_response(r, 0);
926             ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
927             ap_run_log_transaction(r);
928             apr_brigade_destroy(tmp_bb);
929             return r;
930         }
931     }
932
933     apr_brigade_destroy(tmp_bb);
934
935     r->status = HTTP_OK;                         /* Until further notice. */
936
937     /* update what we think the virtual host is based on the headers we've
938      * now read. may update status.
939      */
940     ap_update_vhost_from_headers(r);
941
942     /* we may have switched to another server */
943     r->per_dir_config = r->server->lookup_defaults;
944
945     if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1, 1)))
946         || ((r->proto_num == HTTP_VERSION(1, 1))
947             && !apr_table_get(r->headers_in, "Host"))) {
948         /*
949          * Client sent us an HTTP/1.1 or later request without telling us the
950          * hostname, either with a full URL or a Host: header. We therefore
951          * need to (as per the 1.1 spec) send an error.  As a special case,
952          * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain
953          * a Host: header, and the server MUST respond with 400 if it doesn't.
954          */
955         r->status = HTTP_BAD_REQUEST;
956         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
957                       "client sent HTTP/1.1 request without hostname "
958                       "(see RFC2616 section 14.23): %s", r->uri);
959     }
960
961     if (r->status != HTTP_OK) {
962         ap_send_error_response(r, 0);
963         ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
964         ap_run_log_transaction(r);
965         return r;
966     }
967
968     if (((expect = apr_table_get(r->headers_in, "Expect")) != NULL)
969         && (expect[0] != '\0')) {
970         /*
971          * The Expect header field was added to HTTP/1.1 after RFC 2068
972          * as a means to signal when a 100 response is desired and,
973          * unfortunately, to signal a poor man's mandatory extension that
974          * the server must understand or return 417 Expectation Failed.
975          */
976         if (strcasecmp(expect, "100-continue") == 0) {
977             r->expecting_100 = 1;
978         }
979         else {
980             r->status = HTTP_EXPECTATION_FAILED;
981             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
982                           "client sent an unrecognized expectation value of "
983                           "Expect: %s", expect);
984             ap_send_error_response(r, 0);
985             ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
986             ap_run_log_transaction(r);
987             return r;
988         }
989     }
990
991     ap_add_input_filter_handle(ap_http_input_filter_handle,
992                                NULL, r, r->connection);
993
994     if ((access_status = ap_run_post_read_request(r))) {
995         ap_die(access_status, r);
996         ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
997         ap_run_log_transaction(r);
998         return NULL;
999     }
1000
1001     return r;
1002 }
1003
1004 /*
1005  * A couple of other functions which initialize some of the fields of
1006  * a request structure, as appropriate for adjuncts of one kind or another
1007  * to a request in progress.  Best here, rather than elsewhere, since
1008  * *someone* has to set the protocol-specific fields...
1009  */
1010
1011 AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew,
1012                                          const request_rec *r)
1013 {
1014     rnew->the_request     = r->the_request;  /* Keep original request-line */
1015
1016     rnew->assbackwards    = 1;   /* Don't send headers from this. */
1017     rnew->no_local_copy   = 1;   /* Don't try to send HTTP_NOT_MODIFIED for a
1018                                   * fragment. */
1019     rnew->method          = "GET";
1020     rnew->method_number   = M_GET;
1021     rnew->protocol        = "INCLUDED";
1022
1023     rnew->status          = HTTP_OK;
1024
1025     rnew->headers_in      = apr_table_copy(rnew->pool, r->headers_in);
1026     rnew->subprocess_env  = apr_table_copy(rnew->pool, r->subprocess_env);
1027     rnew->headers_out     = apr_table_make(rnew->pool, 5);
1028     rnew->err_headers_out = apr_table_make(rnew->pool, 5);
1029     rnew->notes           = apr_table_make(rnew->pool, 5);
1030
1031     rnew->expecting_100   = r->expecting_100;
1032     rnew->read_length     = r->read_length;
1033     rnew->read_body       = REQUEST_NO_BODY;
1034
1035     rnew->main = (request_rec *) r;
1036 }
1037
1038 static void end_output_stream(request_rec *r)
1039 {
1040     conn_rec *c = r->connection;
1041     apr_bucket_brigade *bb;
1042     apr_bucket *b;
1043
1044     bb = apr_brigade_create(r->pool, c->bucket_alloc);
1045     b = apr_bucket_eos_create(c->bucket_alloc);
1046     APR_BRIGADE_INSERT_TAIL(bb, b);
1047     ap_pass_brigade(r->output_filters, bb);
1048 }
1049
1050 AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub)
1051 {
1052     /* tell the filter chain there is no more content coming */
1053     if (!sub->eos_sent) {
1054         end_output_stream(sub);
1055     }
1056 }
1057
1058 /* finalize_request_protocol is called at completion of sending the
1059  * response.  Its sole purpose is to send the terminating protocol
1060  * information for any wrappers around the response message body
1061  * (i.e., transfer encodings).  It should have been named finalize_response.
1062  */
1063 AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r)
1064 {
1065     (void) ap_discard_request_body(r);
1066
1067     /* tell the filter chain there is no more content coming */
1068     if (!r->eos_sent) {
1069         end_output_stream(r);
1070     }
1071 }
1072
1073 /*
1074  * Support for the Basic authentication protocol, and a bit for Digest.
1075  */
1076 AP_DECLARE(void) ap_note_auth_failure(request_rec *r)
1077 {
1078     const char *type = ap_auth_type(r);
1079     if (type) {
1080         if (!strcasecmp(type, "Basic"))
1081             ap_note_basic_auth_failure(r);
1082         else if (!strcasecmp(type, "Digest"))
1083             ap_note_digest_auth_failure(r);
1084     }
1085     else {
1086         ap_log_rerror(APLOG_MARK, APLOG_ERR,
1087                       0, r, "need AuthType to note auth failure: %s", r->uri);
1088     }
1089 }
1090
1091 AP_DECLARE(void) ap_note_basic_auth_failure(request_rec *r)
1092 {
1093     const char *type = ap_auth_type(r);
1094
1095     /* if there is no AuthType configure or it is something other than
1096      * Basic, let ap_note_auth_failure() deal with it
1097      */
1098     if (!type || strcasecmp(type, "Basic"))
1099         ap_note_auth_failure(r);
1100     else
1101         apr_table_setn(r->err_headers_out,
1102                        (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
1103                                                        : "WWW-Authenticate",
1104                        apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r),
1105                                    "\"", NULL));
1106 }
1107
1108 AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r)
1109 {
1110     apr_table_setn(r->err_headers_out,
1111                    (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
1112                                                    : "WWW-Authenticate",
1113                    /* need APR_TIME_T_FMT_HEX */
1114                    apr_psprintf(r->pool, "Digest realm=\"%s\", nonce=\"%llx\"",
1115                                 ap_auth_name(r), r->request_time));
1116 }
1117
1118 AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw)
1119 {
1120     const char *auth_line = apr_table_get(r->headers_in,
1121                                           (PROXYREQ_PROXY == r->proxyreq)
1122                                               ? "Proxy-Authorization"
1123                                               : "Authorization");
1124     const char *t;
1125
1126     if (!(t = ap_auth_type(r)) || strcasecmp(t, "Basic"))
1127         return DECLINED;
1128
1129     if (!ap_auth_name(r)) {
1130         ap_log_rerror(APLOG_MARK, APLOG_ERR,
1131                       0, r, "need AuthName: %s", r->uri);
1132         return HTTP_INTERNAL_SERVER_ERROR;
1133     }
1134
1135     if (!auth_line) {
1136         ap_note_basic_auth_failure(r);
1137         return HTTP_UNAUTHORIZED;
1138     }
1139
1140     if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
1141         /* Client tried to authenticate using wrong auth scheme */
1142         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1143                       "client used wrong authentication scheme: %s", r->uri);
1144         ap_note_basic_auth_failure(r);
1145         return HTTP_UNAUTHORIZED;
1146     }
1147
1148     while (*auth_line == ' ' || *auth_line == '\t') {
1149         auth_line++;
1150     }
1151
1152     t = ap_pbase64decode(r->pool, auth_line);
1153     r->user = ap_getword_nulls (r->pool, &t, ':');
1154     r->ap_auth_type = "Basic";
1155
1156     *pw = t;
1157
1158     return OK;
1159 }
1160
1161 struct content_length_ctx {
1162     int data_sent;  /* true if the C-L filter has already sent at
1163                      * least one bucket on to the next output filter
1164                      * for this request
1165                      */
1166 };
1167
1168 /* This filter computes the content length, but it also computes the number
1169  * of bytes sent to the client.  This means that this filter will always run
1170  * through all of the buckets in all brigades
1171  */
1172 AP_CORE_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(
1173     ap_filter_t *f,
1174     apr_bucket_brigade *b)
1175 {
1176     request_rec *r = f->r;
1177     struct content_length_ctx *ctx;
1178     apr_bucket *e;
1179     int eos = 0;
1180     apr_read_type_e eblock = APR_NONBLOCK_READ;
1181
1182     ctx = f->ctx;
1183     if (!ctx) {
1184         f->ctx = ctx = apr_palloc(r->pool, sizeof(*ctx));
1185         ctx->data_sent = 0;
1186     }
1187
1188     /* Loop through this set of buckets to compute their length
1189      */
1190     e = APR_BRIGADE_FIRST(b);
1191     while (e != APR_BRIGADE_SENTINEL(b)) {
1192         if (APR_BUCKET_IS_EOS(e)) {
1193             eos = 1;
1194             break;
1195         }
1196         if (e->length == (apr_size_t)-1) {
1197             apr_size_t len;
1198             const char *ignored;
1199             apr_status_t rv;
1200
1201             /* This is probably a pipe bucket.  Send everything
1202              * prior to this, and then read the data for this bucket.
1203              */
1204             rv = apr_bucket_read(e, &ignored, &len, eblock);
1205             if (rv == APR_SUCCESS) {
1206                 /* Attempt a nonblocking read next time through */
1207                 eblock = APR_NONBLOCK_READ;
1208                 r->bytes_sent += len;
1209             }
1210             else if (APR_STATUS_IS_EAGAIN(rv)) {
1211                 /* Output everything prior to this bucket, and then
1212                  * do a blocking read on the next batch.
1213                  */
1214                 if (e != APR_BRIGADE_FIRST(b)) {
1215                     apr_bucket_brigade *split = apr_brigade_split(b, e);
1216                     apr_bucket *flush = apr_bucket_flush_create(r->connection->bucket_alloc);
1217
1218                     APR_BRIGADE_INSERT_TAIL(b, flush);
1219                     rv = ap_pass_brigade(f->next, b);
1220                     if (rv != APR_SUCCESS || f->c->aborted) {
1221                         apr_brigade_destroy(split);
1222                         return rv;
1223                     }
1224                     b = split;
1225                     e = APR_BRIGADE_FIRST(b);
1226
1227                     ctx->data_sent = 1;
1228                 }
1229                 eblock = APR_BLOCK_READ;
1230                 continue;
1231             }
1232             else {
1233                 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
1234                               "ap_content_length_filter: "
1235                               "apr_bucket_read() failed");
1236                 return rv;
1237             }
1238         }
1239         else {
1240             r->bytes_sent += e->length;
1241         }
1242         e = APR_BUCKET_NEXT(e);
1243     }
1244
1245     /* If we've now seen the entire response and it's otherwise
1246      * okay to set the C-L in the response header, then do so now.
1247      *
1248      * We can only set a C-L in the response header if we haven't already
1249      * sent any buckets on to the next output filter for this request.
1250      */
1251     if (ctx->data_sent == 0 && eos &&
1252         /* don't whack the C-L if it has already been set for a HEAD
1253          * by something like proxy.  the brigade only has an EOS bucket
1254          * in this case, making r->bytes_sent zero.
1255          *
1256          * if r->bytes_sent > 0 we have a (temporary) body whose length may 
1257          * have been changed by a filter.  the C-L header might not have been 
1258          * updated so we do it here.  long term it would be cleaner to have 
1259          * such filters update or remove the C-L header, and just use it 
1260          * if present.
1261          */
1262         !(r->header_only && r->bytes_sent == 0 &&   
1263             apr_table_get(r->headers_out, "Content-Length"))) {
1264         ap_set_content_length(r, r->bytes_sent);
1265     }
1266
1267     ctx->data_sent = 1;
1268     return ap_pass_brigade(f->next, b);
1269 }
1270
1271 /*
1272  * Send the body of a response to the client.
1273  */
1274 AP_DECLARE(apr_status_t) ap_send_fd(apr_file_t *fd, request_rec *r,
1275                                     apr_off_t offset, apr_size_t len,
1276                                     apr_size_t *nbytes)
1277 {
1278     conn_rec *c = r->connection;
1279     apr_bucket_brigade *bb = NULL;
1280     apr_bucket *b;
1281     apr_status_t rv;
1282
1283     bb = apr_brigade_create(r->pool, c->bucket_alloc);
1284     b = apr_bucket_file_create(fd, offset, len, r->pool, c->bucket_alloc);
1285     APR_BRIGADE_INSERT_TAIL(bb, b);
1286
1287     rv = ap_pass_brigade(r->output_filters, bb);
1288     if (rv != APR_SUCCESS) {
1289         *nbytes = 0; /* no way to tell how many were actually sent */
1290     }
1291     else {
1292         *nbytes = len;
1293     }
1294
1295     return rv;
1296 }
1297
1298 #if APR_HAS_MMAP
1299 /* send data from an in-memory buffer */
1300 AP_DECLARE(size_t) ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset,
1301                                 size_t length)
1302 {
1303     conn_rec *c = r->connection;
1304     apr_bucket_brigade *bb = NULL;
1305     apr_bucket *b;
1306
1307     bb = apr_brigade_create(r->pool, c->bucket_alloc);
1308     b = apr_bucket_mmap_create(mm, offset, length, c->bucket_alloc);
1309     APR_BRIGADE_INSERT_TAIL(bb, b);
1310     ap_pass_brigade(r->output_filters, bb);
1311
1312     return mm->size; /* XXX - change API to report apr_status_t? */
1313 }
1314 #endif /* APR_HAS_MMAP */
1315
1316 typedef struct {
1317     apr_bucket_brigade *bb;
1318 } old_write_filter_ctx;
1319
1320 AP_CORE_DECLARE_NONSTD(apr_status_t) ap_old_write_filter(
1321     ap_filter_t *f, apr_bucket_brigade *bb)
1322 {
1323     old_write_filter_ctx *ctx = f->ctx;
1324
1325     AP_DEBUG_ASSERT(ctx);
1326
1327     if (ctx->bb != 0) {
1328         /* whatever is coming down the pipe (we don't care), we
1329          * can simply insert our buffered data at the front and
1330          * pass the whole bundle down the chain.
1331          */
1332         APR_BRIGADE_CONCAT(ctx->bb, bb);
1333         bb = ctx->bb;
1334         ctx->bb = NULL;
1335     }
1336
1337     return ap_pass_brigade(f->next, bb);
1338 }
1339
1340 static apr_status_t buffer_output(request_rec *r,
1341                                   const char *str, apr_size_t len)
1342 {
1343     conn_rec *c = r->connection;
1344     ap_filter_t *f;
1345     old_write_filter_ctx *ctx;
1346
1347     if (len == 0)
1348         return APR_SUCCESS;
1349
1350     /* future optimization: record some flags in the request_rec to
1351      * say whether we've added our filter, and whether it is first.
1352      */
1353
1354     /* this will typically exit on the first test */
1355     for (f = r->output_filters; f != NULL; f = f->next) {
1356         if (ap_old_write_func == f->frec)
1357             break;
1358     }
1359
1360     if (f == NULL) {
1361         /* our filter hasn't been added yet */
1362         ctx = apr_pcalloc(r->pool, sizeof(*ctx));
1363         ap_add_output_filter("OLD_WRITE", ctx, r, r->connection);
1364         f = r->output_filters;
1365     }
1366
1367     /* if the first filter is not our buffering filter, then we have to
1368      * deliver the content through the normal filter chain
1369      */
1370     if (f != r->output_filters) {
1371         apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc);
1372         apr_bucket *b = apr_bucket_transient_create(str, len, c->bucket_alloc);
1373         APR_BRIGADE_INSERT_TAIL(bb, b);
1374
1375         return ap_pass_brigade(r->output_filters, bb);
1376     }
1377
1378     /* grab the context from our filter */
1379     ctx = r->output_filters->ctx;
1380
1381     if (ctx->bb == NULL) {
1382         ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc);
1383     }
1384
1385     return ap_fwrite(f->next, ctx->bb, str, len);
1386 }
1387
1388 AP_DECLARE(int) ap_rputc(int c, request_rec *r)
1389 {
1390     char c2 = (char)c;
1391
1392     if (r->connection->aborted) {
1393         return -1;
1394     }
1395
1396     if (buffer_output(r, &c2, 1) != APR_SUCCESS)
1397         return -1;
1398
1399     return c;
1400 }
1401
1402 AP_DECLARE(int) ap_rputs(const char *str, request_rec *r)
1403 {
1404     apr_size_t len;
1405
1406     if (r->connection->aborted)
1407         return -1;
1408
1409     if (buffer_output(r, str, len = strlen(str)) != APR_SUCCESS)
1410         return -1;
1411
1412     return len;
1413 }
1414
1415 AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
1416 {
1417     if (r->connection->aborted)
1418         return -1;
1419
1420     if (buffer_output(r, buf, nbyte) != APR_SUCCESS)
1421         return -1;
1422
1423     return nbyte;
1424 }
1425
1426 struct ap_vrprintf_data {
1427     apr_vformatter_buff_t vbuff;
1428     request_rec *r;
1429     char *buff;
1430 };
1431
1432 static apr_status_t r_flush(apr_vformatter_buff_t *buff)
1433 {
1434     /* callback function passed to ap_vformatter to be called when
1435      * vformatter needs to write into buff and buff.curpos > buff.endpos */
1436
1437     /* ap_vrprintf_data passed as a apr_vformatter_buff_t, which is then
1438      * "downcast" to an ap_vrprintf_data */
1439     struct ap_vrprintf_data *vd = (struct ap_vrprintf_data*)buff;
1440
1441     if (vd->r->connection->aborted)
1442         return -1;
1443
1444     /* r_flush is called when vbuff is completely full */
1445     if (buffer_output(vd->r, vd->buff, AP_IOBUFSIZE)) {
1446         return -1;
1447     }
1448
1449     /* reset the buffer position */
1450     vd->vbuff.curpos = vd->buff;
1451     vd->vbuff.endpos = vd->buff + AP_IOBUFSIZE;
1452
1453     return APR_SUCCESS;
1454 }
1455
1456 AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
1457 {
1458     apr_size_t written;
1459     struct ap_vrprintf_data vd;
1460     char vrprintf_buf[AP_IOBUFSIZE];
1461
1462     vd.vbuff.curpos = vrprintf_buf;
1463     vd.vbuff.endpos = vrprintf_buf + AP_IOBUFSIZE;
1464     vd.r = r;
1465     vd.buff = vrprintf_buf;
1466
1467     if (r->connection->aborted)
1468         return -1;
1469
1470     written = apr_vformatter(r_flush, &vd.vbuff, fmt, va);
1471
1472     /* tack on null terminator on remaining string */
1473     *(vd.vbuff.curpos) = '\0';
1474
1475     if (written != -1) {
1476         int n = vd.vbuff.curpos - vrprintf_buf;
1477
1478         /* last call to buffer_output, to finish clearing the buffer */
1479         if (buffer_output(r, vrprintf_buf,n) != APR_SUCCESS)
1480             return -1;
1481
1482         written += n;
1483     }
1484
1485     return written;
1486 }
1487
1488 AP_DECLARE_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt, ...)
1489 {
1490     va_list va;
1491     int n;
1492
1493     if (r->connection->aborted)
1494         return -1;
1495
1496     va_start(va, fmt);
1497     n = ap_vrprintf(r, fmt, va);
1498     va_end(va);
1499
1500     return n;
1501 }
1502
1503 AP_DECLARE_NONSTD(int) ap_rvputs(request_rec *r, ...)
1504 {
1505     va_list va;
1506     const char *s;
1507     apr_size_t len;
1508     apr_size_t written = 0;
1509
1510     if (r->connection->aborted)
1511         return -1;
1512
1513     /* ### TODO: if the total output is large, put all the strings
1514      * ### into a single brigade, rather than flushing each time we
1515      * ### fill the buffer
1516      */
1517     va_start(va, r);
1518     while (1) {
1519         s = va_arg(va, const char *);
1520         if (s == NULL)
1521             break;
1522
1523         len = strlen(s);
1524         if (buffer_output(r, s, len) != APR_SUCCESS) {
1525             return -1;
1526         }
1527
1528         written += len;
1529     }
1530     va_end(va);
1531
1532     return written;
1533 }
1534
1535 AP_DECLARE(int) ap_rflush(request_rec *r)
1536 {
1537     conn_rec *c = r->connection;
1538     apr_bucket_brigade *bb;
1539     apr_bucket *b;
1540
1541     bb = apr_brigade_create(r->pool, c->bucket_alloc);
1542     b = apr_bucket_flush_create(c->bucket_alloc);
1543     APR_BRIGADE_INSERT_TAIL(bb, b);
1544     if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS)
1545         return -1;
1546
1547     return 0;
1548 }
1549
1550 /*
1551  * This function sets the Last-Modified output header field to the value
1552  * of the mtime field in the request structure - rationalized to keep it from
1553  * being in the future.
1554  */
1555 AP_DECLARE(void) ap_set_last_modified(request_rec *r)
1556 {
1557     if (!r->assbackwards) {
1558         apr_time_t mod_time = ap_rationalize_mtime(r, r->mtime);
1559         char *datestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
1560
1561         apr_rfc822_date(datestr, mod_time);
1562         apr_table_setn(r->headers_out, "Last-Modified", datestr);
1563     }
1564 }
1565
1566 AP_IMPLEMENT_HOOK_RUN_ALL(int,post_read_request,
1567                           (request_rec *r), (r), OK, DECLINED)
1568 AP_IMPLEMENT_HOOK_RUN_ALL(int,log_transaction,
1569                           (request_rec *r), (r), OK, DECLINED)
1570 AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,http_method,
1571                             (const request_rec *r), (r), NULL)
1572 AP_IMPLEMENT_HOOK_RUN_FIRST(unsigned short,default_port,
1573                             (const request_rec *r), (r), 0)