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