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

« back to all changes in this revision

Viewing changes to modules/http/http_filters.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_filter.c --- HTTP routines which either filters or deal with filters.
 
19
 */
 
20
 
 
21
#include "apr.h"
 
22
#include "apr_strings.h"
 
23
#include "apr_buckets.h"
 
24
#include "apr_lib.h"
 
25
#include "apr_signal.h"
 
26
 
 
27
#define APR_WANT_STDIO          /* for sscanf */
 
28
#define APR_WANT_STRFUNC
 
29
#define APR_WANT_MEMFUNC
 
30
#include "apr_want.h"
 
31
 
 
32
#define CORE_PRIVATE
 
33
#include "util_filter.h"
 
34
#include "ap_config.h"
 
35
#include "httpd.h"
 
36
#include "http_config.h"
 
37
#include "http_core.h"
 
38
#include "http_protocol.h"
 
39
#include "http_main.h"
 
40
#include "http_request.h"
 
41
#include "http_vhost.h"
 
42
#include "http_log.h"           /* For errors detected in basic auth common
 
43
                                 * support code... */
 
44
#include "apr_date.h"           /* For apr_date_parse_http and APR_DATE_BAD */
 
45
#include "util_charset.h"
 
46
#include "util_ebcdic.h"
 
47
#include "util_time.h"
 
48
 
 
49
#include "mod_core.h"
 
50
 
 
51
#if APR_HAVE_STDARG_H
 
52
#include <stdarg.h>
 
53
#endif
 
54
#if APR_HAVE_UNISTD_H
 
55
#include <unistd.h>
 
56
#endif
 
57
 
 
58
static long get_chunk_size(char *);
 
59
 
 
60
typedef struct http_filter_ctx {
 
61
    apr_off_t remaining;
 
62
    apr_off_t limit;
 
63
    apr_off_t limit_used;
 
64
    enum {
 
65
        BODY_NONE,
 
66
        BODY_LENGTH,
 
67
        BODY_CHUNK
 
68
    } state;
 
69
    int eos_sent;
 
70
} http_ctx_t;
 
71
 
 
72
/* This is the HTTP_INPUT filter for HTTP requests and responses from
 
73
 * proxied servers (mod_proxy).  It handles chunked and content-length
 
74
 * bodies.  This can only be inserted/used after the headers
 
75
 * are successfully parsed.
 
76
 */
 
77
apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
 
78
                            ap_input_mode_t mode, apr_read_type_e block,
 
79
                            apr_off_t readbytes)
 
80
{
 
81
    apr_bucket *e;
 
82
    http_ctx_t *ctx = f->ctx;
 
83
    apr_status_t rv;
 
84
    apr_off_t totalread;
 
85
 
 
86
    /* just get out of the way of things we don't want. */
 
87
    if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
 
88
        return ap_get_brigade(f->next, b, mode, block, readbytes);
 
89
    }
 
90
 
 
91
    if (!ctx) {
 
92
        const char *tenc, *lenp;
 
93
        f->ctx = ctx = apr_palloc(f->r->pool, sizeof(*ctx));
 
94
        ctx->state = BODY_NONE;
 
95
        ctx->remaining = 0;
 
96
        ctx->limit_used = 0;
 
97
        ctx->eos_sent = 0;
 
98
 
 
99
        /* LimitRequestBody does not apply to proxied responses.
 
100
         * Consider implementing this check in its own filter.
 
101
         * Would adding a directive to limit the size of proxied
 
102
         * responses be useful?
 
103
         */
 
104
        if (!f->r->proxyreq) {
 
105
            ctx->limit = ap_get_limit_req_body(f->r);
 
106
        }
 
107
        else {
 
108
            ctx->limit = 0;
 
109
        }
 
110
 
 
111
        tenc = apr_table_get(f->r->headers_in, "Transfer-Encoding");
 
112
        lenp = apr_table_get(f->r->headers_in, "Content-Length");
 
113
 
 
114
        if (tenc) {
 
115
            if (!strcasecmp(tenc, "chunked")) {
 
116
                ctx->state = BODY_CHUNK;
 
117
            }
 
118
        }
 
119
        else if (lenp) {
 
120
            char *endstr;
 
121
 
 
122
            ctx->state = BODY_LENGTH;
 
123
            errno = 0;
 
124
 
 
125
            /* Protects against over/underflow, non-digit chars in the
 
126
             * string (excluding leading space) (the endstr checks)
 
127
             * and a negative number. */
 
128
            if (apr_strtoff(&ctx->remaining, lenp, &endstr, 10)
 
129
                || endstr == lenp || *endstr || ctx->remaining < 0) {
 
130
                apr_bucket_brigade *bb;
 
131
 
 
132
                ctx->remaining = 0;
 
133
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
 
134
                              "Invalid Content-Length");
 
135
 
 
136
                bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
 
137
                e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
 
138
                                           f->r->pool, f->c->bucket_alloc);
 
139
                APR_BRIGADE_INSERT_TAIL(bb, e);
 
140
                e = apr_bucket_eos_create(f->c->bucket_alloc);
 
141
                APR_BRIGADE_INSERT_TAIL(bb, e);
 
142
                ctx->eos_sent = 1;
 
143
                return ap_pass_brigade(f->r->output_filters, bb);
 
144
            }
 
145
 
 
146
            /* If we have a limit in effect and we know the C-L ahead of
 
147
             * time, stop it here if it is invalid.
 
148
             */
 
149
            if (ctx->limit && ctx->limit < ctx->remaining) {
 
150
                apr_bucket_brigade *bb;
 
151
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
 
152
                          "Requested content-length of %" APR_OFF_T_FMT
 
153
                          " is larger than the configured limit"
 
154
                          " of %" APR_OFF_T_FMT, ctx->remaining, ctx->limit);
 
155
                bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
 
156
                e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
 
157
                                           f->r->pool, f->c->bucket_alloc);
 
158
                APR_BRIGADE_INSERT_TAIL(bb, e);
 
159
                e = apr_bucket_eos_create(f->c->bucket_alloc);
 
160
                APR_BRIGADE_INSERT_TAIL(bb, e);
 
161
                ctx->eos_sent = 1;
 
162
                return ap_pass_brigade(f->r->output_filters, bb);
 
163
            }
 
164
        }
 
165
 
 
166
        /* If we don't have a request entity indicated by the headers, EOS.
 
167
         * (BODY_NONE is a valid intermediate state due to trailers,
 
168
         *  but it isn't a valid starting state.)
 
169
         *
 
170
         * RFC 2616 Section 4.4 note 5 states that connection-close
 
171
         * is invalid for a request entity - request bodies must be
 
172
         * denoted by C-L or T-E: chunked.
 
173
         *
 
174
         * Note that since the proxy uses this filter to handle the
 
175
         * proxied *response*, proxy responses MUST be exempt.
 
176
         */
 
177
        if (ctx->state == BODY_NONE && f->r->proxyreq != PROXYREQ_RESPONSE) {
 
178
            e = apr_bucket_eos_create(f->c->bucket_alloc);
 
179
            APR_BRIGADE_INSERT_TAIL(b, e);
 
180
            ctx->eos_sent = 1;
 
181
            return APR_SUCCESS;
 
182
        }
 
183
 
 
184
        /* Since we're about to read data, send 100-Continue if needed.
 
185
         * Only valid on chunked and C-L bodies where the C-L is > 0. */
 
