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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * http_filter.c --- HTTP routines which either filters or deal with filters.
22 #include "apr_strings.h"
23 #include "apr_buckets.h"
25 #include "apr_signal.h"
27 #define APR_WANT_STDIO /* for sscanf */
28 #define APR_WANT_STRFUNC
29 #define APR_WANT_MEMFUNC
32 #include "util_filter.h"
33 #include "ap_config.h"
35 #include "http_config.h"
36 #include "http_core.h"
37 #include "http_protocol.h"
38 #include "http_main.h"
39 #include "http_request.h"
40 #include "http_vhost.h"
41 #include "http_connection.h"
42 #include "http_log.h" /* For errors detected in basic auth common
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"
58 #define INVALID_CHAR -2
60 static long get_chunk_size(char *);
62 typedef struct http_filter_ctx
{
76 apr_bucket_brigade
*bb
;
79 static apr_status_t
bail_out_on_error(http_ctx_t
*ctx
,
84 apr_bucket_brigade
*bb
= ctx
->bb
;
86 apr_brigade_cleanup(bb
);
87 e
= ap_bucket_error_create(http_error
,
90 APR_BRIGADE_INSERT_TAIL(bb
, e
);
91 e
= apr_bucket_eos_create(f
->c
->bucket_alloc
);
92 APR_BRIGADE_INSERT_TAIL(bb
, e
);
94 return ap_pass_brigade(f
->r
->output_filters
, bb
);
97 static apr_status_t
get_remaining_chunk_line(http_ctx_t
*ctx
,
98 apr_bucket_brigade
*b
,
102 apr_off_t brigade_length
;
108 * As the brigade b should have been requested in mode AP_MODE_GETLINE
109 * all buckets in this brigade are already some type of memory
110 * buckets (due to the needed scanning for LF in mode AP_MODE_GETLINE)
113 rv
= apr_brigade_length(b
, 0, &brigade_length
);
114 if (rv
!= APR_SUCCESS
) {
117 /* Sanity check. Should never happen. See above. */
118 if (brigade_length
== -1) {
121 if (!brigade_length
) {
124 ctx
->linesize
+= brigade_length
;
125 if (ctx
->linesize
> linelimit
) {
129 * As all buckets are already some type of memory buckets or META buckets
130 * (see above), we only need to check the last byte in the last data bucket.
132 for (e
= APR_BRIGADE_LAST(b
);
133 e
!= APR_BRIGADE_SENTINEL(b
);
134 e
= APR_BUCKET_PREV(e
)) {
136 if (APR_BUCKET_IS_METADATA(e
)) {
139 rv
= apr_bucket_read(e
, &lineend
, &len
, APR_BLOCK_READ
);
140 if (rv
!= APR_SUCCESS
) {
144 break; /* we got the data we want */
146 /* If we got a zero-length data bucket, we try the next one */
148 /* We had no data in this brigade */
149 if (!len
|| e
== APR_BRIGADE_SENTINEL(b
)) {
152 if (lineend
[len
- 1] != APR_ASCII_LF
) {
155 /* Line is complete. So reset ctx->linesize for next round. */
160 static apr_status_t
get_chunk_line(http_ctx_t
*ctx
, apr_bucket_brigade
*b
,
167 tmp_len
= sizeof(ctx
->chunk_ln
) - (ctx
->pos
- ctx
->chunk_ln
) - 1;
168 /* Saveguard ourselves against underflows */
173 len
= (apr_size_t
) tmp_len
;
176 * Check if there is space left in ctx->chunk_ln. If not, then either
177 * the chunk size is insane or we have chunk-extensions. Ignore both
178 * by discarding the remaining part of the line via
179 * get_remaining_chunk_line. Only bail out if the line is too long.
182 rv
= apr_brigade_flatten(b
, ctx
->pos
, &len
);
183 if (rv
!= APR_SUCCESS
) {
187 ctx
->linesize
+= len
;
190 * Check if we really got a full line. If yes the
191 * last char in the just read buffer must be LF.
192 * If not advance the buffer and return APR_EAGAIN.
193 * We do not start processing until we have the
196 if (ctx
->pos
[-1] != APR_ASCII_LF
) {
197 /* Check if the remaining data in the brigade has the LF */
198 return get_remaining_chunk_line(ctx
, b
, linelimit
);
200 /* Line is complete. So reset ctx->pos for next round. */
201 ctx
->pos
= ctx
->chunk_ln
;
204 return get_remaining_chunk_line(ctx
, b
, linelimit
);
208 /* This is the HTTP_INPUT filter for HTTP requests and responses from
209 * proxied servers (mod_proxy). It handles chunked and content-length
210 * bodies. This can only be inserted/used after the headers
211 * are successfully parsed.
213 apr_status_t
ap_http_filter(ap_filter_t
*f
, apr_bucket_brigade
*b
,
214 ap_input_mode_t mode
, apr_read_type_e block
,
218 http_ctx_t
*ctx
= f
->ctx
;
221 int http_error
= HTTP_REQUEST_ENTITY_TOO_LARGE
;
222 apr_bucket_brigade
*bb
;
224 /* just get out of the way of things we don't want. */
225 if (mode
!= AP_MODE_READBYTES
&& mode
!= AP_MODE_GETLINE
) {
226 return ap_get_brigade(f
->next
, b
, mode
, block
, readbytes
);
230 const char *tenc
, *lenp
;
231 f
->ctx
= ctx
= apr_pcalloc(f
->r
->pool
, sizeof(*ctx
));
232 ctx
->state
= BODY_NONE
;
233 ctx
->pos
= ctx
->chunk_ln
;
234 ctx
->bb
= apr_brigade_create(f
->r
->pool
, f
->c
->bucket_alloc
);
237 /* LimitRequestBody does not apply to proxied responses.
238 * Consider implementing this check in its own filter.
239 * Would adding a directive to limit the size of proxied
240 * responses be useful?
242 if (!f
->r
->proxyreq
) {
243 ctx
->limit
= ap_get_limit_req_body(f
->r
);
249 tenc
= apr_table_get(f
->r
->headers_in
, "Transfer-Encoding");
250 lenp
= apr_table_get(f
->r
->headers_in
, "Content-Length");
253 if (!strcasecmp(tenc
, "chunked")) {
254 ctx
->state
= BODY_CHUNK
;
256 /* test lenp, because it gives another case we can handle */
258 /* Something that isn't in HTTP, unless some future
259 * edition defines new transfer ecodings, is unsupported.
261 ap_log_rerror(APLOG_MARK
, APLOG_ERR
, 0, f
->r
,
262 "Unknown Transfer-Encoding: %s", tenc
);
263 return bail_out_on_error(ctx
, f
, HTTP_NOT_IMPLEMENTED
);
266 ap_log_rerror(APLOG_MARK
, APLOG_WARNING
, 0, f
->r
,
267 "Unknown Transfer-Encoding: %s; using Content-Length", tenc
);
274 ctx
->state
= BODY_LENGTH
;
277 /* Protects against over/underflow, non-digit chars in the
278 * string (excluding leading space) (the endstr checks)
279 * and a negative number. */
280 if (apr_strtoff(&ctx
->remaining
, lenp
, &endstr
, 10)
281 || endstr
== lenp
|| *endstr
|| ctx
->remaining
< 0) {
284 ap_log_rerror(APLOG_MARK
, APLOG_ERR
, 0, f
->r
,
285 "Invalid Content-Length");
287 return bail_out_on_error(ctx
, f
, HTTP_REQUEST_ENTITY_TOO_LARGE
);
290 /* If we have a limit in effect and we know the C-L ahead of
291 * time, stop it here if it is invalid.
293 if (ctx
->limit
&& ctx
->limit
< ctx
->remaining
) {
294 ap_log_rerror(APLOG_MARK
, APLOG_ERR
, 0, f
->r
,
295 "Requested content-length of %" APR_OFF_T_FMT
296 " is larger than the configured limit"
297 " of %" APR_OFF_T_FMT
, ctx
->remaining
, ctx
->limit
);
298 return bail_out_on_error(ctx
, f
, HTTP_REQUEST_ENTITY_TOO_LARGE
);
302 /* If we don't have a request entity indicated by the headers, EOS.
303 * (BODY_NONE is a valid intermediate state due to trailers,
304 * but it isn't a valid starting state.)
306 * RFC 2616 Section 4.4 note 5 states that connection-close
307 * is invalid for a request entity - request bodies must be
308 * denoted by C-L or T-E: chunked.
310 * Note that since the proxy uses this filter to handle the
311 * proxied *response*, proxy responses MUST be exempt.
313 if (ctx
->state
== BODY_NONE
&& f
->r
->proxyreq
!= PROXYREQ_RESPONSE
) {
314 e
= apr_bucket_eos_create(f
->c
->bucket_alloc
);
315 APR_BRIGADE_INSERT_TAIL(b
, e
);
320 /* Since we're about to read data, send 100-Continue if needed.
321 * Only valid on chunked and C-L bodies where the C-L is > 0. */
322 if ((ctx
->state
== BODY_CHUNK
||
323 (ctx
->state
== BODY_LENGTH
&& ctx
->remaining
> 0)) &&
324 f
->r
->expecting_100
&& f
->r
->proto_num
>= HTTP_VERSION(1,1) &&
325 !(f
->r
->eos_sent
|| f
->r
->bytes_sent
)) {
326 if (!ap_is_HTTP_SUCCESS(f
->r
->status
)) {
327 ctx
->state
= BODY_NONE
;
333 tmp
= apr_pstrcat(f
->r
->pool
, AP_SERVER_PROTOCOL
, " ",
334 ap_get_status_line(100), CRLF CRLF
, NULL
);
336 ap_xlate_proto_to_ascii(tmp
, len
);
337 apr_brigade_cleanup(bb
);
338 e
= apr_bucket_pool_create(tmp
, len
, f
->r
->pool
,
340 APR_BRIGADE_INSERT_HEAD(bb
, e
);
341 e
= apr_bucket_flush_create(f
->c
->bucket_alloc
);
342 APR_BRIGADE_INSERT_TAIL(bb
, e
);
344 ap_pass_brigade(f
->c
->output_filters
, bb
);
348 /* We can't read the chunk until after sending 100 if required. */
349 if (ctx
->state
== BODY_CHUNK
) {
350 apr_brigade_cleanup(bb
);
352 rv
= ap_get_brigade(f
->next
, bb
, AP_MODE_GETLINE
,
356 if (block
== APR_NONBLOCK_READ
&&
357 ( (rv
== APR_SUCCESS
&& APR_BRIGADE_EMPTY(bb
)) ||
358 (APR_STATUS_IS_EAGAIN(rv
)) )) {
359 ctx
->state
= BODY_CHUNK_PART
;
363 if (rv
== APR_SUCCESS
) {
364 rv
= get_chunk_line(ctx
, bb
, f
->r
->server
->limit_req_line
);
365 if (APR_STATUS_IS_EAGAIN(rv
)) {
366 apr_brigade_cleanup(bb
);
367 ctx
->state
= BODY_CHUNK_PART
;
370 if (rv
== APR_SUCCESS
) {
371 ctx
->remaining
= get_chunk_size(ctx
->chunk_ln
);
372 if (ctx
->remaining
== INVALID_CHAR
) {
374 http_error
= HTTP_SERVICE_UNAVAILABLE
;
378 apr_brigade_cleanup(bb
);
380 /* Detect chunksize error (such as overflow) */
381 if (rv
!= APR_SUCCESS
|| ctx
->remaining
< 0) {
382 ctx
->remaining
= 0; /* Reset it in case we have to
383 * come back here later */
384 return bail_out_on_error(ctx
, f
, http_error
);
387 if (!ctx
->remaining
) {
388 /* Handle trailers by calling ap_get_mime_headers again! */
389 ctx
->state
= BODY_NONE
;
390 ap_get_mime_headers(f
->r
);
391 e
= apr_bucket_eos_create(f
->c
->bucket_alloc
);
392 APR_BRIGADE_INSERT_TAIL(b
, e
);
403 e
= apr_bucket_eos_create(f
->c
->bucket_alloc
);
404 APR_BRIGADE_INSERT_TAIL(b
, e
);
408 if (!ctx
->remaining
) {
409 switch (ctx
->state
) {
413 e
= apr_bucket_eos_create(f
->c
->bucket_alloc
);
414 APR_BRIGADE_INSERT_TAIL(b
, e
);
418 case BODY_CHUNK_PART
:
420 apr_brigade_cleanup(bb
);
422 /* We need to read the CRLF after the chunk. */
423 if (ctx
->state
== BODY_CHUNK
) {
424 rv
= ap_get_brigade(f
->next
, bb
, AP_MODE_GETLINE
,
426 if (block
== APR_NONBLOCK_READ
&&
427 ( (rv
== APR_SUCCESS
&& APR_BRIGADE_EMPTY(bb
)) ||
428 (APR_STATUS_IS_EAGAIN(rv
)) )) {
431 /* If we get an error, then leave */
432 if (rv
!= APR_SUCCESS
) {
436 * We really don't care whats on this line. If it is RFC
437 * compliant it should be only \r\n. If there is more
438 * before we just ignore it as long as we do not get over
439 * the limit for request lines.
441 rv
= get_remaining_chunk_line(ctx
, bb
,
442 f
->r
->server
->limit_req_line
);
443 apr_brigade_cleanup(bb
);
444 if (APR_STATUS_IS_EAGAIN(rv
)) {
451 if (rv
== APR_SUCCESS
) {
452 /* Read the real chunk line. */
453 rv
= ap_get_brigade(f
->next
, bb
, AP_MODE_GETLINE
,
456 if (block
== APR_NONBLOCK_READ
&&
457 ( (rv
== APR_SUCCESS
&& APR_BRIGADE_EMPTY(bb
)) ||
458 (APR_STATUS_IS_EAGAIN(rv
)) )) {
459 ctx
->state
= BODY_CHUNK_PART
;
462 ctx
->state
= BODY_CHUNK
;
463 if (rv
== APR_SUCCESS
) {
464 rv
= get_chunk_line(ctx
, bb
, f
->r
->server
->limit_req_line
);
465 if (APR_STATUS_IS_EAGAIN(rv
)) {
466 ctx
->state
= BODY_CHUNK_PART
;
467 apr_brigade_cleanup(bb
);
470 if (rv
== APR_SUCCESS
) {
471 ctx
->remaining
= get_chunk_size(ctx
->chunk_ln
);
472 if (ctx
->remaining
== INVALID_CHAR
) {
474 http_error
= HTTP_SERVICE_UNAVAILABLE
;
478 apr_brigade_cleanup(bb
);
481 /* Detect chunksize error (such as overflow) */
482 if (rv
!= APR_SUCCESS
|| ctx
->remaining
< 0) {
483 ctx
->remaining
= 0; /* Reset it in case we have to
484 * come back here later */
485 bail_out_on_error(ctx
, f
, http_error
);
489 if (!ctx
->remaining
) {
490 /* Handle trailers by calling ap_get_mime_headers again! */
491 ctx
->state
= BODY_NONE
;
492 ap_get_mime_headers(f
->r
);
493 e
= apr_bucket_eos_create(f
->c
->bucket_alloc
);
494 APR_BRIGADE_INSERT_TAIL(b
, e
);
503 /* Ensure that the caller can not go over our boundary point. */
504 if (ctx
->state
== BODY_LENGTH
|| ctx
->state
== BODY_CHUNK
) {
505 if (ctx
->remaining
< readbytes
) {
506 readbytes
= ctx
->remaining
;
508 AP_DEBUG_ASSERT(readbytes
> 0);
511 rv
= ap_get_brigade(f
->next
, b
, mode
, block
, readbytes
);
513 if (rv
!= APR_SUCCESS
) {
517 /* How many bytes did we just read? */
518 apr_brigade_length(b
, 0, &totalread
);
520 /* If this happens, we have a bucket of unknown length. Die because
521 * it means our assumptions have changed. */
522 AP_DEBUG_ASSERT(totalread
>= 0);
524 if (ctx
->state
!= BODY_NONE
) {
525 ctx
->remaining
-= totalread
;
528 /* If we have no more bytes remaining on a C-L request,
529 * save the callter a roundtrip to discover EOS.
531 if (ctx
->state
== BODY_LENGTH
&& ctx
->remaining
== 0) {
532 e
= apr_bucket_eos_create(f
->c
->bucket_alloc
);
533 APR_BRIGADE_INSERT_TAIL(b
, e
);
536 /* We have a limit in effect. */
538 /* FIXME: Note that we might get slightly confused on chunked inputs
539 * as we'd need to compensate for the chunk lengths which may not
540 * really count. This seems to be up for interpretation. */
541 ctx
->limit_used
+= totalread
;
542 if (ctx
->limit
< ctx
->limit_used
) {
543 ap_log_rerror(APLOG_MARK
, APLOG_ERR
, 0, f
->r
,
544 "Read content-length of %" APR_OFF_T_FMT
545 " is larger than the configured limit"
546 " of %" APR_OFF_T_FMT
, ctx
->limit_used
, ctx
->limit
);
547 apr_brigade_cleanup(bb
);
548 e
= ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE
, NULL
,
551 APR_BRIGADE_INSERT_TAIL(bb
, e
);
552 e
= apr_bucket_eos_create(f
->c
->bucket_alloc
);
553 APR_BRIGADE_INSERT_TAIL(bb
, e
);
555 return ap_pass_brigade(f
->r
->output_filters
, bb
);
563 * Parse a chunk extension, detect overflow.
564 * There are two error cases:
565 * 1) If the conversion would require too many bits, a -1 is returned.
566 * 2) If the conversion used the correct number of bits, but an overflow
567 * caused only the sign bit to flip, then that negative number is
569 * In general, any negative number can be considered an overflow error.
571 static long get_chunk_size(char *b
)
574 size_t chunkbits
= sizeof(long) * 8;
576 ap_xlate_proto_from_ascii(b
, strlen(b
));
578 if (!apr_isxdigit(*b
)) {
580 * Detect invalid character at beginning. This also works for empty
585 /* Skip leading zeros */
590 while (apr_isxdigit(*b
) && (chunkbits
> 0)) {
593 if (*b
>= '0' && *b
<= '9') {
596 else if (*b
>= 'A' && *b
<= 'F') {
597 xvalue
= *b
- 'A' + 0xa;
599 else if (*b
>= 'a' && *b
<= 'f') {
600 xvalue
= *b
- 'a' + 0xa;
603 chunksize
= (chunksize
<< 4) | xvalue
;
607 if (apr_isxdigit(*b
) && (chunkbits
<= 0)) {
615 typedef struct header_struct
{
617 apr_bucket_brigade
*bb
;
620 /* Send a single HTTP header field to the client. Note that this function
621 * is used in calls to table_do(), so their interfaces are co-dependent.
622 * In other words, don't change this one without checking table_do in alloc.c.
623 * It returns true unless there was a write error of some kind.
625 static int form_header_field(header_struct
*h
,
626 const char *fieldname
, const char *fieldval
)
628 #if APR_CHARSET_EBCDIC
635 name_len
= strlen(fieldname
);
636 val_len
= strlen(fieldval
);
637 len
= name_len
+ val_len
+ 4; /* 4 for ": " plus CRLF */
638 headfield
= (char *)apr_palloc(h
->pool
, len
+ 1);
639 memcpy(headfield
, fieldname
, name_len
);
640 next
= headfield
+ name_len
;
643 memcpy(next
, fieldval
, val_len
);
648 ap_xlate_proto_to_ascii(headfield
, len
);
649 apr_brigade_write(h
->bb
, NULL
, NULL
, headfield
, len
);
652 struct iovec
*v
= vec
;
653 v
->iov_base
= (void *)fieldname
;
654 v
->iov_len
= strlen(fieldname
);
657 v
->iov_len
= sizeof(": ") - 1;
659 v
->iov_base
= (void *)fieldval
;
660 v
->iov_len
= strlen(fieldval
);
663 v
->iov_len
= sizeof(CRLF
) - 1;
664 apr_brigade_writev(h
->bb
, NULL
, NULL
, vec
, 4);
665 #endif /* !APR_CHARSET_EBCDIC */
669 /* This routine is called by apr_table_do and merges all instances of
670 * the passed field values into a single array that will be further
671 * processed by some later routine. Originally intended to help split
672 * and recombine multiple Vary fields, though it is generic to any field
673 * consisting of comma/space-separated tokens.
675 static int uniq_field_values(void *d
, const char *key
, const char *val
)
677 apr_array_header_t
*values
;
683 values
= (apr_array_header_t
*)d
;
685 e
= apr_pstrdup(values
->pool
, val
);
688 /* Find a non-empty fieldname */
690 while (*e
== ',' || apr_isspace(*e
)) {
697 while (*e
!= '\0' && *e
!= ',' && !apr_isspace(*e
)) {
704 /* Now add it to values if it isn't already represented.
705 * Could be replaced by a ap_array_strcasecmp() if we had one.
707 for (i
= 0, strpp
= (char **) values
->elts
; i
< values
->nelts
;
709 if (*strpp
&& strcasecmp(*strpp
, start
) == 0) {
713 if (i
== values
->nelts
) { /* if not found */
714 *(char **)apr_array_push(values
) = start
;
716 } while (*e
!= '\0');
722 * Since some clients choke violently on multiple Vary fields, or
723 * Vary fields with duplicate tokens, combine any multiples and remove
726 static void fixup_vary(request_rec
*r
)
728 apr_array_header_t
*varies
;
730 varies
= apr_array_make(r
->pool
, 5, sizeof(char *));
732 /* Extract all Vary fields from the headers_out, separate each into
733 * its comma-separated fieldname values, and then add them to varies
734 * if not already present in the array.
736 apr_table_do((int (*)(void *, const char *, const char *))uniq_field_values
,
737 (void *) varies
, r
->headers_out
, "Vary", NULL
);
739 /* If we found any, replace old Vary fields with unique-ified value */
741 if (varies
->nelts
> 0) {
742 apr_table_setn(r
->headers_out
, "Vary",
743 apr_array_pstrcat(r
->pool
, varies
, ','));
747 /* Send a request's HTTP response headers to the client.
749 static apr_status_t
send_all_header_fields(header_struct
*h
,
750 const request_rec
*r
)
752 const apr_array_header_t
*elts
;
753 const apr_table_entry_t
*t_elt
;
754 const apr_table_entry_t
*t_end
;
756 struct iovec
*vec_next
;
758 elts
= apr_table_elts(r
->headers_out
);
759 if (elts
->nelts
== 0) {
762 t_elt
= (const apr_table_entry_t
*)(elts
->elts
);
763 t_end
= t_elt
+ elts
->nelts
;
764 vec
= (struct iovec
*)apr_palloc(h
->pool
, 4 * elts
->nelts
*
765 sizeof(struct iovec
));
768 /* For each field, generate
769 * name ": " value CRLF
772 vec_next
->iov_base
= (void*)(t_elt
->key
);
773 vec_next
->iov_len
= strlen(t_elt
->key
);
775 vec_next
->iov_base
= ": ";
776 vec_next
->iov_len
= sizeof(": ") - 1;
778 vec_next
->iov_base
= (void*)(t_elt
->val
);
779 vec_next
->iov_len
= strlen(t_elt
->val
);
781 vec_next
->iov_base
= CRLF
;
782 vec_next
->iov_len
= sizeof(CRLF
) - 1;
785 } while (t_elt
< t_end
);
787 #if APR_CHARSET_EBCDIC
790 char *tmp
= apr_pstrcatv(r
->pool
, vec
, vec_next
- vec
, &len
);
791 ap_xlate_proto_to_ascii(tmp
, len
);
792 return apr_brigade_write(h
->bb
, NULL
, NULL
, tmp
, len
);
795 return apr_brigade_writev(h
->bb
, NULL
, NULL
, vec
, vec_next
- vec
);
799 /* Confirm that the status line is well-formed and matches r->status.
800 * If they don't match, a filter may have negated the status line set by a
802 * Zap r->status_line if bad.
804 static void validate_status_line(request_rec
*r
)
808 if (r
->status_line
) {
809 int len
= strlen(r
->status_line
);
811 || apr_strtoi64(r
->status_line
, &end
, 10) != r
->status
812 || (end
- 3) != r
->status_line
813 || (len
>= 4 && ! apr_isspace(r
->status_line
[3]))) {
814 r
->status_line
= NULL
;
816 /* Since we passed the above check, we know that length three
817 * is equivalent to only a 3 digit numeric http status.
818 * RFC2616 mandates a trailing space, let's add it.
821 r
->status_line
= apr_pstrcat(r
->pool
, r
->status_line
, " ", NULL
);
827 * Determine the protocol to use for the response. Potentially downgrade
828 * to HTTP/1.0 in some situations and/or turn off keepalives.
830 * also prepare r->status_line.
832 static void basic_http_header_check(request_rec
*r
,
833 const char **protocol
)
835 if (r
->assbackwards
) {
836 /* no such thing as a response protocol */
840 validate_status_line(r
);
842 if (!r
->status_line
) {
843 r
->status_line
= ap_get_status_line(r
->status
);
846 /* Note that we must downgrade before checking for force responses. */
847 if (r
->proto_num
> HTTP_VERSION(1,0)
848 && apr_table_get(r
->subprocess_env
, "downgrade-1.0")) {
849 r
->proto_num
= HTTP_VERSION(1,0);
852 /* kludge around broken browsers when indicated by force-response-1.0
854 if (r
->proto_num
== HTTP_VERSION(1,0)
855 && apr_table_get(r
->subprocess_env
, "force-response-1.0")) {
856 *protocol
= "HTTP/1.0";
857 r
->connection
->keepalive
= AP_CONN_CLOSE
;
860 *protocol
= AP_SERVER_PROTOCOL
;
865 /* fill "bb" with a barebones/initial HTTP response header */
866 static void basic_http_header(request_rec
*r
, apr_bucket_brigade
*bb
,
867 const char *protocol
)
874 if (r
->assbackwards
) {
875 /* there are no headers to send */
879 /* Output the HTTP/1.x Status-Line and the Date and Server fields */
881 vec
[0].iov_base
= (void *)protocol
;
882 vec
[0].iov_len
= strlen(protocol
);
883 vec
[1].iov_base
= (void *)" ";
884 vec
[1].iov_len
= sizeof(" ") - 1;
885 vec
[2].iov_base
= (void *)(r
->status_line
);
886 vec
[2].iov_len
= strlen(r
->status_line
);
887 vec
[3].iov_base
= (void *)CRLF
;
888 vec
[3].iov_len
= sizeof(CRLF
) - 1;
889 #if APR_CHARSET_EBCDIC
893 tmp
= apr_pstrcatv(r
->pool
, vec
, 4, &len
);
894 ap_xlate_proto_to_ascii(tmp
, len
);
895 apr_brigade_write(bb
, NULL
, NULL
, tmp
, len
);
898 apr_brigade_writev(bb
, NULL
, NULL
, vec
, 4);
905 * keep the set-by-proxy server and date headers, otherwise
906 * generate a new server header / date header
908 if (r
->proxyreq
!= PROXYREQ_NONE
) {
909 const char *proxy_date
;
911 proxy_date
= apr_table_get(r
->headers_out
, "Date");
914 * proxy_date needs to be const. So use date for the creation of
915 * our own Date header and pass it over to proxy_date later to
916 * avoid a compiler warning.
918 date
= apr_palloc(r
->pool
, APR_RFC822_DATE_LEN
);
919 ap_recent_rfc822_date(date
, r
->request_time
);
922 form_header_field(&h
, "Date", proxy_date
);
923 server
= apr_table_get(r
->headers_out
, "Server");
925 form_header_field(&h
, "Server", server
);
927 form_header_field(&h
, "Server", ap_get_server_banner());
931 date
= apr_palloc(r
->pool
, APR_RFC822_DATE_LEN
);
932 ap_recent_rfc822_date(date
, r
->request_time
);
933 form_header_field(&h
, "Date", date
);
934 form_header_field(&h
, "Server", ap_get_server_banner());
937 /* unset so we don't send them again */
938 apr_table_unset(r
->headers_out
, "Date"); /* Avoid bogosity */
939 apr_table_unset(r
->headers_out
, "Server");
942 AP_DECLARE(void) ap_basic_http_header(request_rec
*r
, apr_bucket_brigade
*bb
)
944 const char *protocol
;
946 basic_http_header_check(r
, &protocol
);
947 basic_http_header(r
, bb
, protocol
);
950 static void terminate_header(apr_bucket_brigade
*bb
)
955 buflen
= strlen(crlf
);
956 ap_xlate_proto_to_ascii(crlf
, buflen
);
957 apr_brigade_write(bb
, NULL
, NULL
, crlf
, buflen
);
960 AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec
*r
)
962 core_server_config
*conf
;
964 apr_bucket_brigade
*bb
;
968 char *bodyread
= NULL
, *bodyoff
;
969 apr_size_t bodylen
= 0;
971 long res
= -1; /* init to avoid gcc -Wall warning */
973 if (r
->method_number
!= M_TRACE
) {
977 /* Get the original request */
981 conf
= (core_server_config
*)ap_get_module_config(r
->server
->module_config
,
984 if (conf
->trace_enable
== AP_TRACE_DISABLE
) {
985 apr_table_setn(r
->notes
, "error-notes",
986 "TRACE denied by server configuration");
987 return HTTP_METHOD_NOT_ALLOWED
;
990 if (conf
->trace_enable
== AP_TRACE_EXTENDED
)
991 /* XX should be = REQUEST_CHUNKED_PASS */
992 body
= REQUEST_CHUNKED_DECHUNK
;
994 body
= REQUEST_NO_BODY
;
996 if ((rv
= ap_setup_client_block(r
, body
))) {
997 if (rv
== HTTP_REQUEST_ENTITY_TOO_LARGE
)
998 apr_table_setn(r
->notes
, "error-notes",
999 "TRACE with a request body is not allowed");
1003 if (ap_should_client_block(r
)) {
1005 if (r
->remaining
> 0) {
1006 if (r
->remaining
> 65536) {
1007 apr_table_setn(r
->notes
, "error-notes",
1008 "Extended TRACE request bodies cannot exceed 64k\n");
1009 return HTTP_REQUEST_ENTITY_TOO_LARGE
;
1011 /* always 32 extra bytes to catch chunk header exceptions */
1012 bodybuf
= (apr_size_t
)r
->remaining
+ 32;
1015 /* Add an extra 8192 for chunk headers */
1019 bodyoff
= bodyread
= apr_palloc(r
->pool
, bodybuf
);
1021 /* only while we have enough for a chunked header */
1022 while ((!bodylen
|| bodybuf
>= 32) &&
1023 (res
= ap_get_client_block(r
, bodyoff
, bodybuf
)) > 0) {
1028 if (res
> 0 && bodybuf
< 32) {
1029 /* discard_rest_of_request_body into our buffer */
1030 while (ap_get_client_block(r
, bodyread
, bodylen
) > 0)
1032 apr_table_setn(r
->notes
, "error-notes",
1033 "Extended TRACE request bodies cannot exceed 64k\n");
1034 return HTTP_REQUEST_ENTITY_TOO_LARGE
;
1038 return HTTP_BAD_REQUEST
;
1042 ap_set_content_type(r
, "message/http");
1044 /* Now we recreate the request, and echo it back */
1046 bb
= apr_brigade_create(r
->pool
, r
->connection
->bucket_alloc
);
1047 #if APR_CHARSET_EBCDIC
1051 len
= strlen(r
->the_request
);
1052 tmp
= apr_pmemdup(r
->pool
, r
->the_request
, len
);
1053 ap_xlate_proto_to_ascii(tmp
, len
);
1054 apr_brigade_putstrs(bb
, NULL
, NULL
, tmp
, CRLF_ASCII
, NULL
);
1057 apr_brigade_putstrs(bb
, NULL
, NULL
, r
->the_request
, CRLF
, NULL
);
1061 apr_table_do((int (*) (void *, const char *, const char *))
1062 form_header_field
, (void *) &h
, r
->headers_in
, NULL
);
1063 apr_brigade_puts(bb
, NULL
, NULL
, CRLF_ASCII
);
1065 /* If configured to accept a body, echo the body */
1067 b
= apr_bucket_pool_create(bodyread
, bodylen
,
1068 r
->pool
, bb
->bucket_alloc
);
1069 APR_BRIGADE_INSERT_TAIL(bb
, b
);
1072 ap_pass_brigade(r
->output_filters
, bb
);
1077 typedef struct header_filter_ctx
{
1079 } header_filter_ctx
;
1081 AP_CORE_DECLARE_NONSTD(apr_status_t
) ap_http_header_filter(ap_filter_t
*f
,
1082 apr_bucket_brigade
*b
)
1084 request_rec
*r
= f
->r
;
1085 conn_rec
*c
= r
->connection
;
1086 const char *clheader
;
1087 const char *protocol
;
1089 apr_bucket_brigade
*b2
;
1091 header_filter_ctx
*ctx
= f
->ctx
;
1093 ap_bucket_error
*eb
= NULL
;
1095 AP_DEBUG_ASSERT(!r
->main
);
1097 if (r
->header_only
) {
1099 ctx
= f
->ctx
= apr_pcalloc(r
->pool
, sizeof(header_filter_ctx
));
1101 else if (ctx
->headers_sent
) {
1102 apr_brigade_destroy(b
);
1107 for (e
= APR_BRIGADE_FIRST(b
);
1108 e
!= APR_BRIGADE_SENTINEL(b
);
1109 e
= APR_BUCKET_NEXT(e
))
1111 if (AP_BUCKET_IS_ERROR(e
) && !eb
) {
1116 * If we see an EOC bucket it is a signal that we should get out
1117 * of the way doing nothing.
1119 if (AP_BUCKET_IS_EOC(e
)) {
1120 ap_remove_output_filter(f
);
1121 return ap_pass_brigade(f
->next
, b
);
1127 status
= eb
->status
;
1128 apr_brigade_cleanup(b
);
1130 return AP_FILTER_ERROR
;
1133 if (r
->assbackwards
) {
1135 ap_remove_output_filter(f
);
1136 return ap_pass_brigade(f
->next
, b
);
1140 * Now that we are ready to send a response, we need to combine the two
1141 * header field tables into a single table. If we don't do this, our
1142 * later attempts to set or unset a given fieldname might be bypassed.
1144 if (!apr_is_empty_table(r
->err_headers_out
)) {
1145 r
->headers_out
= apr_table_overlay(r
->pool
, r
->err_headers_out
,
1150 * Remove the 'Vary' header field if the client can't handle it.
1151 * Since this will have nasty effects on HTTP/1.1 caches, force
1152 * the response into HTTP/1.0 mode.
1154 * Note: the force-response-1.0 should come before the call to
1155 * basic_http_header_check()
1157 if (apr_table_get(r
->subprocess_env
, "force-no-vary") != NULL
) {
1158 apr_table_unset(r
->headers_out
, "Vary");
1159 r
->proto_num
= HTTP_VERSION(1,0);
1160 apr_table_set(r
->subprocess_env
, "force-response-1.0", "1");
1167 * Now remove any ETag response header field if earlier processing
1168 * says so (such as a 'FileETag None' directive).
1170 if (apr_table_get(r
->notes
, "no-etag") != NULL
) {
1171 apr_table_unset(r
->headers_out
, "ETag");
1174 /* determine the protocol and whether we should use keepalives. */
1175 basic_http_header_check(r
, &protocol
);
1176 ap_set_keepalive(r
);
1179 apr_table_mergen(r
->headers_out
, "Transfer-Encoding", "chunked");
1180 apr_table_unset(r
->headers_out
, "Content-Length");
1183 ctype
= ap_make_content_type(r
, r
->content_type
);
1185 apr_table_setn(r
->headers_out
, "Content-Type", ctype
);
1188 if (r
->content_encoding
) {
1189 apr_table_setn(r
->headers_out
, "Content-Encoding",
1190 r
->content_encoding
);
1193 if (!apr_is_empty_array(r
->content_languages
)) {
1196 char **languages
= (char **)(r
->content_languages
->elts
);
1197 const char *field
= apr_table_get(r
->headers_out
, "Content-Language");
1199 while (field
&& (token
= ap_get_list_item(r
->pool
, &field
)) != NULL
) {
1200 for (i
= 0; i
< r
->content_languages
->nelts
; ++i
) {
1201 if (!strcasecmp(token
, languages
[i
]))
1204 if (i
== r
->content_languages
->nelts
) {
1205 *((char **) apr_array_push(r
->content_languages
)) = token
;
1209 field
= apr_array_pstrcat(r
->pool
, r
->content_languages
, ',');
1210 apr_table_setn(r
->headers_out
, "Content-Language", field
);
1214 * Control cachability for non-cachable responses if not already set by
1215 * some other part of the server configuration.
1217 if (r
->no_cache
&& !apr_table_get(r
->headers_out
, "Expires")) {
1218 char *date
= apr_palloc(r
->pool
, APR_RFC822_DATE_LEN
);
1219 ap_recent_rfc822_date(date
, r
->request_time
);
1220 apr_table_addn(r
->headers_out
, "Expires", date
);
1223 /* This is a hack, but I can't find anyway around it. The idea is that
1224 * we don't want to send out 0 Content-Lengths if it is a head request.
1225 * This happens when modules try to outsmart the server, and return
1226 * if they see a HEAD request. Apache 1.3 handlers were supposed to
1227 * just return in that situation, and the core handled the HEAD. In
1228 * 2.0, if a handler returns, then the core sends an EOS bucket down
1229 * the filter stack, and the content-length filter computes a C-L of
1230 * zero and that gets put in the headers, and we end up sending a
1231 * zero C-L to the client. We can't just remove the C-L filter,
1232 * because well behaved 2.0 handlers will send their data down the stack,
1233 * and we will compute a real C-L for the head request. RBB
1236 && (clheader
= apr_table_get(r
->headers_out
, "Content-Length"))
1237 && !strcmp(clheader
, "0")) {
1238 apr_table_unset(r
->headers_out
, "Content-Length");
1241 b2
= apr_brigade_create(r
->pool
, c
->bucket_alloc
);
1242 basic_http_header(r
, b2
, protocol
);
1247 if (r
->status
== HTTP_NOT_MODIFIED
) {
1248 apr_table_do((int (*)(void *, const char *, const char *)) form_header_field
,
1249 (void *) &h
, r
->headers_out
,
1259 "Proxy-Authenticate",
1265 send_all_header_fields(&h
, r
);
1268 terminate_header(b2
);
1270 ap_pass_brigade(f
->next
, b2
);
1272 if (r
->header_only
) {
1273 apr_brigade_destroy(b
);
1274 ctx
->headers_sent
= 1;
1278 r
->sent_bodyct
= 1; /* Whatever follows is real body stuff... */
1281 /* We can't add this filter until we have already sent the headers.
1282 * If we add it before this point, then the headers will be chunked
1283 * as well, and that is just wrong.
1285 ap_add_output_filter("CHUNK", NULL
, r
, r
->connection
);
1288 /* Don't remove this filter until after we have added the CHUNK filter.
1289 * Otherwise, f->next won't be the CHUNK filter and thus the first
1290 * brigade won't be chunked properly.
1292 ap_remove_output_filter(f
);
1293 return ap_pass_brigade(f
->next
, b
);
1296 /* In HTTP/1.1, any method can have a body. However, most GET handlers
1297 * wouldn't know what to do with a request body if they received one.
1298 * This helper routine tests for and reads any message body in the request,
1299 * simply discarding whatever it receives. We need to do this because
1300 * failing to read the request body would cause it to be interpreted
1301 * as the next request on a persistent connection.
1303 * Since we return an error status if the request is malformed, this
1304 * routine should be called at the beginning of a no-body handler, e.g.,
1306 * if ((retval = ap_discard_request_body(r)) != OK) {
1310 AP_DECLARE(int) ap_discard_request_body(request_rec
*r
)
1312 apr_bucket_brigade
*bb
;
1315 /* Sometimes we'll get in a state where the input handling has
1316 * detected an error where we want to drop the connection, so if
1317 * that's the case, don't read the data as that is what we're trying
1320 * This function is also a no-op on a subrequest.
1322 if (r
->main
|| r
->connection
->keepalive
== AP_CONN_CLOSE
||
1323 ap_status_drops_connection(r
->status
)) {
1327 bb
= apr_brigade_create(r
->pool
, r
->connection
->bucket_alloc
);
1332 rv
= ap_get_brigade(r
->input_filters
, bb
, AP_MODE_READBYTES
,
1333 APR_BLOCK_READ
, HUGE_STRING_LEN
);
1335 if (rv
!= APR_SUCCESS
) {
1336 /* FIXME: If we ever have a mapping from filters (apr_status_t)
1337 * to HTTP error codes, this would be a good place for them.
1339 * If we received the special case AP_FILTER_ERROR, it means
1340 * that the filters have already handled this error.
1341 * Otherwise, we should assume we have a bad request.
1343 if (rv
== AP_FILTER_ERROR
) {
1344 apr_brigade_destroy(bb
);
1348 apr_brigade_destroy(bb
);
1349 return HTTP_BAD_REQUEST
;
1353 for (bucket
= APR_BRIGADE_FIRST(bb
);
1354 bucket
!= APR_BRIGADE_SENTINEL(bb
);
1355 bucket
= APR_BUCKET_NEXT(bucket
))
1360 if (APR_BUCKET_IS_EOS(bucket
)) {
1365 /* These are metadata buckets. */
1366 if (bucket
->length
== 0) {
1370 /* We MUST read because in case we have an unknown-length
1371 * bucket or one that morphs, we want to exhaust it.
1373 rv
= apr_bucket_read(bucket
, &data
, &len
, APR_BLOCK_READ
);
1374 if (rv
!= APR_SUCCESS
) {
1375 apr_brigade_destroy(bb
);
1376 return HTTP_BAD_REQUEST
;
1379 apr_brigade_cleanup(bb
);
1380 } while (!seen_eos
);
1385 /* Here we deal with getting the request message body from the client.
1386 * Whether or not the request contains a body is signaled by the presence
1387 * of a non-zero Content-Length or by a Transfer-Encoding: chunked.
1389 * Note that this is more complicated than it was in Apache 1.1 and prior
1390 * versions, because chunked support means that the module does less.
1392 * The proper procedure is this:
1394 * 1. Call ap_setup_client_block() near the beginning of the request
1395 * handler. This will set up all the necessary properties, and will
1396 * return either OK, or an error code. If the latter, the module should
1397 * return that error code. The second parameter selects the policy to
1398 * apply if the request message indicates a body, and how a chunked
1399 * transfer-coding should be interpreted. Choose one of
1401 * REQUEST_NO_BODY Send 413 error if message has any body
1402 * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
1403 * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
1404 * REQUEST_CHUNKED_PASS If chunked, pass the chunk headers with body.
1406 * In order to use the last two options, the caller MUST provide a buffer
1407 * large enough to hold a chunk-size line, including any extensions.
1409 * 2. When you are ready to read a body (if any), call ap_should_client_block().
1410 * This will tell the module whether or not to read input. If it is 0,
1411 * the module should assume that there is no message body to read.
1413 * 3. Finally, call ap_get_client_block in a loop. Pass it a buffer and its size.
1414 * It will put data into the buffer (not necessarily a full buffer), and
1415 * return the length of the input block. When it is done reading, it will
1416 * return 0 if EOF, or -1 if there was an error.
1417 * If an error occurs on input, we force an end to keepalive.
1419 * This step also sends a 100 Continue response to HTTP/1.1 clients if appropriate.
1422 AP_DECLARE(int) ap_setup_client_block(request_rec
*r
, int read_policy
)
1424 const char *tenc
= apr_table_get(r
->headers_in
, "Transfer-Encoding");
1425 const char *lenp
= apr_table_get(r
->headers_in
, "Content-Length");
1427 r
->read_body
= read_policy
;
1428 r
->read_chunked
= 0;
1432 if (strcasecmp(tenc
, "chunked")) {
1433 ap_log_rerror(APLOG_MARK
, APLOG_ERR
, 0, r
,
1434 "Unknown Transfer-Encoding %s", tenc
);
1435 return HTTP_NOT_IMPLEMENTED
;
1437 if (r
->read_body
== REQUEST_CHUNKED_ERROR
) {
1438 ap_log_rerror(APLOG_MARK
, APLOG_ERR
, 0, r
,
1439 "chunked Transfer-Encoding forbidden: %s", r
->uri
);
1440 return (lenp
) ? HTTP_BAD_REQUEST
: HTTP_LENGTH_REQUIRED
;
1443 r
->read_chunked
= 1;
1448 if (apr_strtoff(&r
->remaining
, lenp
, &endstr
, 10)
1449 || *endstr
|| r
->remaining
< 0) {
1451 ap_log_rerror(APLOG_MARK
, APLOG_ERR
, 0, r
,
1452 "Invalid Content-Length");
1453 return HTTP_BAD_REQUEST
;
1457 if ((r
->read_body
== REQUEST_NO_BODY
)
1458 && (r
->read_chunked
|| (r
->remaining
> 0))) {
1459 ap_log_rerror(APLOG_MARK
, APLOG_ERR
, 0, r
,
1460 "%s with body is not allowed for %s", r
->method
, r
->uri
);
1461 return HTTP_REQUEST_ENTITY_TOO_LARGE
;
1466 /* Make sure ap_getline() didn't leave any droppings. */
1467 core_request_config
*req_cfg
=
1468 (core_request_config
*)ap_get_module_config(r
->request_config
,
1470 AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(req_cfg
->bb
));
1477 AP_DECLARE(int) ap_should_client_block(request_rec
*r
)
1479 /* First check if we have already read the request body */
1481 if (r
->read_length
|| (!r
->read_chunked
&& (r
->remaining
<= 0))) {
1488 /* get_client_block is called in a loop to get the request message body.
1489 * This is quite simple if the client includes a content-length
1490 * (the normal case), but gets messy if the body is chunked. Note that
1491 * r->remaining is used to maintain state across calls and that
1492 * r->read_length is the total number of bytes given to the caller
1493 * across all invocations. It is messy because we have to be careful not
1494 * to read past the data provided by the client, since these reads block.
1495 * Returns 0 on End-of-body, -1 on error or premature chunk end.
1498 AP_DECLARE(long) ap_get_client_block(request_rec
*r
, char *buffer
,
1502 apr_bucket_brigade
*bb
;
1504 if (r
->remaining
< 0 || (!r
->read_chunked
&& r
->remaining
== 0)) {
1508 bb
= apr_brigade_create(r
->pool
, r
->connection
->bucket_alloc
);
1510 r
->connection
->keepalive
= AP_CONN_CLOSE
;
1514 rv
= ap_get_brigade(r
->input_filters
, bb
, AP_MODE_READBYTES
,
1515 APR_BLOCK_READ
, bufsiz
);
1517 /* We lose the failure code here. This is why ap_get_client_block should
1520 if (rv
!= APR_SUCCESS
) {
1521 /* if we actually fail here, we want to just return and
1522 * stop trying to read data from the client.
1524 r
->connection
->keepalive
= AP_CONN_CLOSE
;
1525 apr_brigade_destroy(bb
);
1529 /* If this fails, it means that a filter is written incorrectly and that
1530 * it needs to learn how to properly handle APR_BLOCK_READ requests by
1531 * returning data when requested.
1533 AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(bb
));
1535 /* Check to see if EOS in the brigade.
1537 * If so, we have to leave a nugget for the *next* ap_get_client_block
1540 if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb
))) {
1541 if (r
->read_chunked
) {
1549 rv
= apr_brigade_flatten(bb
, buffer
, &bufsiz
);
1550 if (rv
!= APR_SUCCESS
) {
1551 apr_brigade_destroy(bb
);
1556 r
->read_length
+= bufsiz
;
1558 apr_brigade_destroy(bb
);
1562 /* Context struct for ap_http_outerror_filter */
1565 } outerror_filter_ctx_t
;
1567 /* Filter to handle any error buckets on output */
1568 apr_status_t
ap_http_outerror_filter(ap_filter_t
*f
,
1569 apr_bucket_brigade
*b
)
1571 request_rec
*r
= f
->r
;
1572 outerror_filter_ctx_t
*ctx
= (outerror_filter_ctx_t
*)(f
->ctx
);
1575 /* Create context if none is present */
1577 ctx
= apr_pcalloc(r
->pool
, sizeof(outerror_filter_ctx_t
));
1580 for (e
= APR_BRIGADE_FIRST(b
);
1581 e
!= APR_BRIGADE_SENTINEL(b
);
1582 e
= APR_BUCKET_NEXT(e
))
1584 if (AP_BUCKET_IS_ERROR(e
)) {
1586 * Start of error handling state tree. Just one condition
1589 if (((ap_bucket_error
*)(e
->data
))->status
== HTTP_BAD_GATEWAY
) {
1590 /* stream aborted and we have not ended it yet */
1591 r
->connection
->keepalive
= AP_CONN_CLOSE
;
1595 /* Detect EOC buckets and memorize this in the context. */
1596 if (AP_BUCKET_IS_EOC(e
)) {
1601 * Remove all data buckets that are in a brigade after an EOC bucket
1602 * was seen, as an EOC bucket tells us that no (further) resource
1603 * and protocol data should go out to the client. OTOH meta buckets
1604 * are still welcome as they might trigger needed actions down in
1605 * the chain (e.g. in network filters like SSL).
1606 * Remark 1: It is needed to dump ALL data buckets in the brigade
1607 * since an filter in between might have inserted data
1608 * buckets BEFORE the EOC bucket sent by the original
1609 * sender and we do NOT want this data to be sent.
1610 * Remark 2: Dumping all data buckets here does not necessarily mean
1611 * that no further data is send to the client as:
1612 * 1. Network filters like SSL can still be triggered via
1613 * meta buckets to talk with the client e.g. for a
1615 * 2. There could be still data that was buffered before
1616 * down in the chain that gets flushed by a FLUSH or an
1619 if (ctx
->seen_eoc
) {
1620 for (e
= APR_BRIGADE_FIRST(b
);
1621 e
!= APR_BRIGADE_SENTINEL(b
);
1622 e
= APR_BUCKET_NEXT(e
))
1624 if (!APR_BUCKET_IS_METADATA(e
)) {
1625 APR_BUCKET_REMOVE(e
);
1630 return ap_pass_brigade(f
->next
, b
);