]> granicus.if.org Git - apache/blob - server/protocol.c
Don't overwrite r->the_request. This was causing us to never get the
[apache] / server / protocol.c
1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  *    if any, must include the following acknowledgment:
21  *       "This product includes software developed by the
22  *        Apache Software Foundation (http://www.apache.org/)."
23  *    Alternately, this acknowledgment may appear in the software itself,
24  *    if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Apache" and "Apache Software Foundation" must
27  *    not be used to endorse or promote products derived from this
28  *    software without prior written permission. For written
29  *    permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache",
32  *    nor may "Apache" appear in their name, without prior written
33  *    permission of the Apache Software Foundation.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation.  For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  *
54  * Portions of this software are based upon public domain software
55  * originally written at the National Center for Supercomputing Applications,
56  * University of Illinois, Urbana-Champaign.
57  */
58
59 /*
60  * http_protocol.c --- routines which directly communicate with the client.
61  *
62  * Code originally by Rob McCool; much redone by Robert S. Thau
63  * and the Apache Software Foundation.
64  */
65
66 #include "apr.h"
67 #include "apr_strings.h"
68 #include "apr_buckets.h"
69 #include "apr_lib.h"
70 #include "apr_signal.h"
71
72 #define APR_WANT_STDIO          /* for sscanf */
73 #define APR_WANT_STRFUNC
74 #define APR_WANT_MEMFUNC
75 #include "apr_want.h"
76
77 #define CORE_PRIVATE
78 #include "util_filter.h"
79 #include "ap_config.h"
80 #include "httpd.h"
81 #include "http_config.h"
82 #include "http_core.h"
83 #include "http_protocol.h"
84 #include "http_main.h"
85 #include "http_request.h"
86 #include "http_vhost.h"
87 #include "http_log.h"           /* For errors detected in basic auth common
88                                  * support code... */
89 #include "util_date.h"          /* For parseHTTPdate and BAD_DATE */
90 #include "util_charset.h"
91 #include "util_ebcdic.h"
92
93 #if APR_HAVE_STDARG_H
94 #include <stdarg.h>
95 #endif
96 #if APR_HAVE_UNISTD_H
97 #include <unistd.h>
98 #endif
99
100
101 APR_HOOK_STRUCT(
102             APR_HOOK_LINK(post_read_request)
103             APR_HOOK_LINK(log_transaction)
104             APR_HOOK_LINK(http_method)
105             APR_HOOK_LINK(default_port)
106 )
107
108 /*
109  * Builds the content-type that should be sent to the client from the
110  * content-type specified.  The following rules are followed:
111  *    - if type is NULL, type is set to ap_default_type(r)
112  *    - if charset adding is disabled, stop processing and return type.
113  *    - then, if there are no parameters on type, add the default charset
114  *    - return type
115  */
116 AP_DECLARE(const char *)ap_make_content_type(request_rec *r, const char *type)
117 {
118     static const char *needcset[] = {
119         "text/plain",
120         "text/html",
121         NULL };
122     const char **pcset;
123     core_dir_config *conf =
124         (core_dir_config *)ap_get_module_config(r->per_dir_config,
125                                                 &core_module);
126
127     if (!type) {
128         type = ap_default_type(r);
129     }
130     if (conf->add_default_charset != ADD_DEFAULT_CHARSET_ON) {
131         return type;
132     }
133
134     if (ap_strcasestr(type, "charset=") != NULL) {
135         /* already has parameter, do nothing */
136         /* XXX we don't check the validity */
137         ;
138     }
139     else {
140         /* see if it makes sense to add the charset. At present,
141          * we only add it if the Content-type is one of needcset[]
142          */
143         for (pcset = needcset; *pcset ; pcset++) {
144             if (ap_strcasestr(type, *pcset) != NULL) {
145                 type = apr_pstrcat(r->pool, type, "; charset=", 
146                                    conf->add_default_charset_name, NULL);
147                 break;
148             }
149         }
150     }
151     return type;
152 }
153
154 AP_DECLARE(void) ap_set_content_length(request_rec *r, apr_off_t clength)
155 {
156     r->clength = clength;
157     apr_table_setn(r->headers_out, "Content-Length",
158                    apr_psprintf(r->pool, "%" APR_OFF_T_FMT, clength));
159 }
160
161 /*
162  * Return the latest rational time from a request/mtime (modification time)
163  * pair.  We return the mtime unless it's in the future, in which case we
164  * return the current time.  We use the request time as a reference in order
165  * to limit the number of calls to time().  We don't check for futurosity
166  * unless the mtime is at least as new as the reference.
167  */
168 AP_DECLARE(apr_time_t) ap_rationalize_mtime(request_rec *r, apr_time_t mtime)
169 {
170     apr_time_t now;
171
172     /* For all static responses, it's almost certain that the file was
173      * last modified before the beginning of the request.  So there's
174      * no reason to call time(NULL) again.  But if the response has been
175      * created on demand, then it might be newer than the time the request
176      * started.  In this event we really have to call time(NULL) again
177      * so that we can give the clients the most accurate Last-Modified.  If we
178      * were given a time in the future, we return the current time - the
179      * Last-Modified can't be in the future.
180      */
181     now = (mtime < r->request_time) ? r->request_time : apr_time_now();
182     return (mtime > now) ? now : mtime;
183 }
184
185 /* Get a line of protocol input, including any continuation lines
186  * caused by MIME folding (or broken clients) if fold != 0, and place it
187  * in the buffer s, of size n bytes, without the ending newline.
188  *
189  * Returns -1 on error, or the length of s.  
190  *
191  * Notes: Because the buffer uses 1 char for NUL, the most we can return is 
192  *        (n - 1) actual characters.  
193  *
194  *        If no LF is detected on the last line due to a dropped connection 
195  *        or a full buffer, that's considered an error.
196  */
197 AP_CORE_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold)
198 {
199     char *pos = s;
200     char *last_char;
201     char *beyond_buff = s + n;
202     const char *temp;
203     int retval;
204     int total = 0;
205     int looking_ahead = 0;
206     apr_size_t length;
207     conn_rec *c = r->connection;
208     core_request_config *req_cfg;
209     apr_bucket_brigade *b;
210     apr_bucket *e;
211
212     req_cfg = (core_request_config *)
213                 ap_get_module_config(r->request_config, &core_module);
214     b = req_cfg->bb;
215     /* make sure it's empty unless we're folding */ 
216     AP_DEBUG_ASSERT(fold || APR_BRIGADE_EMPTY(b));
217
218     while (1) {
219         if (APR_BRIGADE_EMPTY(b)) {
220             if ((retval = ap_get_brigade(c->input_filters, b, AP_MODE_BLOCKING)) != APR_SUCCESS ||
221                 APR_BRIGADE_EMPTY(b)) {
222                 apr_brigade_destroy(b);
223                 return -1;
224             }
225         }
226         e = APR_BRIGADE_FIRST(b); 
227         if (e->length == 0) {
228             apr_bucket_delete(e);
229             continue;
230         }
231         retval = apr_bucket_read(e, &temp, &length, APR_BLOCK_READ);
232         if (retval != APR_SUCCESS) {
233             apr_brigade_destroy(b);
234             ap_log_rerror(APLOG_MARK, APLOG_ERR, retval, r, "apr_bucket_read() failed");
235             if (total) {
236                 break; /* report previously-read data to caller, do ap_xlate_proto_to_ascii() */
237             }
238             else {
239                 return -1;
240             }
241         }
242
243         if ((looking_ahead) && (*temp != APR_ASCII_BLANK) && (*temp != APR_ASCII_TAB)) { 
244             /* can't fold because next line isn't indented, 
245              * so return what we have.  lookahead brigade is 
246              * stashed on req_cfg->bb
247              */
248             AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(req_cfg->bb));
249             break;
250         }
251         last_char = pos + length - 1;
252         if (last_char < beyond_buff) {
253             memcpy(pos, temp, length);
254             apr_bucket_delete(e);
255         }
256         else {
257             /* input line was larger than the caller's buffer */
258             apr_brigade_destroy(b); 
259
260             /* don't need to worry about req_cfg->bb being bogus.
261              * the request is about to die, and ErrorDocument
262              * redirects get a new req_cfg->bb
263              */
264
265             return -1;
266         }
267         
268         pos = last_char;        /* Point at the last character           */
269
270         if (*pos == APR_ASCII_LF) { /* Did we get a full line of input?      */
271                 
272             if (pos > s && *(pos - 1) == APR_ASCII_CR) {
273                 --pos;          /* zap optional CR before LF             */
274             }
275                 
276             /*
277              * Trim any extra trailing spaces or tabs except for the first
278              * space or tab at the beginning of a blank string.  This makes
279              * it much easier to check field values for exact matches, and
280              * saves memory as well.  Terminate string at end of line.
281              */
282             while (pos > (s + 1) && 
283                    (*(pos - 1) == APR_ASCII_BLANK || *(pos - 1) == APR_ASCII_TAB)) {
284                 --pos;          /* trim extra trailing spaces or tabs    */
285             }
286             *pos = '\0';        /* zap end of string                     */
287             total = pos - s;    /* update total string length            */
288
289             /* look ahead another line if line folding is desired 
290              * and this line isn't empty
291              */
292             if (fold && total) {
293                 looking_ahead = 1;
294             }
295             else {
296                 AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(req_cfg->bb));
297                 break;
298             }
299         }
300         else {
301             /* no LF yet...character mode client (telnet)...keep going
302              * bump past last character read,   
303              * and set total in case we bail before finding a LF   
304              */
305             total = ++pos - s;    
306             looking_ahead = 0;  /* only appropriate right after LF       */ 
307         }
308     }
309     ap_xlate_proto_from_ascii(s, total);
310     return total;
311 }
312
313 /* parse_uri: break apart the uri
314  * Side Effects:
315  * - sets r->args to rest after '?' (or NULL if no '?')
316  * - sets r->uri to request uri (without r->args part)
317  * - sets r->hostname (if not set already) from request (scheme://host:port)
318  */
319 AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri)
320 {
321     int status = HTTP_OK;
322
323     r->unparsed_uri = apr_pstrdup(r->pool, uri);
324
325     if (r->method_number == M_CONNECT) {
326         status = ap_parse_hostinfo_components(r->pool, uri, &r->parsed_uri);
327     }
328     else {
329         /* Simple syntax Errors in URLs are trapped by parse_uri_components(). */
330         status = ap_parse_uri_components(r->pool, uri, &r->parsed_uri);
331     }
332
333     if (ap_is_HTTP_SUCCESS(status)) {
334         /* if it has a scheme we may need to do absoluteURI vhost stuff */
335         if (r->parsed_uri.scheme
336             && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r))) {
337             r->hostname = r->parsed_uri.hostname;
338         }
339         else if (r->method_number == M_CONNECT) {
340             r->hostname = r->parsed_uri.hostname;
341         }
342         r->args = r->parsed_uri.query;
343         r->uri = r->parsed_uri.path ? r->parsed_uri.path
344                                     : apr_pstrdup(r->pool, "/");
345 #if defined(OS2) || defined(WIN32)
346         /* Handle path translations for OS/2 and plug security hole.
347          * This will prevent "http://www.wherever.com/..\..\/" from
348          * returning a directory for the root drive.
349          */
350         {
351             char *x;
352
353             for (x = r->uri; (x = strchr(x, '\\')) != NULL; )
354                 *x = '/';
355         }
356 #endif  /* OS2 || WIN32 */
357     }
358     else {
359         r->args = NULL;
360         r->hostname = NULL;
361         r->status = status;             /* set error status */
362         r->uri = apr_pstrdup(r->pool, uri);
363     }
364 }
365
366 static void get_mime_headers(request_rec *r)
367 {
368     char field[DEFAULT_LIMIT_REQUEST_FIELDSIZE + 2]; /* getline's two extra */
369     char *value;
370     char *copy;
371     int len;
372     int fields_read = 0;
373     apr_table_t *tmp_headers;
374
375     /* We'll use apr_table_overlap later to merge these into r->headers_in. */
376     tmp_headers = apr_table_make(r->pool, 50);
377
378     /*
379      * Read header lines until we get the empty separator line, a read error,
380      * the connection closes (EOF), reach the server limit, or we timeout.
381      */
382     while ((len = ap_getline(field, sizeof(field), r, 1)) > 0) {
383
384         if (r->server->limit_req_fields &&
385             (++fields_read > r->server->limit_req_fields)) {
386             r->status = HTTP_BAD_REQUEST;
387             apr_table_setn(r->notes, "error-notes",
388                            "The number of request header fields exceeds "
389                            "this server's limit.<P>\n");
390             return;
391         }
392         /* ap_getline returns (size of max buffer - 1) if it fills up the
393          * buffer before finding the end-of-line.  This is only going to
394          * happen if it exceeds the configured limit for a field size.
395          */
396         if (len > r->server->limit_req_fieldsize) {
397             r->status = HTTP_BAD_REQUEST;
398             apr_table_setn(r->notes, "error-notes",
399                            apr_pstrcat(r->pool,
400                                        "Size of a request header field "
401                                        "exceeds server limit.<P>\n"
402                                        "<PRE>\n",
403                                        ap_escape_html(r->pool, field),
404                                        "</PRE>\n", NULL));
405             return;
406         }
407         copy = apr_palloc(r->pool, len + 1);
408         memcpy(copy, field, len + 1);
409
410         if (!(value = strchr(copy, ':'))) {     /* Find the colon separator */
411             r->status = HTTP_BAD_REQUEST;       /* or abort the bad request */
412             apr_table_setn(r->notes, "error-notes",
413                            apr_pstrcat(r->pool,
414                                        "Request header field is missing "
415                                        "colon separator.<P>\n"
416                                        "<PRE>\n",
417                                        ap_escape_html(r->pool, copy),
418                                        "</PRE>\n", NULL));
419             return;
420         }
421
422         *value = '\0';
423         ++value;
424         while (*value == ' ' || *value == '\t') {
425             ++value;            /* Skip to start of value   */
426         }
427
428         apr_table_addn(tmp_headers, copy, value);
429     }
430
431     apr_table_overlap(r->headers_in, tmp_headers, APR_OVERLAP_TABLES_MERGE);
432 }
433
434 request_rec *ap_read_request(conn_rec *conn)
435 {
436     request_rec *r;
437     apr_pool_t *p;
438     const char *expect;
439     int access_status;
440
441     AP_DEBUG_ASSERT(conn->remain == 0);
442
443     apr_pool_create(&p, conn->pool);
444     r = apr_pcalloc(p, sizeof(request_rec));
445     r->pool            = p;
446     r->connection      = conn;
447     r->server          = conn->base_server;
448
449     r->user            = NULL;
450     r->ap_auth_type    = NULL;
451
452     r->allowed_methods = ap_make_method_list(p, 2);
453
454     r->headers_in      = apr_table_make(r->pool, 50);
455     r->subprocess_env  = apr_table_make(r->pool, 50);
456     r->headers_out     = apr_table_make(r->pool, 12);
457     r->err_headers_out = apr_table_make(r->pool, 5);
458     r->notes           = apr_table_make(r->pool, 5);
459
460     r->request_config  = ap_create_request_config(r->pool);
461     if (ap_run_create_request(r) != OK) {
462         return NULL;
463     }
464     r->per_dir_config  = r->server->lookup_defaults;
465
466     r->sent_bodyct     = 0;                      /* bytect isn't for body */
467
468     r->read_length     = 0;
469     r->read_body       = REQUEST_NO_BODY;
470
471     r->status          = HTTP_REQUEST_TIME_OUT;  /* Until we get a request */
472     r->output_filters  = conn->output_filters;
473     r->input_filters   = conn->input_filters;
474
475     ap_add_output_filter("BYTERANGE", NULL, r, r->connection);
476     ap_add_output_filter("CONTENT_LENGTH", NULL, r, r->connection);
477     ap_add_output_filter("HTTP_HEADER", NULL, r, r->connection);
478
479     if (!r->assbackwards) {
480         get_mime_headers(r);
481         if (r->status != HTTP_REQUEST_TIME_OUT) {
482             ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
483                           "request failed: error reading the headers");
484             ap_send_error_response(r, 0);
485             ap_run_log_transaction(r);
486             return r;
487         }
488     }
489     else {
490         if (r->header_only) {
491             /*
492              * Client asked for headers only with HTTP/0.9, which doesn't send
493              * headers! Have to dink things just to make sure the error message
494              * comes through...
495              */
496             ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
497                           "client sent invalid HTTP/0.9 request: HEAD %s",
498                           r->uri);
499             r->header_only = 0;
500             r->status = HTTP_BAD_REQUEST;
501             ap_send_error_response(r, 0);
502             ap_run_log_transaction(r);
503             return r;
504         }
505     }
506
507     r->status = HTTP_OK;                         /* Until further notice. */
508
509     /* update what we think the virtual host is based on the headers we've
510      * now read. may update status.
511      */
512     ap_update_vhost_from_headers(r);
513
514     /* we may have switched to another server */
515     r->per_dir_config = r->server->lookup_defaults;
516
517     if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1,1))) ||
518         ((r->proto_num == HTTP_VERSION(1,1)) &&
519          !apr_table_get(r->headers_in, "Host"))) {
520         /*
521          * Client sent us an HTTP/1.1 or later request without telling us the
522          * hostname, either with a full URL or a Host: header. We therefore
523          * need to (as per the 1.1 spec) send an error.  As a special case,
524          * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain
525          * a Host: header, and the server MUST respond with 400 if it doesn't.
526          */
527         r->status = HTTP_BAD_REQUEST;
528         ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
529                       "client sent HTTP/1.1 request without hostname "
530                       "(see RFC2616 section 14.23): %s", r->uri);
531     }
532     if (r->status != HTTP_OK) {
533         ap_send_error_response(r, 0);
534         ap_run_log_transaction(r);
535         return r;
536     }
537     if (((expect = apr_table_get(r->headers_in, "Expect")) != NULL) &&
538         (expect[0] != '\0')) {
539         /*
540          * The Expect header field was added to HTTP/1.1 after RFC 2068
541          * as a means to signal when a 100 response is desired and,
542          * unfortunately, to signal a poor man's mandatory extension that
543          * the server must understand or return 417 Expectation Failed.
544          */
545         if (strcasecmp(expect, "100-continue") == 0) {
546             r->expecting_100 = 1;
547         }
548         else {
549             r->status = HTTP_EXPECTATION_FAILED;
550             ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r,
551                           "client sent an unrecognized expectation value of "
552                           "Expect: %s", expect);
553             ap_send_error_response(r, 0);
554             (void) ap_discard_request_body(r);
555             ap_run_log_transaction(r);
556             return r;
557         }
558     }
559
560     if ((access_status = ap_run_post_read_request(r))) {
561         ap_die(access_status, r);
562         ap_run_log_transaction(r);
563         return NULL;
564     }
565
566     return r;
567 }
568
569 /*
570  * A couple of other functions which initialize some of the fields of
571  * a request structure, as appropriate for adjuncts of one kind or another
572  * to a request in progress.  Best here, rather than elsewhere, since
573  * *someone* has to set the protocol-specific fields...
574  */
575
576 void ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r)
577 {
578     rnew->the_request     = r->the_request;  /* Keep original request-line */
579
580     rnew->assbackwards    = 1;   /* Don't send headers from this. */
581     rnew->no_local_copy   = 1;   /* Don't try to send HTTP_NOT_MODIFIED for a
582                                   * fragment. */
583     rnew->method          = "GET";
584     rnew->method_number   = M_GET;
585     rnew->protocol        = "INCLUDED";
586
587     rnew->status          = HTTP_OK;
588
589     rnew->headers_in      = r->headers_in;
590     rnew->subprocess_env  = apr_table_copy(rnew->pool, r->subprocess_env);
591     rnew->headers_out     = apr_table_make(rnew->pool, 5);
592     rnew->err_headers_out = apr_table_make(rnew->pool, 5);
593     rnew->notes           = apr_table_make(rnew->pool, 5);
594
595     rnew->expecting_100   = r->expecting_100;
596     rnew->read_length     = r->read_length;
597     rnew->read_body       = REQUEST_NO_BODY;
598
599     rnew->main = (request_rec *) r;
600 }
601
602 static void end_output_stream(request_rec *r)
603 {
604     apr_bucket_brigade *bb;
605     apr_bucket *b;
606
607     bb = apr_brigade_create(r->pool);
608     b = apr_bucket_eos_create();
609     APR_BRIGADE_INSERT_TAIL(bb, b);
610     ap_pass_brigade(r->output_filters, bb);
611 }
612
613 void ap_finalize_sub_req_protocol(request_rec *sub)
614 {
615     end_output_stream(sub); 
616 }
617
618 /* finalize_request_protocol is called at completion of sending the
619  * response.  Its sole purpose is to send the terminating protocol
620  * information for any wrappers around the response message body
621  * (i.e., transfer encodings).  It should have been named finalize_response.
622  */
623 AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r)
624 {
625     while (r->next) {
626         r = r->next;
627     }
628     /* tell the filter chain there is no more content coming */
629     if (!r->eos_sent) {
630         end_output_stream(r);
631     }
632
633
634 /*
635  * Support for the Basic authentication protocol, and a bit for Digest.
636  */
637
638 AP_DECLARE(void) ap_note_auth_failure(request_rec *r)
639 {
640     if (!strcasecmp(ap_auth_type(r), "Basic"))
641         ap_note_basic_auth_failure(r);
642     else if (!strcasecmp(ap_auth_type(r), "Digest"))
643         ap_note_digest_auth_failure(r);
644 }
645
646 AP_DECLARE(void) ap_note_basic_auth_failure(request_rec *r)
647 {
648     if (strcasecmp(ap_auth_type(r), "Basic"))
649         ap_note_auth_failure(r);
650     else
651         apr_table_setn(r->err_headers_out,
652                   (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" : "WWW-Authenticate",
653                   apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), "\"",
654                           NULL));
655 }
656
657 AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r)
658 {
659     apr_table_setn(r->err_headers_out,
660             (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" : "WWW-Authenticate",
661             apr_psprintf(r->pool, "Digest realm=\"%s\", nonce=\"%llx\"",
662                 ap_auth_name(r), r->request_time));
663 }
664
665 AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw)
666 {
667     const char *auth_line = apr_table_get(r->headers_in,
668                                       (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authorization"
669                                                   : "Authorization");
670     const char *t;
671
672     if (!(t = ap_auth_type(r)) || strcasecmp(t, "Basic"))
673         return DECLINED;
674
675     if (!ap_auth_name(r)) {
676         ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,
677                       0, r, "need AuthName: %s", r->uri);
678         return HTTP_INTERNAL_SERVER_ERROR;
679     }
680
681     if (!auth_line) {
682         ap_note_basic_auth_failure(r);
683         return HTTP_UNAUTHORIZED;
684     }
685
686     if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
687         /* Client tried to authenticate using wrong auth scheme */
688         ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
689                       "client used wrong authentication scheme: %s", r->uri);
690         ap_note_basic_auth_failure(r);
691         return HTTP_UNAUTHORIZED;
692     }
693
694     while (*auth_line== ' ' || *auth_line== '\t') {
695         auth_line++;
696     }
697
698     t = ap_pbase64decode(r->pool, auth_line);
699     /* Note that this allocation has to be made from r->connection->pool
700      * because it has the lifetime of the connection.  The other allocations
701      * are temporary and can be tossed away any time.
702      */
703     r->user = ap_getword_nulls (r->pool, &t, ':');
704     r->ap_auth_type = "Basic";
705
706     *pw = t;
707
708     return OK;
709 }
710
711 struct content_length_ctx {
712     apr_bucket_brigade *saved;
713     int compute_len;
714     apr_size_t curr_len;
715 };
716
717 /* This filter computes the content length, but it also computes the number
718  * of bytes sent to the client.  This means that this filter will always run
719  * through all of the buckets in all brigades 
720  */
721 AP_CORE_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(ap_filter_t *f,
722                                                               apr_bucket_brigade *b)
723 {
724     request_rec *r = f->r;
725     struct content_length_ctx *ctx;
726     apr_status_t rv;
727     apr_bucket *e;
728     int send_it = 0;
729
730     ctx = f->ctx;
731     if (!ctx) { /* first time through */
732         f->ctx = ctx = apr_pcalloc(r->pool, sizeof(struct content_length_ctx));
733     }
734
735     APR_BRIGADE_FOREACH(e, b) {
736         const char *ignored;
737         apr_size_t length;
738
739         if (APR_BUCKET_IS_EOS(e) || APR_BUCKET_IS_FLUSH(e)) {
740             send_it = 1;
741         }
742         if (e->length == -1) { /* if length unknown */
743             rv = apr_bucket_read(e, &ignored, &length, APR_BLOCK_READ);
744             if (rv != APR_SUCCESS) {
745                 return rv;
746             }
747         }
748         else {
749             length = e->length;
750         }
751         ctx->curr_len += length;
752         r->bytes_sent += length;
753     }
754
755     if ((ctx->curr_len < AP_MIN_BYTES_TO_WRITE) && !send_it) {
756         return ap_save_brigade(f, &ctx->saved, &b);
757     }
758
759     /* We will compute a content length if:
760      *     The protocol is < 1.1
761      * and We can not chunk
762      * and this is a keepalive request.
763      * or  We already have all the data
764      *         This is a bit confusing, because we will always buffer up
765      *         to AP_MIN_BYTES_TO_WRITE, so if we get all the data while
766      *         we are buffering that much data, we set the c-l.
767      */
768     if ((r->proto_num < HTTP_VERSION(1,1)
769         && (!ap_find_last_token(f->r->pool,
770                                apr_table_get(r->headers_out,
771                                              "Transfer-Encoding"),
772                                "chunked")
773         && (f->r->connection->keepalive)))
774         || (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(b)))) {
775         ctx->compute_len = 1;
776     }
777     else {
778         ctx->compute_len = 0;
779     }
780
781     if (ctx->compute_len) {
782         /* save the brigade; we can't pass any data to the next
783          * filter until we have the entire content length
784          */
785         if (!send_it) {
786             ap_save_brigade(f, &ctx->saved, &b);
787             return APR_SUCCESS;
788         }
789         ap_set_content_length(r, r->bytes_sent);
790     }
791     if (ctx->saved) {
792         APR_BRIGADE_CONCAT(ctx->saved, b);
793         apr_brigade_destroy(b);
794         b = ctx->saved;
795         ctx->saved = NULL;
796     }
797
798     ctx->curr_len = 0;
799     return ap_pass_brigade(f->next, b);
800 }
801
802 /*
803  * Send the body of a response to the client.
804  */
805 AP_DECLARE(apr_status_t) ap_send_fd(apr_file_t *fd, request_rec *r, apr_off_t offset, 
806                                     apr_size_t len, apr_size_t *nbytes) 
807 {
808     apr_bucket_brigade *bb = NULL;
809     apr_bucket *b;
810     apr_status_t rv;
811
812     bb = apr_brigade_create(r->pool);
813     b = apr_bucket_file_create(fd, offset, len);
814     APR_BRIGADE_INSERT_TAIL(bb, b);
815
816     rv = ap_pass_brigade(r->output_filters, bb);
817     if (rv != APR_SUCCESS) {
818         *nbytes = 0; /* no way to tell how many were actually sent */
819     }
820     else {
821         *nbytes = len;
822     }
823
824     return rv;
825 }
826
827 #if APR_HAS_MMAP
828 /* send data from an in-memory buffer */
829 AP_DECLARE(size_t) ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset,
830                              size_t length)
831 {
832     apr_bucket_brigade *bb = NULL;
833     apr_bucket *b;
834
835     bb = apr_brigade_create(r->pool);
836     b = apr_bucket_mmap_create(mm, offset, length);
837     APR_BRIGADE_INSERT_TAIL(bb, b);
838     ap_pass_brigade(r->output_filters, bb);
839
840     return mm->size; /* XXX - change API to report apr_status_t? */
841 }
842 #endif /* APR_HAS_MMAP */
843
844 typedef struct {
845     apr_bucket_brigade *bb;
846 } old_write_filter_ctx;
847
848 AP_CORE_DECLARE_NONSTD(apr_status_t) ap_old_write_filter(
849     ap_filter_t *f, apr_bucket_brigade *bb)
850 {
851     old_write_filter_ctx *ctx = f->ctx;
852
853     AP_DEBUG_ASSERT(ctx);
854
855     if (ctx->bb != 0) {
856         /* whatever is coming down the pipe (we don't care), we
857          * can simply insert our buffered data at the front and
858          * pass the whole bundle down the chain. 
859          */
860         APR_BRIGADE_CONCAT(ctx->bb, bb);
861     }
862
863     return ap_pass_brigade(f->next, ctx->bb);
864 }
865
866 static apr_status_t buffer_output(request_rec *r,
867                                   const char *str, apr_size_t len)
868 {
869     ap_filter_t *f;
870     old_write_filter_ctx *ctx;
871
872     if (len == 0)
873         return APR_SUCCESS;
874
875     /* future optimization: record some flags in the request_rec to
876      * say whether we've added our filter, and whether it is first.
877      */
878
879     /* this will typically exit on the first test */
880     for (f = r->output_filters; f != NULL; f = f->next)
881         if (strcmp("OLD_WRITE", f->frec->name) == 0)
882             break;
883     if (f == NULL) {
884         /* our filter hasn't been added yet */
885         ctx = apr_pcalloc(r->pool, sizeof(*ctx));
886         ap_add_output_filter("OLD_WRITE", ctx, r, r->connection);
887         f = r->output_filters;
888     }
889
890     /* if the first filter is not our buffering filter, then we have to
891      * deliver the content through the normal filter chain */
892     if (f != r->output_filters) {
893         apr_bucket_brigade *bb = apr_brigade_create(r->pool);
894         apr_bucket *b = apr_bucket_transient_create(str, len);
895         APR_BRIGADE_INSERT_TAIL(bb, b);
896
897         return ap_pass_brigade(r->output_filters, bb);
898     }
899
900     /* grab the context from our filter */
901     ctx = r->output_filters->ctx;
902
903     if (ctx->bb == NULL) {
904         ctx->bb = apr_brigade_create(r->pool);
905     }
906
907     ap_fwrite(f->next, ctx->bb, str, len);
908
909     return APR_SUCCESS;
910 }
911
912 AP_DECLARE(int) ap_rputc(int c, request_rec *r)
913 {
914     char c2 = (char)c;
915
916     if (r->connection->aborted) {
917         return -1;
918     }
919
920     if (buffer_output(r, &c2, 1) != APR_SUCCESS)
921         return -1;
922
923     return c;
924 }
925
926 AP_DECLARE(int) ap_rputs(const char *str, request_rec *r)
927 {
928     apr_size_t len;
929
930     if (r->connection->aborted)
931         return -1;
932
933     if (buffer_output(r, str, len = strlen(str)) != APR_SUCCESS)
934         return -1;
935
936     return len;
937 }
938
939 AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
940 {
941     if (r->connection->aborted)
942         return -1;
943
944     if (buffer_output(r, buf, nbyte) != APR_SUCCESS)
945         return -1;
946
947     return nbyte;
948 }
949
950 AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
951 {
952     char buf[4096];
953     apr_size_t written;
954
955     if (r->connection->aborted)
956         return -1;
957
958     /* ### fix this mechanism to allow more than 4K of output */
959     written = apr_vsnprintf(buf, sizeof(buf), fmt, va);
960     if (buffer_output(r, buf, written) != APR_SUCCESS)
961         return -1;
962
963     return written;
964 }
965
966 AP_DECLARE_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt, ...)
967 {
968     va_list va;
969     int n;
970
971     if (r->connection->aborted)
972         return -1;
973
974     va_start(va, fmt);
975     n = ap_vrprintf(r, fmt, va);
976     va_end(va);
977
978     return n;
979 }
980
981 AP_DECLARE_NONSTD(int) ap_rvputs(request_rec *r, ...)
982 {
983     va_list va;
984     const char *s;
985     apr_size_t len;
986     apr_size_t written = 0;
987
988     if (r->connection->aborted)
989         return -1;
990
991     /* ### TODO: if the total output is large, put all the strings
992        ### into a single brigade, rather than flushing each time we
993        ### fill the buffer */
994     va_start(va, r);
995     while (1) {
996         s = va_arg(va, const char *);
997         if (s == NULL)
998             break;
999
1000         len = strlen(s);
1001         if (buffer_output(r, s, len) != APR_SUCCESS) {
1002             return -1;
1003         }
1004
1005         written += len;
1006     }
1007     va_end(va);
1008
1009     return written;
1010 }
1011
1012 AP_DECLARE(int) ap_rflush(request_rec *r)
1013 {
1014     apr_bucket_brigade *bb;
1015     apr_bucket *b;
1016
1017     bb = apr_brigade_create(r->pool);
1018     b = apr_bucket_flush_create();
1019     APR_BRIGADE_INSERT_TAIL(bb, b);
1020     if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS)
1021         return -1;
1022     return 0;
1023 }
1024
1025 /*
1026  * This function sets the Last-Modified output header field to the value
1027  * of the mtime field in the request structure - rationalized to keep it from
1028  * being in the future.
1029  */
1030 AP_DECLARE(void) ap_set_last_modified(request_rec *r)
1031 {
1032     apr_time_t mod_time = ap_rationalize_mtime(r, r->mtime);
1033     char *datestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
1034     apr_rfc822_date(datestr, mod_time);
1035     apr_table_setn(r->headers_out, "Last-Modified", datestr);
1036 }
1037
1038 AP_IMPLEMENT_HOOK_RUN_ALL(int,post_read_request,
1039                           (request_rec *r),(r),OK,DECLINED)
1040 AP_IMPLEMENT_HOOK_RUN_ALL(int,log_transaction,
1041                           (request_rec *r),(r),OK,DECLINED)
1042 AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,http_method,
1043                             (const request_rec *r),(r),NULL)
1044 AP_IMPLEMENT_HOOK_RUN_FIRST(unsigned short,default_port,
1045                             (const request_rec *r),(r),0)