186
        if ((ctx->state == BODY_CHUNK ||
 
187
            (ctx->state == BODY_LENGTH && ctx->remaining > 0)) &&
 
188
            f->r->expecting_100 && f->r->proto_num >= HTTP_VERSION(1,1)) {
 
189
            char *tmp;
 
190
            apr_bucket_brigade *bb;
 
191
 
 
192
            tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL, " ",
 
193
                              ap_get_status_line(100), CRLF CRLF, NULL);
 
194
            bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
 
195
            e = apr_bucket_pool_create(tmp, strlen(tmp), f->r->pool,
 
196
                                       f->c->bucket_alloc);
 
197
            APR_BRIGADE_INSERT_HEAD(bb, e);
 
198
            e = apr_bucket_flush_create(f->c->bucket_alloc);
 
199
            APR_BRIGADE_INSERT_TAIL(bb, e);
 
200
 
 
201
            ap_pass_brigade(f->c->output_filters, bb);
 
202
        }
 
203
 
 
204
        /* We can't read the chunk until after sending 100 if required. */
 
205
        if (ctx->state == BODY_CHUNK) {
 
206
            char line[30];
 
207
            apr_bucket_brigade *bb;
 
208
            apr_size_t len = 30;
 
209
            apr_off_t brigade_length;
 
210
 
 
211
            bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
 
212
 
 
213
            rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
 
214
                                APR_BLOCK_READ, 0);
 
215
 
 
216
            if (rv == APR_SUCCESS) {
 
217
                /* We have to check the length of the brigade we got back.
 
218
                 * We will not accept partial or blank lines.
 
219
                 */
 
220
                rv = apr_brigade_length(bb, 1, &brigade_length);
 
221
                if (rv == APR_SUCCESS
 
222
                    && (!brigade_length ||
 
223
                        brigade_length > f->r->server->limit_req_line)) {
 
224
                    rv = APR_ENOSPC;
 
225
                }
 
226
                if (rv == APR_SUCCESS) {
 
227
                    rv = apr_brigade_flatten(bb, line, &len);
 
228
                    if (rv == APR_SUCCESS) {
 
229
                        ctx->remaining = get_chunk_size(line);
 
230
                    }
 
231
                }
 
232
            }
 
233
            apr_brigade_cleanup(bb);
 
234
 
 
235
            /* Detect chunksize error (such as overflow) */
 
236
            if (rv != APR_SUCCESS || ctx->remaining < 0) {
 
237
                ctx->remaining = 0; /* Reset it in case we have to
 
238
                                     * come back here later */
 
239
                e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
 
240
                                           f->r->pool,
 
241
                                           f->c->bucket_alloc);
 
242
                APR_BRIGADE_INSERT_TAIL(bb, e);
 
243
                e = apr_bucket_eos_create(f->c->bucket_alloc);
 
244
                APR_BRIGADE_INSERT_TAIL(bb, e);
 
245
                ctx->eos_sent = 1;
 
246
                return ap_pass_brigade(f->r->output_filters, bb);
 
247
            }
 
248
 
 
249
            if (!ctx->remaining) {
 
250
                /* Handle trailers by calling ap_get_mime_headers again! */
 
251
                ctx->state = BODY_NONE;
 
252
                ap_get_mime_headers(f->r);
 
253
                e = apr_bucket_eos_create(f->c->bucket_alloc);
 
254
                APR_BRIGADE_INSERT_TAIL(b, e);
 
255
                ctx->eos_sent = 1;
 
256
                return APR_SUCCESS;
 
257
            }
 
258
        }
 
259
    }
 
260
 
 
261
    if (ctx->eos_sent) {
 
262
        e = apr_bucket_eos_create(f->c->bucket_alloc);
 
263
        APR_BRIGADE_INSERT_TAIL(b, e);
 
264
        return APR_SUCCESS;
 
265
    }
 
266
 
 
267
    if (!ctx->remaining) {
 
268
        switch (ctx->state) {
 
269
        case BODY_NONE:
 
270
            break;
 
271
        case BODY_LENGTH:
 
272
            e = apr_bucket_eos_create(f->c->bucket_alloc);
 
273
            APR_BRIGADE_INSERT_TAIL(b, e);
 
274
            ctx->eos_sent = 1;
 
275
            return APR_SUCCESS;
 
276
        case BODY_CHUNK:
 
277
            {
 
278
                char line[30];
 
279
                apr_bucket_brigade *bb;
 
280
                apr_size_t len = 30;
 
281
                apr_status_t http_error = HTTP_REQUEST_ENTITY_TOO_LARGE;
 
282
 
 
283
                bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
 
284
 
 
285
                /* We need to read the CRLF after the chunk.  */
 
286
                rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
 
287
                                    APR_BLOCK_READ, 0);
 
288
                apr_brigade_cleanup(bb);
 
289
 
 
290
                if (rv == APR_SUCCESS) {
 
291
                    /* Read the real chunk line. */
 
292
                    rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
 
293
                                        APR_BLOCK_READ, 0);
 
294
                    if (rv == APR_SUCCESS) {
 
295
                        rv = apr_brigade_flatten(bb, line, &len);
 
296
                        if (rv == APR_SUCCESS) {
 
297
                            /* Wait a sec, that's a blank line!  Oh no. */
 
298
                            if (!len) {
 
299
                                rv = APR_EGENERAL;
 
300
                                http_error = HTTP_SERVICE_UNAVAILABLE;
 
301
                            }
 
302
                            else {
 
303
                                ctx->remaining = get_chunk_size(line);
 
304
                            }
 
305
                        }
 
306
                    }
 
307
                    apr_brigade_cleanup(bb);
 
308
                }
 
309
 
 
310
                /* Detect chunksize error (such as overflow) */
 
311
                if (rv != APR_SUCCESS || ctx->remaining < 0) {
 
312
                    apr_status_t out_error;
 
313
 
 
314
                    ctx->remaining = 0; /* Reset it in case we have to
 
315
                                         * come back here later */
 
316
                    e = ap_bucket_error_create(http_error,
 
317
                                               NULL, f->r->pool,
 
318
                                               f->c->bucket_alloc);
 
319
                    APR_BRIGADE_INSERT_TAIL(bb, e);
 
320
                    e = apr_bucket_eos_create(f->c->bucket_alloc);
 
321
                    APR_BRIGADE_INSERT_TAIL(bb, e);
 
322
                    ctx->eos_sent = 1;
 
323
                    out_error = ap_pass_brigade(f->r->output_filters, bb);
 
324
                    return rv;
 
325
                }
 
326
 
 
327
                if (!ctx->remaining) {
 
328
                    /* Handle trailers by calling ap_get_mime_headers again! */
 
329
                    ctx->state = BODY_NONE;
 
330
                    ap_get_mime_headers(f->r);
 
331
                    e = apr_bucket_eos_create(f->c->bucket_alloc);
 
332
                    APR_BRIGADE_INSERT_TAIL(b, e);
 
333
                    ctx->eos_sent = 1;
 
334
                    return APR_SUCCESS;
 
335
                }
 
336
            }
 
337
            break;
 
338
        }
 
339
    }
 
340
 
 
341
    /* Ensure that the caller can not go over our boundary point. */
 
342
    if (ctx->state == BODY_LENGTH || ctx->state == BODY_CHUNK) {
 
343
        if (ctx->remaining < readbytes) {
 
344
            readbytes = ctx->remaining;
 
345
        }
 
346
        AP_DEBUG_ASSERT(readbytes > 0);
 
347
    }
 
