~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to server/protocol.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

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