348
 
 
349
    rv = ap_get_brigade(f->next, b, mode, block, readbytes);
 
350
 
 
351
    if (rv != APR_SUCCESS) {
 
352
        return rv;
 
353
    }
 
354
 
 
355
    /* How many bytes did we just read? */
 
356
    apr_brigade_length(b, 0, &totalread);
 
357
 
 
358
    /* If this happens, we have a bucket of unknown length.  Die because
 
359
     * it means our assumptions have changed. */
 
360
    AP_DEBUG_ASSERT(totalread >= 0);
 
361
 
 
362
    if (ctx->state != BODY_NONE) {
 
363
        ctx->remaining -= totalread;
 
364
    }
 
365
 
 
366
    /* If we have no more bytes remaining on a C-L request,
 
367
     * save the callter a roundtrip to discover EOS.
 
368
     */
 
369
    if (ctx->state == BODY_LENGTH && ctx->remaining == 0) {
 
370
        e = apr_bucket_eos_create(f->c->bucket_alloc);
 
371
        APR_BRIGADE_INSERT_TAIL(b, e);
 
372
    }
 
373
 
 
374
    /* We have a limit in effect. */
 
375
    if (ctx->limit) {
 
376
        /* FIXME: Note that we might get slightly confused on chunked inputs
 
377
         * as we'd need to compensate for the chunk lengths which may not
 
378
         * really count.  This seems to be up for interpretation.  */
 
379
        ctx->limit_used += totalread;
 
380
        if (ctx->limit < ctx->limit_used) {
 
381
            apr_bucket_brigade *bb;
 
382
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
 
383
                          "Read content-length of %" APR_OFF_T_FMT
 
384
                          " is larger than the configured limit"
 
385
                          " of %" APR_OFF_T_FMT, ctx->limit_used, ctx->limit);
 
386
            bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
 
387
            e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
 
388
                                       f->r->pool,
 
389
                                       f->c->bucket_alloc);
 
390
            APR_BRIGADE_INSERT_TAIL(bb, e);
 
391
            e = apr_bucket_eos_create(f->c->bucket_alloc);
 
392
            APR_BRIGADE_INSERT_TAIL(bb, e);
 
393
            ctx->eos_sent = 1;
 
394
            return ap_pass_brigade(f->r->output_filters, bb);
 
395
        }
 
396
    }
 
397
 
 
398
    return APR_SUCCESS;
 
399
}
 
400
 
 
401
/**
 
402
 * Parse a chunk extension, detect overflow.
 
403
 * There are two error cases:
 
404
 *  1) If the conversion would require too many bits, a -1 is returned.
 
405
 *  2) If the conversion used the correct number of bits, but an overflow
 
406
 *     caused only the sign bit to flip, then that negative number is
 
407
 *     returned.
 
408
 * In general, any negative number can be considered an overflow error.
 
409
 */
 
410
static long get_chunk_size(char *b)
 
411
{
 
412
    long chunksize = 0;
 
413
    size_t chunkbits = sizeof(long) * 8;
 
414
 
 
415
    ap_xlate_proto_from_ascii(b, strlen(b));
 
416
 
 
417
    /* Skip leading zeros */
 
418
    while (*b == '0') {
 
419
        ++b;
 
420
    }
 
421
 
 
422
    while (apr_isxdigit(*b) && (chunkbits > 0)) {
 
423
        int xvalue = 0;
 
424
 
 
425
        if (*b >= '0' && *b <= '9') {
 
426
            xvalue = *b - '0';
 
427
        }
 
428
        else if (*b >= 'A' && *b <= 'F') {
 
429
            xvalue = *b - 'A' + 0xa;
 
430
        }
 
431
        else if (*b >= 'a' && *b <= 'f') {
 
432
            xvalue = *b - 'a' + 0xa;
 
433
        }
 
434
 
 
435
        chunksize = (chunksize << 4) | xvalue;
 
436
        chunkbits -= 4;
 
437
        ++b;
 
438
    }
 
439
    if (apr_isxdigit(*b) && (chunkbits <= 0)) {
 
440
        /* overflow */
 
441
        return -1;
 
442
    }
 
443
 
 
444
    return chunksize;
 
445
}
 
446
 
 
447
typedef struct header_struct {
 
448
    apr_pool_t *pool;
 
449
    apr_bucket_brigade *bb;
 
450
} header_struct;
 
451
 
 
452
/* Send a single HTTP header field to the client.  Note that this function
 
453
 * is used in calls to table_do(), so their interfaces are co-dependent.
 
454
 * In other words, don't change this one without checking table_do in alloc.c.
 
455
 * It returns true unless there was a write error of some kind.
 
456
 */
 
457
static int form_header_field(header_struct *h,
 
458
                             const char *fieldname, const char *fieldval)
 
459
{
 
460
#if APR_CHARSET_EBCDIC
 
461
    char *headfield;
 
462
    apr_size_t len;
 
463
    apr_size_t name_len;
 
464
    apr_size_t val_len;
 
465
    char *next;
 
466
 
 
467
    name_len = strlen(fieldname);
 
468
    val_len = strlen(fieldval);
 
469
    len = name_len + val_len + 4; /* 4 for ": " plus CRLF */
 
470
    headfield = (char *)apr_palloc(h->pool, len + 1);
 
471
    memcpy(headfield, fieldname, name_len);
 
472
    next = headfield + name_len;
 
473
    *next++ = ':';
 
474
    *next++ = ' ';
 
475
    memcpy(next, fieldval, val_len);
 
476
    next += val_len;
 
477
    *next++ = CR;
 
478
    *next++ = LF;
 
479
    *next = 0;
 
480
    ap_xlate_proto_to_ascii(headfield, len);
 
481
    apr_brigade_write(h->bb, NULL, NULL, headfield, len);
 
482
#else
 
483
    struct iovec vec[4];
 
484
    struct iovec *v = vec;
 
485
    v->iov_base = (void *)fieldname;
 
486
    v->iov_len = strlen(fieldname);
 
487
    v++;
 
488
    v->iov_base = ": ";
 
489
    v->iov_len = sizeof(": ") - 1;
 
490
    v++;
 
491
    v->iov_base = (void *)fieldval;
 
492
    v->iov_len = strlen(fieldval);
 
493
    v++;
 
494
    v->iov_base = CRLF;
 
495
    v->iov_len = sizeof(CRLF) - 1;
 
496
    apr_brigade_writev(h->bb, NULL, NULL, vec, 4);
 
497
#endif /* !APR_CHARSET_EBCDIC */
 
498
    return 1;
 
499
}
 
500
 
 
501
/* This routine is called by apr_table_do and merges all instances of
 
502
 * the passed field values into a single array that will be further
 
503
 * processed by some later routine.  Originally intended to help split
 
504
 * and recombine multiple Vary fields, though it is generic to any field
 
505
 * consisting of comma/space-separated tokens.
 
506
 */
 
507
static int uniq_field_values(void *d, const char *key, const char *val)
 
508
{
 
509
    apr_array_header_t *values;
 
510
    char *start;
 
511
    char *e;
 
512
    char **strpp;
 
513
    int  i;
 
514
 
 
515
    values = (apr_array_header_t *)d;
 
516
 
 
517
    e = apr_pstrdup(values->pool, val);
 
518
 
 
519
    do {
 
520
        /* Find a non-empty fieldname */
 
521
 
 
522
        while (*e == ',' || apr_isspace(*e)) {
 
523
            ++e;
 
524
        }
 
525
        if (*e == '\0') {
 
526
            break;
 
527
        }
 
528
        start = e;
 
529
        while (*e != '\0' && *e != ',' && !apr_isspace(*e)) {
 
530
            ++e;
 
531
        }
 
532
        if (*e != '\0') {
 
533
            *e++ = '\0';
 
534
        }
 
535
 
 
536
        /* Now add it to values if it isn't already represented.
 
537
         * Could be replaced by a ap_array_strcasecmp() if we had one.
 
538
         */
 
539
        for (i = 0, strpp = (char **) values->elts; i < values->nelts;
 
540
             ++i, ++strpp) {
 
541
            if (*strpp && strcasecmp(*strpp, start) == 0) {
 
542
                break;
 
543
            }
 
544
        }
 
545
        if (i == values->nelts) {  /* if not found */
 
546
            *(char **)apr_array_push(values) = start;
 
547
        }
 
548
    } while (*e != '\0');
 
549
 
 
550
    return 1;
 
551
}
 
552
 
 
553
/*
 
554
 * Since some clients choke violently on multiple Vary fields, or
 
555
 * Vary fields with duplicate tokens, combine any multiples and remove
 
556
 * any duplicates.
 
557
 */
 
558
static void fixup_vary(request_rec *r)
 
559
{
 
560
    apr_array_header_t *varies;
 
561
 
 
562
    varies = apr_array_make(r->pool, 5, sizeof(char *));
 
563
 
 
564
    /* Extract all Vary fields from the headers_out, separate each into
 
565
     * its comma-separated fieldname values, and then add them to varies
 
566
     * if not already present in the array.
 
567
     */
 
568
    apr_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
 
569
                 (void *) varies, r->headers_out, "Vary", NULL);
 
570
 
 
571
    /* If we found any, replace old Vary fields with unique-ified value */
 
572
 
 
573
    if (varies->nelts > 0) {
 
574
        apr_table_setn(r->headers_out, "Vary",
 
575
                       apr_array_pstrcat(r->pool, varies, ','));
 
576
    }
 
577
}
 
578
 
 
579
/* Send a request's HTTP response headers to the client.
 
580
 */
 
581
static apr_status_t send_all_header_fields(header_struct *h,
 
582
                                           const request_rec *r)
 
583
{
 
584
    const apr_array_header_t *elts;
 
585
    const apr_table_entry_t *t_elt;
 
586
    const apr_table_entry_t *t_end;
 
587
    struct iovec *vec;
 
588
    struct iovec *vec_next;
 
589
 
 
590
    elts = apr_table_elts(r->headers_out);
 
591
    if (elts->nelts == 0) {
 
592
        return APR_SUCCESS;
 
593
    }
 
594
    t_elt = (const apr_table_entry_t *)(elts->elts);
 
595
    t_end = t_elt + elts->nelts;
 
596
    vec = (struct iovec *)apr_palloc(h->pool, 4 * elts->nelts *
 
597
                                     sizeof(struct iovec));
 
598
    vec_next = vec;
 
599
 
 
600
    /* For each field, generate
 
601
     *    name ": " value CRLF
 
602
     */
 
603
    do {
 
604
        vec_next->iov_base = (void*)(t_elt->key);
 
605
        vec_next->iov_len = strlen(t_elt->key);
 
606
        vec_next++;
 
607
        vec_next->iov_base = ": ";
 
608
        vec_next->iov_len = sizeof(": ") - 1;
 
609
        vec_next++;
 
610
        vec_next->iov_base = (void*)(t_elt->val);
 
611
        vec_next->iov_len = strlen(t_elt->val);
 
612
        vec_next++;
 
613
        vec_next->iov_base = CRLF;
 
614
        vec_next->iov_len = sizeof(CRLF) - 1;
 
615
        vec_next++;
 
616
        t_elt++;
 
617
    } while (t_elt < t_end);
 
618
 
 
619
#if APR_CHARSET_EBCDIC
 
620
    {
 
621
        apr_size_t len;
 
622
        char *tmp = apr_pstrcatv(r->pool, vec, vec_next - vec, &len);
 
623
        ap_xlate_proto_to_ascii(tmp, len);
 
624
        return apr_brigade_write(h->bb, NULL, NULL, tmp, len);
 
625
    }
 
626
#else
 
627
    return apr_brigade_writev(h->bb, NULL, NULL, vec, vec_next - vec);
 
628
#endif
 
629
}
 
630
 
 
631
/* Confirm that the status line is well-formed and matches r->status.
 
632
 * If they don't match, a filter may have negated the status line set by a
 
633
 * handler.
 
634
 * Zap r->status_line if bad.
 
635
 */
 
636
static void validate_status_line(request_rec *r)
 
637
{
 
638
    char *end;
 
639
 
 
640
    if (r->status_line
 
641
        && (strlen(r->status_line) <= 4
 
642
            || apr_strtoi64(r->status_line, &end, 10) != r->status
 
643
            || *end != ' '
 
644
            || (end - 3) != r->status_line)) {
 
645
        r->status_line = NULL;
 
646
    }
 
647
}
 
648
 
 
649
/*
 
650
 * Determine the protocol to use for the response. Potentially downgrade
 
651
 * to HTTP/1.0 in some situations and/or turn off keepalives.
 
652
 *
 
653
 * also prepare r->status_line.
 
654
 */
 
655
static void basic_http_header_check(request_rec *r,
 
656
                                    const char **protocol)
 
657
{
 
658
    if (r->assbackwards) {
 
659
        /* no such thing as a response protocol */
 
660
        return;
 
661
    }
 
662
 
 
663
    validate_status_line(r);
 
664
 
 
665
    if (!r->status_line) {
 
666
        r->status_line = ap_get_status_line(r->status);
 
667
    }
 
668
 
 
669
    /* Note that we must downgrade before checking for force responses. */
 
670
    if (r->proto_num > HTTP_VERSION(1,0)
 
671
        && apr_table_get(r->subprocess_env, "downgrade-1.0")) {
 
672
        r->proto_num = HTTP_VERSION(1,0);
 
673
    }
 
674
 
 
675
    /* kludge around broken browsers when indicated by force-response-1.0
 
676
     */
 
677
    if (r->proto_num == HTTP_VERSION(1,0)
 
678
        && apr_table_get(r->subprocess_env, "force-response-1.0")) {
 
679
        *protocol = "HTTP/1.0";
 
680
        r->connection->keepalive = AP_CONN_CLOSE;
 
681
    }
 
682
    else {
 
683
        *protocol = AP_SERVER_PROTOCOL;
 
684
    }
 
685
 
 
686
}
 
687
 
 
688
/* fill "bb" with a barebones/initial HTTP response header */
 
689
static void basic_http_header(request_rec *r, apr_bucket_brigade *bb,
 
690
                              const char *protocol)
 
691
{
 
692
    char *date;
 
693
    const char *server;
 
694
    header_struct h;
 
695
    struct iovec vec[4];
 
696
 
 
697
    if (r->assbackwards) {
 
698
        /* there are no headers to send */
 
699
        return;
 
700
    }
 
701
 
 
702
    /* Output the HTTP/1.x Status-Line and the Date and Server fields */
 
703
 
 
704
    vec[0].iov_base = (void *)protocol;
 
705
    vec[0].iov_len  = strlen(protocol);
 
706
    vec[1].iov_base = (void *)" ";
 
707
    vec[1].iov_len  = sizeof(" ") - 1;
 
708
    vec[2].iov_base = (void *)(r->status_line);
 
709
    vec[2].iov_len  = strlen(r->status_line);
 
710
    vec[3].iov_base = (void *)CRLF;
 
711
    vec[3].iov_len  = sizeof(CRLF) - 1;
 
712
#if APR_CHARSET_EBCDIC
 
713
    {
 
714
        char *tmp;
 
715
        apr_size_t len;
 
716
        tmp = apr_pstrcatv(r->pool, vec, 4, &len);
 
717
        ap_xlate_proto_to_ascii(tmp, len);
 
718
        apr_brigade_write(bb, NULL, NULL, tmp, len);
 
719
    }
 
720
#else
 
721
    apr_brigade_writev(bb, NULL, NULL, vec, 4);
 
722
#endif
 
723
 
 
724
    date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
 
725
    ap_recent_rfc822_date(date, r->request_time);
 
726
 
 
727
    h.pool = r->pool;
 
728
    h.bb = bb;
 
729
    form_header_field(&h, "Date", date);
 
730
 
 
731
    /* keep the set-by-proxy server header, otherwise
 
732
     * generate a new server header */
 
733
    if (r->proxyreq != PROXYREQ_NONE) {
 
734
        server = apr_table_get(r->headers_out, "Server");
 
735
        if (server) {
 
736
            form_header_field(&h, "Server", server);
 
737
        }
 
738
    }
 
739
    else {
 
740
        form_header_field(&h, "Server", ap_get_server_version());
 
741
    }
 
742
 
 
743
    /* unset so we don't send them again */
 
744
    apr_table_unset(r->headers_out, "Date");        /* Avoid bogosity */
 
745
    apr_table_unset(r->headers_out, "Server");
 
746
}
 
747
 
 
748
AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb)
 
749
{
 
750
    const char *protocol;
 
751
 
 
752
    basic_http_header_check(r, &protocol);
 
753
    basic_http_header(r, bb, protocol);
 
754
}
 
755
 
 
756
/* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
 
757
 * have a header parsing bug.  If the terminating \r\n occur starting
 
758
 * at offset 256, 257 or 258 of output then it will not properly parse
 
759
 * the headers.  Curiously it doesn't exhibit this problem at 512, 513.
 
760
 * We are guessing that this is because their initial read of a new request
 
761
 * uses a 256 byte buffer, and subsequent reads use a larger buffer.
 
762
 * So the problem might exist at different offsets as well.
 
763
 *
 
764
 * This should also work on keepalive connections assuming they use the
 
765
 * same small buffer for the first read of each new request.
 
766
 *
 
767
 * At any rate, we check the bytes written so far and, if we are about to
 
768
 * tickle the bug, we instead insert a bogus padding header.  Since the bug
 
769
 * manifests as a broken image in Navigator, users blame the server.  :(
 
770
 * It is more expensive to check the User-Agent than it is to just add the
 
771
 * bytes, so we haven't used the BrowserMatch feature here.
 
772
 */
 
773
static void terminate_header(apr_bucket_brigade *bb)
 
774
{
 
775
    char tmp[] = "X-Pad: avoid browser bug" CRLF;
 
776
    char crlf[] = CRLF;
 
777
    apr_off_t len;
 
778
    apr_size_t buflen;
 
779
 
 
780
    (void) apr_brigade_length(bb, 1, &len);
 
781
 
 
782
    if (len >= 255 && len <= 257) {
 
783
        buflen = strlen(tmp);
 
784
        ap_xlate_proto_to_ascii(tmp, buflen);
 
785
        apr_brigade_write(bb, NULL, NULL, tmp, buflen);
 
786
    }
 
787
    buflen = strlen(crlf);
 
788
    ap_xlate_proto_to_ascii(crlf, buflen);
 
789
    apr_brigade_write(bb, NULL, NULL, crlf, buflen);
 
790
}
 
791
 
 
792
AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r)
 
793
{
 
794
    core_server_config *conf;
 
795
    int rv;
 
796
    apr_bucket_brigade *bb;
 
797
    header_struct h;
 
798
    apr_bucket *b;
 
799
    int body;
 
800
    char *bodyread = NULL, *bodyoff;
 
801
    apr_size_t bodylen = 0;
 
802
    apr_size_t bodybuf;
 
803
    long res = -1; /* init to avoid gcc -Wall warning */
 
804
 
 
805
    if (r->method_number != M_TRACE) {
 
806
        return DECLINED;
 
807
    }
 
808
 
 
809
    /* Get the original request */
 
810
    while (r->prev) {
 
811
        r = r->prev;
 
812
    }
 
813
    conf = (core_server_config *)ap_get_module_config(r->server->module_config,
 
814
                                                      &core_module);
 
815
 
 
816
    if (conf->trace_enable == AP_TRACE_DISABLE) {
 
817
        apr_table_setn(r->notes, "error-notes",
 
818
                      "TRACE denied by server configuration");
 
819
        return HTTP_FORBIDDEN;
 
820
    }
 
821
 
 
822
    if (conf->trace_enable == AP_TRACE_EXTENDED)
 
823
        /* XX should be = REQUEST_CHUNKED_PASS */
 
824
        body = REQUEST_CHUNKED_DECHUNK;
 
825
    else
 
826
        body = REQUEST_NO_BODY;
 
827
 
 
828
    if ((rv = ap_setup_client_block(r, body))) {
 
829
        if (rv == HTTP_REQUEST_ENTITY_TOO_LARGE)
 
830
            apr_table_setn(r->notes, "error-notes",
 
831
                          "TRACE with a request body is not allowed");
 
832
        return rv;
 
833
    }
 
834
 
 
835
    if (ap_should_client_block(r)) {
 
836
 
 
837
        if (r->remaining > 0) {
 
838
            if (r->remaining > 65536) {
 
839
                apr_table_setn(r->notes, "error-notes",
 
840
                       "Extended TRACE request bodies cannot exceed 64k\n");
 
841
                return HTTP_REQUEST_ENTITY_TOO_LARGE;
 
842
            }
 
843
            /* always 32 extra bytes to catch chunk header exceptions */
 
844
            bodybuf = (apr_size_t)r->remaining + 32;
 
845
        }
 
846
        else {
 
847
            /* Add an extra 8192 for chunk headers */
 
848
            bodybuf = 73730;
 
849
        }
 
850
 
 
851
        bodyoff = bodyread = apr_palloc(r->pool, bodybuf);
 
852
 
 
853
        /* only while we have enough for a chunked header */
 
854
        while ((!bodylen || bodybuf >= 32) &&
 
855
               (res = ap_get_client_block(r, bodyoff, bodybuf)) > 0) {
 
856
            bodylen += res;
 
857
            bodybuf -= res;
 
858
            bodyoff += res;
 
859
        }
 
860
        if (res > 0 && bodybuf < 32) {
 
861
            /* discard_rest_of_request_body into our buffer */
 
862
            while (ap_get_client_block(r, bodyread, bodylen) > 0)
 
863
                ;
 
864
            apr_table_setn(r->notes, "error-notes",
 
865
                   "Extended TRACE request bodies cannot exceed 64k\n");
 
866
            return HTTP_REQUEST_ENTITY_TOO_LARGE;
 
867
        }
 
868
 
 
869
        if (res < 0) {
 
870
            return HTTP_BAD_REQUEST;
 
871
        }
 
872
    }
 
873
 
 
874
    ap_set_content_type(r, "message/http");
 
875
 
 
876
    /* Now we recreate the request, and echo it back */
 
877
 
 
878
    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
 
879
    apr_brigade_putstrs(bb, NULL, NULL, r->the_request, CRLF, NULL);
 
880
    h.pool = r->pool;
 
881
    h.bb = bb;
 
882
    apr_table_do((int (*) (void *, const char *, const char *))
 
883
                 form_header_field, (void *) &h, r->headers_in, NULL);
 
884
    apr_brigade_puts(bb, NULL, NULL, CRLF);
 
885
 
 
886
    /* If configured to accept a body, echo the body */
 
887
    if (bodylen) {
 
888
        b = apr_bucket_pool_create(bodyread, bodylen,
 
889
                                   r->pool, bb->bucket_alloc);
 
890
        APR_BRIGADE_INSERT_TAIL(bb, b);
 
891
    }
 
892
 
 
893
    ap_pass_brigade(r->output_filters,  bb);
 
894
 
 
895
    return DONE;
 
896
}
 
897
 
 
898
typedef struct header_filter_ctx {
 
899
    int headers_sent;
 
900
} header_filter_ctx;
 
901
 
 
902
AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
 
903
                                                           apr_bucket_brigade *b)
 
904
{
 
905
    request_rec *r = f->r;
 
906
    conn_rec *c = r->connection;
 
907
    const char *clheader;
 
908
    const char *protocol;
 
909
    apr_bucket *e;
 
910
    apr_bucket_brigade *b2;
 
911
    header_struct h;
 
912
    header_filter_ctx *ctx = f->ctx;
 
913
 
 
914
    AP_DEBUG_ASSERT(!r->main);
 
915
 
 
916
    if (r->header_only) {
 
917
        if (!ctx) {
 
918
            ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx));
 
919
        }
 
920
        else if (ctx->headers_sent) {
 
921
            apr_brigade_destroy(b);
 
922
            return OK;
 
923
        }
 
924
    }
 
925
 
 
926
    for (e = APR_BRIGADE_FIRST(b);
 
927
         e != APR_BRIGADE_SENTINEL(b);
 
928
         e = APR_BUCKET_NEXT(e))
 
929
    {
 
930
        if (AP_BUCKET_IS_ERROR(e)) {
 
931
            ap_bucket_error *eb = e->data;
 
932
 
 
933
            ap_die(eb->status, r);
 
934
            return AP_FILTER_ERROR;
 
935
        }
 
936
    }
 
937
 
 
938
    if (r->assbackwards) {
 
939
        r->sent_bodyct = 1;
 
940
        ap_remove_output_filter(f);
 
941
        return ap_pass_brigade(f->next, b);
 
942
    }
 
943
 
 
944
    /*
 
945
     * Now that we are ready to send a response, we need to combine the two
 
946
     * header field tables into a single table.  If we don't do this, our
 
947
     * later attempts to set or unset a given fieldname might be bypassed.
 
948
     */
 
949
    if (!apr_is_empty_table(r->err_headers_out)) {
 
950
        r->headers_out = apr_table_overlay(r->pool, r->err_headers_out,
 
951
                                           r->headers_out);
 
952
    }
 
953
 
 
954
    /*
 
955
     * Remove the 'Vary' header field if the client can't handle it.
 
956
     * Since this will have nasty effects on HTTP/1.1 caches, force
 
957
     * the response into HTTP/1.0 mode.
 
958
     *
 
959
     * Note: the force-response-1.0 should come before the call to
 
960
     *       basic_http_header_check()
 
961
     */
 
962
    if (apr_table_get(r->subprocess_env, "force-no-vary") != NULL) {
 
963
        apr_table_unset(r->headers_out, "Vary");
 
964
        r->proto_num = HTTP_VERSION(1,0);
 
965
        apr_table_set(r->subprocess_env, "force-response-1.0", "1");
 
966
    }
 
967
    else {
 
968
        fixup_vary(r);
 
969
    }
 
970
 
 
971
    /*
 
972
     * Now remove any ETag response header field if earlier processing
 
973
     * says so (such as a 'FileETag None' directive).
 
974
     */
 
975
    if (apr_table_get(r->notes, "no-etag") != NULL) {
 
976
        apr_table_unset(r->headers_out, "ETag");
 
977
    }
 
978
 
 
979
    /* determine the protocol and whether we should use keepalives. */
 
980
    basic_http_header_check(r, &protocol);
 
981
    ap_set_keepalive(r);
 
982
 
 
983
    if (r->chunked) {
 
984
        apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
 
985
        apr_table_unset(r->headers_out, "Content-Length");
 
986
    }
 
987
 
 
988
    apr_table_setn(r->headers_out, "Content-Type",
 
989
                   ap_make_content_type(r, r->content_type));
 
990
 
 
991
    if (r->content_encoding) {
 
992
        apr_table_setn(r->headers_out, "Content-Encoding",
 
993
                       r->content_encoding);
 
994
    }
 
995
 
 
996
    if (!apr_is_empty_array(r->content_languages)) {
 
997
        int i;
 
998
        char **languages = (char **)(r->content_languages->elts);
 
999
        for (i = 0; i < r->content_languages->nelts; ++i) {
 
1000
            apr_table_mergen(r->headers_out, "Content-Language", languages[i]);
 
1001
        }
 
1002
    }
 
1003
 
 
1004
    /*
 
1005
     * Control cachability for non-cachable responses if not already set by
 
1006
     * some other part of the server configuration.
 
1007
     */
 
1008
    if (r->no_cache && !apr_table_get(r->headers_out, "Expires")) {
 
1009
        char *date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
 
1010
        ap_recent_rfc822_date(date, r->request_time);
 
1011
        apr_table_addn(r->headers_out, "Expires", date);
 
1012
    }
 
1013
 
 
1014
    /* This is a hack, but I can't find anyway around it.  The idea is that
 
1015
     * we don't want to send out 0 Content-Lengths if it is a head request.
 
1016
     * This happens when modules try to outsmart the server, and return
 
1017
     * if they see a HEAD request.  Apache 1.3 handlers were supposed to
 
1018
     * just return in that situation, and the core handled the HEAD.  In
 
1019
     * 2.0, if a handler returns, then the core sends an EOS bucket down
 
1020
     * the filter stack, and the content-length filter computes a C-L of
 
1021
     * zero and that gets put in the headers, and we end up sending a
 
1022
     * zero C-L to the client.  We can't just remove the C-L filter,
 
1023
     * because well behaved 2.0 handlers will send their data down the stack,
 
1024
     * and we will compute a real C-L for the head request. RBB
 
1025
     */
 
1026
    if (r->header_only
 
1027
        && (clheader = apr_table_get(r->headers_out, "Content-Length"))
 
1028
        && !strcmp(clheader, "0")) {
 
1029
        apr_table_unset(r->headers_out, "Content-Length");
 
1030
    }
 
1031
 
 
1032
    b2 = apr_brigade_create(r->pool, c->bucket_alloc);
 
1033
    basic_http_header(r, b2, protocol);
 
1034
 
 
1035
    h.pool = r->pool;
 
1036
    h.bb = b2;
 
1037
 
 
1038
    if (r->status == HTTP_NOT_MODIFIED) {
 
1039
        apr_table_do((int (*)(void *, const char *, const char *)) form_header_field,
 
1040
                     (void *) &h, r->headers_out,
 
1041
                     "Connection",
 
1042
                     "Keep-Alive",
 
1043
                     "ETag",
 
1044
                     "Content-Location",
 
1045
                     "Expires",
 
1046
                     "Cache-Control",
 
1047
                     "Vary",
 
1048
                     "Warning",
 
1049
                     "WWW-Authenticate",
 
1050
                     "Proxy-Authenticate",
 
1051
                     "Set-Cookie",
 
1052
                     "Set-Cookie2",
 
1053
                     NULL);
 
1054
    }
 
1055
    else {
 
1056
        send_all_header_fields(&h, r);
 
1057
    }
 
1058
 
 
1059
    terminate_header(b2);
 
1060
 
 
1061
    ap_pass_brigade(f->next, b2);
 
1062
 
 
1063
    if (r->header_only) {
 
1064
        apr_brigade_destroy(b);
 
1065
        ctx->headers_sent = 1;
 
1066
        return OK;
 
1067
    }
 
1068
 
 
1069
    r->sent_bodyct = 1;         /* Whatever follows is real body stuff... */
 
1070
 
 
1071
    if (r->chunked) {
 
1072
        /* We can't add this filter until we have already sent the headers.
 
1073
         * If we add it before this point, then the headers will be chunked
 
1074
         * as well, and that is just wrong.
 
1075
         */
 
1076
        ap_add_output_filter("CHUNK", NULL, r, r->connection);
 
1077
    }
 
1078
 
 
1079
    /* Don't remove this filter until after we have added the CHUNK filter.
 
1080
     * Otherwise, f->next won't be the CHUNK filter and thus the first
 
1081
     * brigade won't be chunked properly.
 
1082
     */
 
1083
    ap_remove_output_filter(f);
 
1084
    return ap_pass_brigade(f->next, b);
 
1085
}
 
1086
 
 
1087
/* In HTTP/1.1, any method can have a body.  However, most GET handlers
 
1088
 * wouldn't know what to do with a request body if they received one.
 
1089
 * This helper routine tests for and reads any message body in the request,
 
1090
 * simply discarding whatever it receives.  We need to do this because
 
1091
 * failing to read the request body would cause it to be interpreted
 
1092
 * as the next request on a persistent connection.
 
1093
 *
 
1094
 * Since we return an error status if the request is malformed, this
 
1095
 * routine should be called at the beginning of a no-body handler, e.g.,
 
1096
 *
 
1097
 *    if ((retval = ap_discard_request_body(r)) != OK) {
 
1098
 *        return retval;
 
1099
 *    }
 
1100
 */
 
1101
AP_DECLARE(int) ap_discard_request_body(request_rec *r)
 
1102
{
 
1103
    apr_bucket_brigade *bb;
 
1104
    int rv, seen_eos;
 
1105
 
 
1106
    /* Sometimes we'll get in a state where the input handling has
 
1107
     * detected an error where we want to drop the connection, so if
 
1108
     * that's the case, don't read the data as that is what we're trying
 
1109
     * to avoid.
 
1110
     *
 
1111
     * This function is also a no-op on a subrequest.
 
1112
     */
 
1113
    if (r->main || r->connection->keepalive == AP_CONN_CLOSE ||
 
1114
        ap_status_drops_connection(r->status)) {
 
1115
        return OK;
 
1116
    }
 
1117
 
 
1118
    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
 
1119
    seen_eos = 0;
 
1120
    do {
 
1121
        apr_bucket *bucket;
 
1122
 
 
1123
        rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
 
1124
                            APR_BLOCK_READ, HUGE_STRING_LEN);
 
1125
 
 
1126
        if (rv != APR_SUCCESS) {
 
1127
            /* FIXME: If we ever have a mapping from filters (apr_status_t)
 
1128
             * to HTTP error codes, this would be a good place for them.
 
1129
             *
 
1130
             * If we received the special case AP_FILTER_ERROR, it means
 
1131
             * that the filters have already handled this error.
 
1132
             * Otherwise, we should assume we have a bad request.
 
1133
             */
 
1134
            if (rv == AP_FILTER_ERROR) {
 
1135
                apr_brigade_destroy(bb);
 
1136
                return rv;
 
1137
            }
 
1138
            else {
 
1139
                apr_brigade_destroy(bb);
 
1140
                return HTTP_BAD_REQUEST;
 
1141
            }
 
1142
        }
 
1143
 
 
1144
        for (bucket = APR_BRIGADE_FIRST(bb);
 
1145
             bucket != APR_BRIGADE_SENTINEL(bb);
 
1146
             bucket = APR_BUCKET_NEXT(bucket))
 
1147
        {
 
1148
            const char *data;
 
1149
            apr_size_t len;
 
1150
 
 
1151
            if (APR_BUCKET_IS_EOS(bucket)) {
 
1152
                seen_eos = 1;
 
1153
                break;
 
1154
            }
 
1155
 
 
1156
            /* These are metadata buckets. */
 
1157
            if (bucket->length == 0) {
 
1158
                continue;
 
1159
            }
 
1160
 
 
1161
            /* We MUST read because in case we have an unknown-length
 
1162
             * bucket or one that morphs, we want to exhaust it.
 
1163
             */
 
1164
            rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
 
1165
            if (rv != APR_SUCCESS) {
 
1166
                apr_brigade_destroy(bb);
 
1167
                return HTTP_BAD_REQUEST;
 
1168
            }
 
1169
        }
 
1170
        apr_brigade_cleanup(bb);
 
1171
    } while (!seen_eos);
 
1172
 
 
1173
    return OK;
 
1174
}
 
1175
 
 
1176
/* Here we deal with getting the request message body from the client.
 
1177
 * Whether or not the request contains a body is signaled by the presence
 
1178
 * of a non-zero Content-Length or by a Transfer-Encoding: chunked.
 
1179
 *
 
1180
 * Note that this is more complicated than it was in Apache 1.1 and prior
 
1181
 * versions, because chunked support means that the module does less.
 
1182
 *
 
1183
 * The proper procedure is this:
 
1184
 *
 
1185
 * 1. Call ap_setup_client_block() near the beginning of the request
 
1186
 *    handler. This will set up all the necessary properties, and will
 
1187
 *    return either OK, or an error code. If the latter, the module should
 
1188
 *    return that error code. The second parameter selects the policy to
 
1189
 *    apply if the request message indicates a body, and how a chunked
 
1190
 *    transfer-coding should be interpreted. Choose one of
 
1191
 *
 
1192
 *    REQUEST_NO_BODY          Send 413 error if message has any body
 
1193
 *    REQUEST_CHUNKED_ERROR    Send 411 error if body without Content-Length
 
1194
 *    REQUEST_CHUNKED_DECHUNK  If chunked, remove the chunks for me.
 
1195
 *    REQUEST_CHUNKED_PASS     If chunked, pass the chunk headers with body.
 
1196
 *
 
1197
 *    In order to use the last two options, the caller MUST provide a buffer
 
1198
 *    large enough to hold a chunk-size line, including any extensions.
 
1199
 *
 
1200
 * 2. When you are ready to read a body (if any), call ap_should_client_block().
 
1201
 *    This will tell the module whether or not to read input. If it is 0,
 
1202
 *    the module should assume that there is no message body to read.
 
1203
 *
 
1204
 * 3. Finally, call ap_get_client_block in a loop. Pass it a buffer and its size.
 
1205
 *    It will put data into the buffer (not necessarily a full buffer), and
 
1206
 *    return the length of the input block. When it is done reading, it will
 
1207
 *    return 0 if EOF, or -1 if there was an error.
 
1208
 *    If an error occurs on input, we force an end to keepalive.
 
1209
 *
 
1210
 *    This step also sends a 100 Continue response to HTTP/1.1 clients if appropriate.
 
1211
 */
 
1212
 
 
1213
AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy)
 
1214
{
 
1215
    const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
 
1216
    const char *lenp = apr_table_get(r->headers_in, "Content-Length");
 
1217
 
 
1218
    r->read_body = read_policy;
 
1219
    r->read_chunked = 0;
 
1220
    r->remaining = 0;
 
1221
 
 
1222
    if (tenc) {
 
1223
        if (strcasecmp(tenc, "chunked")) {
 
1224
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
 
1225
                          "Unknown Transfer-Encoding %s", tenc);
 
1226
            return HTTP_NOT_IMPLEMENTED;
 
1227
        }
 
1228
        if (r->read_body == REQUEST_CHUNKED_ERROR) {
 
1229
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
 
1230
                          "chunked Transfer-Encoding forbidden: %s", r->uri);
 
1231
            return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
 
1232
        }
 
1233
 
 
1234
        r->read_chunked = 1;
 
1235
    }
 
1236
    else if (lenp) {
 
1237
        char *endstr;
 
1238
 
 
1239
        if (apr_strtoff(&r->remaining, lenp, &endstr, 10)
 
1240
            || *endstr || r->remaining < 0) {
 
1241
            r->remaining = 0;
 
1242
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
 
1243
                          "Invalid Content-Length");
 
1244
            return HTTP_BAD_REQUEST;
 
1245
        }
 
1246
    }
 
1247
 
 
1248
    if ((r->read_body == REQUEST_NO_BODY)
 
1249
        && (r->read_chunked || (r->remaining > 0))) {
 
1250
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
 
1251
                      "%s with body is not allowed for %s", r->method, r->uri);
 
1252
        return HTTP_REQUEST_ENTITY_TOO_LARGE;
 
1253
    }
 
1254
 
 
1255
#ifdef AP_DEBUG
 
1256
    {
 
1257
        /* Make sure ap_getline() didn't leave any droppings. */
 
1258
        core_request_config *req_cfg =
 
1259
            (core_request_config *)ap_get_module_config(r->request_config,
 
1260
                                                        &core_module);
 
1261
        AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(req_cfg->bb));
 
1262
    }
 
1263
#endif
 
1264
 
 
1265
    return OK;
 
1266
}
 
1267
 
 
1268
AP_DECLARE(int) ap_should_client_block(request_rec *r)
 
1269
{
 
1270
    /* First check if we have already read the request body */
 
1271
 
 
1272
    if (r->read_length || (!r->read_chunked && (r->remaining <= 0))) {
 
1273
        return 0;
 
1274
    }
 
1275
 
 
1276
    return 1;
 
1277
}
 
1278
 
 
1279
/* get_client_block is called in a loop to get the request message body.
 
1280
 * This is quite simple if the client includes a content-length
 
1281
 * (the normal case), but gets messy if the body is chunked. Note that
 
1282
 * r->remaining is used to maintain state across calls and that
 
1283
 * r->read_length is the total number of bytes given to the caller
 
1284
 * across all invocations.  It is messy because we have to be careful not
 
1285
 * to read past the data provided by the client, since these reads block.
 
1286
 * Returns 0 on End-of-body, -1 on error or premature chunk end.
 
1287
 *
 
1288
 */
 
1289
AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer,
 
1290
                                     apr_size_t bufsiz)
 
1291
{
 
1292
    apr_status_t rv;
 
1293
    apr_bucket_brigade *bb;
 
1294
 
 
1295
    if (r->remaining < 0 || (!r->read_chunked && r->remaining == 0)) {
 
1296
        return 0;
 
1297
    }
 
1298
 
 
1299
    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
 
1300
    if (bb == NULL) {
 
1301
        r->connection->keepalive = AP_CONN_CLOSE;
 
1302
        return -1;
 
1303
    }
 
1304
 
 
1305
    rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
 
1306
                        APR_BLOCK_READ, bufsiz);
 
1307
 
 
1308
    /* We lose the failure code here.  This is why ap_get_client_block should
 
1309
     * not be used.
 
1310
     */
 
1311
    if (rv != APR_SUCCESS) {
 
1312
        /* if we actually fail here, we want to just return and
 
1313
         * stop trying to read data from the client.
 
1314
         */
 
1315
        r->connection->keepalive = AP_CONN_CLOSE;
 
1316
        apr_brigade_destroy(bb);
 
1317
        return -1;
 
1318
    }
 
1319
 
 
1320
    /* If this fails, it means that a filter is written incorrectly and that
 
1321
     * it needs to learn how to properly handle APR_BLOCK_READ requests by
 
1322
     * returning data when requested.
 
1323
     */
 
1324
    AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(bb));
 
1325
 
 
1326
    /* Check to see if EOS in the brigade.
 
1327
     *
 
1328
     * If so, we have to leave a nugget for the *next* ap_get_client_block
 
1329
     * call to return 0.
 
1330
     */
 
1331
    if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
 
1332
        if (r->read_chunked) {
 
1333
            r->remaining = -1;
 
1334
        }
 
1335
        else {
 
1336
            r->remaining = 0;
 
1337
        }
 
1338
    }
 
1339
 
 
1340
    rv = apr_brigade_flatten(bb, buffer, &bufsiz);
 
1341
    if (rv != APR_SUCCESS) {
 
1342
        apr_brigade_destroy(bb);
 
1343
        return -1;
 
1344
    }
 
1345
 
 
1346
    /* XXX yank me? */
 
1347
    r->read_length += bufsiz;
 
1348
 
 
1349
    apr_brigade_destroy(bb);
 
1350
    return bufsiz;
 
1351
}
 
1352
 
 
1353
/* Filter to handle any error buckets on output */
 
1354
apr_status_t ap_http_outerror_filter(ap_filter_t *f,
 
1355
                                     apr_bucket_brigade *b)
 
1356
{
 
1357
    request_rec *r = f->r;
 
1358
    apr_bucket *e;
 
1359
 
 
1360
    for (e = APR_BRIGADE_FIRST(b);
 
1361
         e != APR_BRIGADE_SENTINEL(b);
 
1362
         e = APR_BUCKET_NEXT(e))
 
1363
    {
 
1364
        if (AP_BUCKET_IS_ERROR(e)) {
 
1365
            /*
 
1366
             * Start of error handling state tree. Just one condition
 
1367
             * right now :)
 
1368
             */
 
1369
            if (((ap_bucket_error *)(e->data))->status == HTTP_BAD_GATEWAY) {
 
1370
                /* stream aborted and we have not ended it yet */
 
1371
                r->connection->keepalive = AP_CONN_CLOSE;
 
1372
            }
 
1373
        }
 
1374
    }
 
1375
 
 
1376
    return ap_pass_brigade(f->next,  b);
 
1377
}
 
1378