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_log.h" /* For errors detected in basic auth common
43 #include "apr_date.h" /* For apr_date_parse_http and APR_DATE_BAD */
44 #include "util_charset.h"
45 #include "util_ebcdic.h"
46 #include "util_time.h"
57 #define INVALID_CHAR -2
59 extern module AP_MODULE_DECLARE_DATA http_module;
61 static long get_chunk_size(char *);
63 typedef struct http_filter_ctx {
77 apr_bucket_brigade *bb;
80 static apr_status_t bail_out_on_error(http_ctx_t *ctx,
85 apr_bucket_brigade *bb = ctx->bb;
87 apr_brigade_cleanup(bb);
88 e = ap_bucket_error_create(http_error,
91 APR_BRIGADE_INSERT_TAIL(bb, e);
92 e = apr_bucket_eos_create(f->c->bucket_alloc);
93 APR_BRIGADE_INSERT_TAIL(bb, e);
95 return ap_pass_brigade(f->r->output_filters, bb);
98 static apr_status_t get_remaining_chunk_line(http_ctx_t *ctx,
99 apr_bucket_brigade *b,
103 apr_off_t brigade_length;
109 * As the brigade b should have been requested in mode AP_MODE_GETLINE
110 * all buckets in this brigade are already some type of memory
111 * buckets (due to the needed scanning for LF in mode AP_MODE_GETLINE)
114 rv = apr_brigade_length(b, 0, &brigade_length);
115 if (rv != APR_SUCCESS) {
118 /* Sanity check. Should never happen. See above. */
119 if (brigade_length == -1) {
122 if (!brigade_length) {
125 ctx->linesize += brigade_length;
126 if (ctx->linesize > linelimit) {
130 * As all buckets are already some type of memory buckets or META buckets
131 * (see above), we only need to check the last byte in the last data bucket.
133 for (e = APR_BRIGADE_LAST(b);
134 e != APR_BRIGADE_SENTINEL(b);
135 e = APR_BUCKET_PREV(e)) {
137 if (APR_BUCKET_IS_METADATA(e)) {
140 rv = apr_bucket_read(e, &lineend, &len, APR_BLOCK_READ);
141 if (rv != APR_SUCCESS) {
145 break; /* we got the data we want */
147 /* If we got a zero-length data bucket, we try the next one */
149 /* We had no data in this brigade */
150 if (!len || e == APR_BRIGADE_SENTINEL(b)) {
153 if (lineend[len - 1] != APR_ASCII_LF) {
156 /* Line is complete. So reset ctx->linesize for next round. */
161 static apr_status_t get_chunk_line(http_ctx_t *ctx, apr_bucket_brigade *b,
168 tmp_len = sizeof(ctx->chunk_ln) - (ctx->pos - ctx->chunk_ln) - 1;
169 /* Saveguard ourselves against underflows */
174 len = (apr_size_t) tmp_len;
177 * Check if there is space left in ctx->chunk_ln. If not, then either
178 * the chunk size is insane or we have chunk-extensions. Ignore both
179 * by discarding the remaining part of the line via
180 * get_remaining_chunk_line. Only bail out if the line is too long.
183 rv = apr_brigade_flatten(b, ctx->pos, &len);
184 if (rv != APR_SUCCESS) {
188 ctx->linesize += len;
191 * Check if we really got a full line. If yes the
192 * last char in the just read buffer must be LF.
193 * If not advance the buffer and return APR_EAGAIN.
194 * We do not start processing until we have the
197 if (ctx->pos[-1] != APR_ASCII_LF) {
198 /* Check if the remaining data in the brigade has the LF */
199 return get_remaining_chunk_line(ctx, b, linelimit);
201 /* Line is complete. So reset ctx->pos for next round. */
202 ctx->pos = ctx->chunk_ln;
205 return get_remaining_chunk_line(ctx, b, linelimit);
209 /* This is the HTTP_INPUT filter for HTTP requests and responses from
210 * proxied servers (mod_proxy). It handles chunked and content-length
211 * bodies. This can only be inserted/used after the headers
212 * are successfully parsed.
214 apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
215 ap_input_mode_t mode, apr_read_type_e block,
219 http_ctx_t *ctx = f->ctx;
222 int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE;
223 apr_bucket_brigade *bb;
225 /* just get out of the way of things we don't want. */
226 if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
227 return ap_get_brigade(f->next, b, mode, block, readbytes);
231 const char *tenc, *lenp;
232 f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
233 ctx->state = BODY_NONE;
234 ctx->pos = ctx->chunk_ln;
235 ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
238 /* LimitRequestBody does not apply to proxied responses.
239 * Consider implementing this check in its own filter.
240 * Would adding a directive to limit the size of proxied
241 * responses be useful?
243 if (!f->r->proxyreq) {
244 ctx->limit = ap_get_limit_req_body(f->r);
250 tenc = apr_table_get(f->r->headers_in, "Transfer-Encoding");
251 lenp = apr_table_get(f->r->headers_in, "Content-Length");
254 if (!strcasecmp(tenc, "chunked")) {
255 ctx->state = BODY_CHUNK;
257 /* test lenp, because it gives another case we can handle */
259 /* Something that isn't in HTTP, unless some future
260 * edition defines new transfer ecodings, is unsupported.
262 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
263 "Unknown Transfer-Encoding: %s", tenc);
264 return bail_out_on_error(ctx, f, HTTP_NOT_IMPLEMENTED);
267 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, f->r,
268 "Unknown Transfer-Encoding: %s; using Content-Length", tenc);
275 ctx->state = BODY_LENGTH;
278 /* Protects against over/underflow, non-digit chars in the
279 * string (excluding leading space) (the endstr checks)
280 * and a negative number. */
281 if (apr_strtoff(&ctx->remaining, lenp, &endstr, 10)
282 || endstr == lenp || *endstr || ctx->remaining < 0) {
285 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
286 "Invalid Content-Length");
288 return bail_out_on_error(ctx, f, HTTP_REQUEST_ENTITY_TOO_LARGE);
291 /* If we have a limit in effect and we know the C-L ahead of
292 * time, stop it here if it is invalid.
294 if (ctx->limit && ctx->limit < ctx->remaining) {
295 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
296 "Requested content-length of %" APR_OFF_T_FMT
297 " is larger than the configured limit"
298 " of %" APR_OFF_T_FMT, ctx->remaining, ctx->limit);
299 return bail_out_on_error(ctx, f, HTTP_REQUEST_ENTITY_TOO_LARGE);
303 /* If we don't have a request entity indicated by the headers, EOS.
304 * (BODY_NONE is a valid intermediate state due to trailers,
305 * but it isn't a valid starting state.)
307 * RFC 2616 Section 4.4 note 5 states that connection-close
308 * is invalid for a request entity - request bodies must be
309 * denoted by C-L or T-E: chunked.
311 * Note that since the proxy uses this filter to handle the
312 * proxied *response*, proxy responses MUST be exempt.
314 if (ctx->state == BODY_NONE && f->r->proxyreq != PROXYREQ_RESPONSE) {
315 e = apr_bucket_eos_create(f->c->bucket_alloc);
316 APR_BRIGADE_INSERT_TAIL(b, e);
321 /* Since we're about to read data, send 100-Continue if needed.
322 * Only valid on chunked and C-L bodies where the C-L is > 0. */
323 if ((ctx->state == BODY_CHUNK ||
324 (ctx->state == BODY_LENGTH && ctx->remaining > 0)) &&
325 f->r->expecting_100 && f->r->proto_num >= HTTP_VERSION(1,1) &&
326 !(f->r->eos_sent || f->r->bytes_sent)) {
327 if (ap_is_HTTP_CLIENT_ERROR(f->r->status)) {
328 ctx->state = BODY_NONE;
333 tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL, " ",
334 ap_get_status_line(100), CRLF CRLF, NULL);
335 apr_brigade_cleanup(bb);
336 e = apr_bucket_pool_create(tmp, strlen(tmp), f->r->pool,
338 APR_BRIGADE_INSERT_HEAD(bb, e);
339 e = apr_bucket_flush_create(f->c->bucket_alloc);
340 APR_BRIGADE_INSERT_TAIL(bb, e);
342 ap_pass_brigade(f->c->output_filters, bb);
346 /* We can't read the chunk until after sending 100 if required. */
347 if (ctx->state == BODY_CHUNK) {
348 apr_brigade_cleanup(bb);
350 rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
354 if (block == APR_NONBLOCK_READ &&
355 ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) ||
356 (APR_STATUS_IS_EAGAIN(rv)) )) {
357 ctx->state = BODY_CHUNK_PART;
361 if (rv == APR_SUCCESS) {
362 rv = get_chunk_line(ctx, bb, f->r->server->limit_req_line);
363 if (APR_STATUS_IS_EAGAIN(rv)) {
364 apr_brigade_cleanup(bb);
365 ctx->state = BODY_CHUNK_PART;
368 if (rv == APR_SUCCESS) {
369 ctx->remaining = get_chunk_size(ctx->chunk_ln);
370 if (ctx->remaining == INVALID_CHAR) {
372 http_error = HTTP_SERVICE_UNAVAILABLE;
376 apr_brigade_cleanup(bb);
378 /* Detect chunksize error (such as overflow) */
379 if (rv != APR_SUCCESS || ctx->remaining < 0) {
380 ctx->remaining = 0; /* Reset it in case we have to
381 * come back here later */
382 return bail_out_on_error(ctx, f, http_error);
385 if (!ctx->remaining) {
386 /* Handle trailers by calling ap_get_mime_headers again! */
387 ctx->state = BODY_NONE;
388 ap_get_mime_headers(f->r);
389 e = apr_bucket_eos_create(f->c->bucket_alloc);
390 APR_BRIGADE_INSERT_TAIL(b, e);
401 e = apr_bucket_eos_create(f->c->bucket_alloc);
402 APR_BRIGADE_INSERT_TAIL(b, e);
406 if (!ctx->remaining) {
407 switch (ctx->state) {
411 e = apr_bucket_eos_create(f->c->bucket_alloc);
412 APR_BRIGADE_INSERT_TAIL(b, e);
416 case BODY_CHUNK_PART:
418 apr_brigade_cleanup(bb);
420 /* We need to read the CRLF after the chunk. */
421 if (ctx->state == BODY_CHUNK) {
422 rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
424 if (block == APR_NONBLOCK_READ &&
425 ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) ||
426 (APR_STATUS_IS_EAGAIN(rv)) )) {
429 /* If we get an error, then leave */
430 if (rv != APR_SUCCESS) {
434 * We really don't care whats on this line. If it is RFC
435 * compliant it should be only \r\n. If there is more
436 * before we just ignore it as long as we do not get over
437 * the limit for request lines.
439 rv = get_remaining_chunk_line(ctx, bb,
440 f->r->server->limit_req_line);
441 apr_brigade_cleanup(bb);
442 if (APR_STATUS_IS_EAGAIN(rv)) {
449 if (rv == APR_SUCCESS) {
450 /* Read the real chunk line. */
451 rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
454 if (block == APR_NONBLOCK_READ &&
455 ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) ||
456 (APR_STATUS_IS_EAGAIN(rv)) )) {
457 ctx->state = BODY_CHUNK_PART;
460 ctx->state = BODY_CHUNK;
461 if (rv == APR_SUCCESS) {
462 rv = get_chunk_line(ctx, bb, f->r->server->limit_req_line);
463 if (APR_STATUS_IS_EAGAIN(rv)) {
464 ctx->state = BODY_CHUNK_PART;
465 apr_brigade_cleanup(bb);
468 if (rv == APR_SUCCESS) {
469 ctx->remaining = get_chunk_size(ctx->chunk_ln);
470 if (ctx->remaining == INVALID_CHAR) {
472 http_error = HTTP_SERVICE_UNAVAILABLE;
476 apr_brigade_cleanup(bb);
479 /* Detect chunksize error (such as overflow) */
480 if (rv != APR_SUCCESS || ctx->remaining < 0) {
481 ctx->remaining = 0; /* Reset it in case we have to
482 * come back here later */
483 bail_out_on_error(ctx, f, http_error);
487 if (!ctx->remaining) {
488 /* Handle trailers by calling ap_get_mime_headers again! */
489 ctx->state = BODY_NONE;
490 ap_get_mime_headers(f->r);
491 e = apr_bucket_eos_create(f->c->bucket_alloc);
492 APR_BRIGADE_INSERT_TAIL(b, e);
501 /* Ensure that the caller can not go over our boundary point. */
502 if (ctx->state == BODY_LENGTH || ctx->state == BODY_CHUNK) {
503 if (ctx->remaining < readbytes) {
504 readbytes = ctx->remaining;
506 AP_DEBUG_ASSERT(readbytes > 0);
509 rv = ap_get_brigade(f->next, b, mode, block, readbytes);
511 if (rv != APR_SUCCESS) {
515 /* How many bytes did we just read? */
516 apr_brigade_length(b, 0, &totalread);
518 /* If this happens, we have a bucket of unknown length. Die because
519 * it means our assumptions have changed. */
520 AP_DEBUG_ASSERT(totalread >= 0);
522 if (ctx->state != BODY_NONE) {
523 ctx->remaining -= totalread;
526 /* If we have no more bytes remaining on a C-L request,
527 * save the callter a roundtrip to discover EOS.
529 if (ctx->state == BODY_LENGTH && ctx->remaining == 0) {
530 e = apr_bucket_eos_create(f->c->bucket_alloc);
531 APR_BRIGADE_INSERT_TAIL(b, e);
534 /* We have a limit in effect. */
536 /* FIXME: Note that we might get slightly confused on chunked inputs
537 * as we'd need to compensate for the chunk lengths which may not
538 * really count. This seems to be up for interpretation. */
539 ctx->limit_used += totalread;
540 if (ctx->limit < ctx->limit_used) {
541 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
542 "Read content-length of %" APR_OFF_T_FMT
543 " is larger than the configured limit"
544 " of %" APR_OFF_T_FMT, ctx->limit_used, ctx->limit);
545 apr_brigade_cleanup(bb);
546 e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
549 APR_BRIGADE_INSERT_TAIL(bb, e);
550 e = apr_bucket_eos_create(f->c->bucket_alloc);
551 APR_BRIGADE_INSERT_TAIL(bb, e);
553 return ap_pass_brigade(f->r->output_filters, bb);
561 * Parse a chunk extension, detect overflow.
562 * There are two error cases:
563 * 1) If the conversion would require too many bits, a -1 is returned.
564 * 2) If the conversion used the correct number of bits, but an overflow
565 * caused only the sign bit to flip, then that negative number is
567 * In general, any negative number can be considered an overflow error.
569 static long get_chunk_size(char *b)
572 size_t chunkbits = sizeof(long) * 8;
574 ap_xlate_proto_from_ascii(b, strlen(b));
576 if (!apr_isxdigit(*b)) {
578 * Detect invalid character at beginning. This also works for empty
583 /* Skip leading zeros */
588 while (apr_isxdigit(*b) && (chunkbits > 0)) {
591 if (*b >= '0' && *b <= '9') {
594 else if (*b >= 'A' && *b <= 'F') {
595 xvalue = *b - 'A' + 0xa;
597 else if (*b >= 'a' && *b <= 'f') {
598 xvalue = *b - 'a' + 0xa;
601 chunksize = (chunksize << 4) | xvalue;
605 if (apr_isxdigit(*b) && (chunkbits <= 0)) {
613 typedef struct header_struct {
615 apr_bucket_brigade *bb;
618 /* Send a single HTTP header field to the client. Note that this function
619 * is used in calls to table_do(), so their interfaces are co-dependent.
620 * In other words, don't change this one without checking table_do in alloc.c.
621 * It returns true unless there was a write error of some kind.
623 static int form_header_field(header_struct *h,
624 const char *fieldname, const char *fieldval)
626 #if APR_CHARSET_EBCDIC
633 name_len = strlen(fieldname);
634 val_len = strlen(fieldval);
635 len = name_len + val_len + 4; /* 4 for ": " plus CRLF */
636 headfield = (char *)apr_palloc(h->pool, len + 1);
637 memcpy(headfield, fieldname, name_len);
638 next = headfield + name_len;
641 memcpy(next, fieldval, val_len);
646 ap_xlate_proto_to_ascii(headfield, len);
647 apr_brigade_write(h->bb, NULL, NULL, headfield, len);
650 struct iovec *v = vec;
651 v->iov_base = (void *)fieldname;
652 v->iov_len = strlen(fieldname);
655 v->iov_len = sizeof(": ") - 1;
657 v->iov_base = (void *)fieldval;
658 v->iov_len = strlen(fieldval);
661 v->iov_len = sizeof(CRLF) - 1;
662 apr_brigade_writev(h->bb, NULL, NULL, vec, 4);
663 #endif /* !APR_CHARSET_EBCDIC */
667 /* This routine is called by apr_table_do and merges all instances of
668 * the passed field values into a single array that will be further
669 * processed by some later routine. Originally intended to help split
670 * and recombine multiple Vary fields, though it is generic to any field
671 * consisting of comma/space-separated tokens.
673 static int uniq_field_values(void *d, const char *key, const char *val)
675 apr_array_header_t *values;
681 values = (apr_array_header_t *)d;
683 e = apr_pstrdup(values->pool, val);
686 /* Find a non-empty fieldname */
688 while (*e == ',' || apr_isspace(*e)) {
695 while (*e != '\0' && *e != ',' && !apr_isspace(*e)) {
702 /* Now add it to values if it isn't already represented.
703 * Could be replaced by a ap_array_strcasecmp() if we had one.
705 for (i = 0, strpp = (char **) values->elts; i < values->nelts;
707 if (*strpp && strcasecmp(*strpp, start) == 0) {
711 if (i == values->nelts) { /* if not found */
712 *(char **)apr_array_push(values) = start;
714 } while (*e != '\0');
720 * Since some clients choke violently on multiple Vary fields, or
721 * Vary fields with duplicate tokens, combine any multiples and remove
724 static void fixup_vary(request_rec *r)
726 apr_array_header_t *varies;
728 varies = apr_array_make(r->pool, 5, sizeof(char *));
730 /* Extract all Vary fields from the headers_out, separate each into
731 * its comma-separated fieldname values, and then add them to varies
732 * if not already present in the array.
734 apr_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
735 (void *) varies, r->headers_out, "Vary", NULL);
737 /* If we found any, replace old Vary fields with unique-ified value */
739 if (varies->nelts > 0) {
740 apr_table_setn(r->headers_out, "Vary",
741 apr_array_pstrcat(r->pool, varies, ','));
745 /* Send a request's HTTP response headers to the client.
747 static apr_status_t send_all_header_fields(header_struct *h,
748 const request_rec *r)
750 const apr_array_header_t *elts;
751 const apr_table_entry_t *t_elt;
752 const apr_table_entry_t *t_end;
754 struct iovec *vec_next;
756 elts = apr_table_elts(r->headers_out);
757 if (elts->nelts == 0) {
760 t_elt = (const apr_table_entry_t *)(elts->elts);
761 t_end = t_elt + elts->nelts;
762 vec = (struct iovec *)apr_palloc(h->pool, 4 * elts->nelts *
763 sizeof(struct iovec));
766 /* For each field, generate
767 * name ": " value CRLF
770 vec_next->iov_base = (void*)(t_elt->key);
771 vec_next->iov_len = strlen(t_elt->key);
773 vec_next->iov_base = ": ";
774 vec_next->iov_len = sizeof(": ") - 1;
776 vec_next->iov_base = (void*)(t_elt->val);
777 vec_next->iov_len = strlen(t_elt->val);
779 vec_next->iov_base = CRLF;
780 vec_next->iov_len = sizeof(CRLF) - 1;
783 } while (t_elt < t_end);
785 #if APR_CHARSET_EBCDIC
788 char *tmp = apr_pstrcatv(r->pool, vec, vec_next - vec, &len);
789 ap_xlate_proto_to_ascii(tmp, len);
790 return apr_brigade_write(h->bb, NULL, NULL, tmp, len);
793 return apr_brigade_writev(h->bb, NULL, NULL, vec, vec_next - vec);
797 /* Confirm that the status line is well-formed and matches r->status.
798 * If they don't match, a filter may have negated the status line set by a
800 * Zap r->status_line if bad.
802 static void validate_status_line(request_rec *r)
807 && (strlen(r->status_line) <= 4
808 || apr_strtoi64(r->status_line, &end, 10) != r->status
810 || (end - 3) != r->status_line)) {
811 r->status_line = NULL;
816 * Determine the protocol to use for the response. Potentially downgrade
817 * to HTTP/1.0 in some situations and/or turn off keepalives.
819 * also prepare r->status_line.
821 static void basic_http_header_check(request_rec *r,
822 const char **protocol)
824 if (r->assbackwards) {
825 /* no such thing as a response protocol */
829 validate_status_line(r);
831 if (!r->status_line) {
832 r->status_line = ap_get_status_line(r->status);
835 /* Note that we must downgrade before checking for force responses. */
836 if (r->proto_num > HTTP_VERSION(1,0)
837 && apr_table_get(r->subprocess_env, "downgrade-1.0")) {
838 r->proto_num = HTTP_VERSION(1,0);
841 /* kludge around broken browsers when indicated by force-response-1.0
843 if (r->proto_num == HTTP_VERSION(1,0)
844 && apr_table_get(r->subprocess_env, "force-response-1.0")) {
845 *protocol = "HTTP/1.0";
846 r->connection->keepalive = AP_CONN_CLOSE;
849 *protocol = AP_SERVER_PROTOCOL;
854 /* fill "bb" with a barebones/initial HTTP response header */
855 static void basic_http_header(request_rec *r, apr_bucket_brigade *bb,
856 const char *protocol)
863 if (r->assbackwards) {
864 /* there are no headers to send */
868 /* Output the HTTP/1.x Status-Line and the Date and Server fields */
870 vec[0].iov_base = (void *)protocol;
871 vec[0].iov_len = strlen(protocol);
872 vec[1].iov_base = (void *)" ";
873 vec[1].iov_len = sizeof(" ") - 1;
874 vec[2].iov_base = (void *)(r->status_line);
875 vec[2].iov_len = strlen(r->status_line);
876 vec[3].iov_base = (void *)CRLF;
877 vec[3].iov_len = sizeof(CRLF) - 1;
878 #if APR_CHARSET_EBCDIC
882 tmp = apr_pstrcatv(r->pool, vec, 4, &len);
883 ap_xlate_proto_to_ascii(tmp, len);
884 apr_brigade_write(bb, NULL, NULL, tmp, len);
887 apr_brigade_writev(bb, NULL, NULL, vec, 4);
894 * keep the set-by-proxy server and date headers, otherwise
895 * generate a new server header / date header
897 if (r->proxyreq != PROXYREQ_NONE) {
898 const char *proxy_date;
900 proxy_date = apr_table_get(r->headers_out, "Date");
903 * proxy_date needs to be const. So use date for the creation of
904 * our own Date header and pass it over to proxy_date later to
905 * avoid a compiler warning.
907 date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
908 ap_recent_rfc822_date(date, r->request_time);
911 form_header_field(&h, "Date", proxy_date);
912 server = apr_table_get(r->headers_out, "Server");
914 form_header_field(&h, "Server", server);
916 form_header_field(&h, "Server", ap_get_server_banner());
920 date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
921 ap_recent_rfc822_date(date, r->request_time);
922 form_header_field(&h, "Date", date);
923 form_header_field(&h, "Server", ap_get_server_banner());
926 /* unset so we don't send them again */
927 apr_table_unset(r->headers_out, "Date"); /* Avoid bogosity */
928 apr_table_unset(r->headers_out, "Server");
931 AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb)
933 const char *protocol;
935 basic_http_header_check(r, &protocol);
936 basic_http_header(r, bb, protocol);
939 /* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
940 * have a header parsing bug. If the terminating \r\n occur starting
941 * at offset 256, 257 or 258 of output then it will not properly parse
942 * the headers. Curiously it doesn't exhibit this problem at 512, 513.
943 * We are guessing that this is because their initial read of a new request
944 * uses a 256 byte buffer, and subsequent reads use a larger buffer.
945 * So the problem might exist at different offsets as well.
947 * This should also work on keepalive connections assuming they use the
948 * same small buffer for the first read of each new request.
950 * At any rate, we check the bytes written so far and, if we are about to
951 * tickle the bug, we instead insert a bogus padding header. Since the bug
952 * manifests as a broken image in Navigator, users blame the server. :(
953 * It is more expensive to check the User-Agent than it is to just add the
954 * bytes, so we haven't used the BrowserMatch feature here.
956 static void terminate_header(apr_bucket_brigade *bb)
958 char tmp[] = "X-Pad: avoid browser bug" CRLF;
963 (void) apr_brigade_length(bb, 1, &len);
965 if (len >= 255 && len <= 257) {
966 buflen = strlen(tmp);
967 ap_xlate_proto_to_ascii(tmp, buflen);
968 apr_brigade_write(bb, NULL, NULL, tmp, buflen);
970 buflen = strlen(crlf);
971 ap_xlate_proto_to_ascii(crlf, buflen);
972 apr_brigade_write(bb, NULL, NULL, crlf, buflen);
975 AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r)
977 core_server_config *conf;
979 apr_bucket_brigade *bb;
983 char *bodyread = NULL, *bodyoff;
984 apr_size_t bodylen = 0;
986 long res = -1; /* init to avoid gcc -Wall warning */
988 if (r->method_number != M_TRACE) {
992 /* Get the original request */
996 conf = (core_server_config *)ap_get_module_config(r->server->module_config,
999 if (conf->trace_enable == AP_TRACE_DISABLE) {
1000 apr_table_setn(r->notes, "error-notes",
1001 "TRACE denied by server configuration");
1002 return HTTP_METHOD_NOT_ALLOWED;
1005 if (conf->trace_enable == AP_TRACE_EXTENDED)
1006 /* XX should be = REQUEST_CHUNKED_PASS */
1007 body = REQUEST_CHUNKED_DECHUNK;
1009 body = REQUEST_NO_BODY;
1011 if ((rv = ap_setup_client_block(r, body))) {
1012 if (rv == HTTP_REQUEST_ENTITY_TOO_LARGE)
1013 apr_table_setn(r->notes, "error-notes",
1014 "TRACE with a request body is not allowed");
1018 if (ap_should_client_block(r)) {
1020 if (r->remaining > 0) {
1021 if (r->remaining > 65536) {
1022 apr_table_setn(r->notes, "error-notes",
1023 "Extended TRACE request bodies cannot exceed 64k\n");
1024 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1026 /* always 32 extra bytes to catch chunk header exceptions */
1027 bodybuf = (apr_size_t)r->remaining + 32;
1030 /* Add an extra 8192 for chunk headers */
1034 bodyoff = bodyread = apr_palloc(r->pool, bodybuf);
1036 /* only while we have enough for a chunked header */
1037 while ((!bodylen || bodybuf >= 32) &&
1038 (res = ap_get_client_block(r, bodyoff, bodybuf)) > 0) {
1043 if (res > 0 && bodybuf < 32) {
1044 /* discard_rest_of_request_body into our buffer */
1045 while (ap_get_client_block(r, bodyread, bodylen) > 0)
1047 apr_table_setn(r->notes, "error-notes",
1048 "Extended TRACE request bodies cannot exceed 64k\n");
1049 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1053 return HTTP_BAD_REQUEST;
1057 ap_set_content_type(r, "message/http");
1059 /* Now we recreate the request, and echo it back */
1061 bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1062 apr_brigade_putstrs(bb, NULL, NULL, r->the_request, CRLF, NULL);
1065 apr_table_do((int (*) (void *, const char *, const char *))
1066 form_header_field, (void *) &h, r->headers_in, NULL);
1067 apr_brigade_puts(bb, NULL, NULL, CRLF);
1069 /* If configured to accept a body, echo the body */
1071 b = apr_bucket_pool_create(bodyread, bodylen,
1072 r->pool, bb->bucket_alloc);
1073 APR_BRIGADE_INSERT_TAIL(bb, b);
1076 ap_pass_brigade(r->output_filters, bb);
1081 typedef struct header_filter_ctx {
1083 } header_filter_ctx;
1085 AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
1086 apr_bucket_brigade *b)
1088 request_rec *r = f->r;
1089 conn_rec *c = r->connection;
1090 const char *clheader;
1091 const char *protocol;
1093 apr_bucket_brigade *b2;
1095 header_filter_ctx *ctx = f->ctx;
1098 AP_DEBUG_ASSERT(!r->main);
1100 if (r->header_only) {
1102 ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx));
1104 else if (ctx->headers_sent) {
1105 apr_brigade_destroy(b);
1110 for (e = APR_BRIGADE_FIRST(b);
1111 e != APR_BRIGADE_SENTINEL(b);
1112 e = APR_BUCKET_NEXT(e))
1114 if (AP_BUCKET_IS_ERROR(e)) {
1115 ap_bucket_error *eb = e->data;
1117 ap_die(eb->status, r);
1118 return AP_FILTER_ERROR;
1122 if (r->assbackwards) {
1124 ap_remove_output_filter(f);
1125 return ap_pass_brigade(f->next, b);
1129 * Now that we are ready to send a response, we need to combine the two
1130 * header field tables into a single table. If we don't do this, our
1131 * later attempts to set or unset a given fieldname might be bypassed.
1133 if (!apr_is_empty_table(r->err_headers_out)) {
1134 r->headers_out = apr_table_overlay(r->pool, r->err_headers_out,
1139 * Remove the 'Vary' header field if the client can't handle it.
1140 * Since this will have nasty effects on HTTP/1.1 caches, force
1141 * the response into HTTP/1.0 mode.
1143 * Note: the force-response-1.0 should come before the call to
1144 * basic_http_header_check()
1146 if (apr_table_get(r->subprocess_env, "force-no-vary") != NULL) {
1147 apr_table_unset(r->headers_out, "Vary");
1148 r->proto_num = HTTP_VERSION(1,0);
1149 apr_table_set(r->subprocess_env, "force-response-1.0", "1");
1156 * Now remove any ETag response header field if earlier processing
1157 * says so (such as a 'FileETag None' directive).
1159 if (apr_table_get(r->notes, "no-etag") != NULL) {
1160 apr_table_unset(r->headers_out, "ETag");
1163 /* determine the protocol and whether we should use keepalives. */
1164 basic_http_header_check(r, &protocol);
1165 ap_set_keepalive(r);
1168 apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
1169 apr_table_unset(r->headers_out, "Content-Length");
1172 ctype = ap_make_content_type(r, r->content_type);
1173 if (strcasecmp(ctype, NO_CONTENT_TYPE)) {
1174 apr_table_setn(r->headers_out, "Content-Type", ctype);
1177 if (r->content_encoding) {
1178 apr_table_setn(r->headers_out, "Content-Encoding",
1179 r->content_encoding);
1182 if (!apr_is_empty_array(r->content_languages)) {
1185 char **languages = (char **)(r->content_languages->elts);
1186 const char *field = apr_table_get(r->headers_out, "Content-Language");
1188 while (field && (token = ap_get_list_item(r->pool, &field)) != NULL) {
1189 for (i = 0; i < r->content_languages->nelts; ++i) {
1190 if (!strcasecmp(token, languages[i]))
1193 if (i == r->content_languages->nelts) {
1194 *((char **) apr_array_push(r->content_languages)) = token;
1198 field = apr_array_pstrcat(r->pool, r->content_languages, ',');
1199 apr_table_setn(r->headers_out, "Content-Language", field);
1203 * Control cachability for non-cachable responses if not already set by
1204 * some other part of the server configuration.
1206 if (r->no_cache && !apr_table_get(r->headers_out, "Expires")) {
1207 char *date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
1208 ap_recent_rfc822_date(date, r->request_time);
1209 apr_table_addn(r->headers_out, "Expires", date);
1212 /* This is a hack, but I can't find anyway around it. The idea is that
1213 * we don't want to send out 0 Content-Lengths if it is a head request.
1214 * This happens when modules try to outsmart the server, and return
1215 * if they see a HEAD request. Apache 1.3 handlers were supposed to
1216 * just return in that situation, and the core handled the HEAD. In
1217 * 2.0, if a handler returns, then the core sends an EOS bucket down
1218 * the filter stack, and the content-length filter computes a C-L of
1219 * zero and that gets put in the headers, and we end up sending a
1220 * zero C-L to the client. We can't just remove the C-L filter,
1221 * because well behaved 2.0 handlers will send their data down the stack,
1222 * and we will compute a real C-L for the head request. RBB
1225 && (clheader = apr_table_get(r->headers_out, "Content-Length"))
1226 && !strcmp(clheader, "0")) {
1227 apr_table_unset(r->headers_out, "Content-Length");
1230 b2 = apr_brigade_create(r->pool, c->bucket_alloc);
1231 basic_http_header(r, b2, protocol);
1236 if (r->status == HTTP_NOT_MODIFIED) {
1237 apr_table_do((int (*)(void *, const char *, const char *)) form_header_field,
1238 (void *) &h, r->headers_out,
1248 "Proxy-Authenticate",
1254 send_all_header_fields(&h, r);
1257 terminate_header(b2);
1259 ap_pass_brigade(f->next, b2);
1261 if (r->header_only) {
1262 apr_brigade_destroy(b);
1263 ctx->headers_sent = 1;
1267 r->sent_bodyct = 1; /* Whatever follows is real body stuff... */
1270 /* We can't add this filter until we have already sent the headers.
1271 * If we add it before this point, then the headers will be chunked
1272 * as well, and that is just wrong.
1274 ap_add_output_filter("CHUNK", NULL, r, r->connection);
1277 /* Don't remove this filter until after we have added the CHUNK filter.
1278 * Otherwise, f->next won't be the CHUNK filter and thus the first
1279 * brigade won't be chunked properly.
1281 ap_remove_output_filter(f);
1282 return ap_pass_brigade(f->next, b);
1285 /* In HTTP/1.1, any method can have a body. However, most GET handlers
1286 * wouldn't know what to do with a request body if they received one.
1287 * This helper routine tests for and reads any message body in the request,
1288 * simply discarding whatever it receives. We need to do this because
1289 * failing to read the request body would cause it to be interpreted
1290 * as the next request on a persistent connection.
1292 * Since we return an error status if the request is malformed, this
1293 * routine should be called at the beginning of a no-body handler, e.g.,
1295 * if ((retval = ap_discard_request_body(r)) != OK) {
1299 AP_DECLARE(int) ap_discard_request_body(request_rec *r)
1301 apr_bucket_brigade *bb, *kept_body = NULL;
1304 core_dir_conf *dconf;
1307 /* Sometimes we'll get in a state where the input handling has
1308 * detected an error where we want to drop the connection, so if
1309 * that's the case, don't read the data as that is what we're trying
1312 * This function is also a no-op on a subrequest.
1314 if (r->main || r->connection->keepalive == AP_CONN_CLOSE ||
1315 ap_status_drops_connection(r->status)) {
1319 /* We may want to save this body away if the administrator has
1320 * asked us to do so for this directory. This allows the body
1321 * to be reexamined by filters such as mod_include, even though
1322 * the main request has no need for this body.
1324 if (!r->kept_body) {
1325 dconf = ap_get_module_config(r->per_dir_config,
1327 if (dconf->keep_body > 0) {
1328 left = dconf->keep_body;
1329 kept_body = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1333 bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1338 rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
1339 APR_BLOCK_READ, HUGE_STRING_LEN);
1341 if (rv != APR_SUCCESS) {
1342 /* FIXME: If we ever have a mapping from filters (apr_status_t)
1343 * to HTTP error codes, this would be a good place for them.
1345 * If we received the special case AP_FILTER_ERROR, it means
1346 * that the filters have already handled this error.
1347 * Otherwise, we should assume we have a bad request.
1349 if (rv == AP_FILTER_ERROR) {
1350 apr_brigade_destroy(bb);
1354 apr_brigade_destroy(bb);
1355 return HTTP_BAD_REQUEST;
1359 for (bucket = APR_BRIGADE_FIRST(bb);
1360 bucket != APR_BRIGADE_SENTINEL(bb);
1361 bucket = APR_BUCKET_NEXT(bucket))
1366 if (APR_BUCKET_IS_EOS(bucket)) {
1371 /* These are metadata buckets. */
1372 if (bucket->length == 0) {
1376 /* We MUST read because in case we have an unknown-length
1377 * bucket or one that morphs, we want to exhaust it.
1379 rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
1380 if (rv != APR_SUCCESS) {
1381 apr_brigade_destroy(bb);
1382 return HTTP_BAD_REQUEST;
1385 /* If we have been asked to, keep the data up until the
1386 * configured limit. If the limit is exceeded, we return an
1387 * HTTP_REQUEST_ENTITY_TOO_LARGE response so the caller is
1388 * clear the server couldn't handle their request.
1392 apr_bucket_copy(bucket, &e);
1393 APR_BRIGADE_INSERT_TAIL(kept_body, e);
1397 apr_brigade_destroy(bb);
1398 apr_brigade_destroy(kept_body);
1399 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1404 apr_brigade_cleanup(bb);
1405 } while (!seen_eos);
1408 r->kept_body = kept_body;
1414 /* Here we deal with getting the request message body from the client.
1415 * Whether or not the request contains a body is signaled by the presence
1416 * of a non-zero Content-Length or by a Transfer-Encoding: chunked.
1418 * Note that this is more complicated than it was in Apache 1.1 and prior
1419 * versions, because chunked support means that the module does less.
1421 * The proper procedure is this:
1423 * 1. Call ap_setup_client_block() near the beginning of the request
1424 * handler. This will set up all the necessary properties, and will
1425 * return either OK, or an error code. If the latter, the module should
1426 * return that error code. The second parameter selects the policy to
1427 * apply if the request message indicates a body, and how a chunked
1428 * transfer-coding should be interpreted. Choose one of
1430 * REQUEST_NO_BODY Send 413 error if message has any body
1431 * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
1432 * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
1433 * REQUEST_CHUNKED_PASS If chunked, pass the chunk headers with body.
1435 * In order to use the last two options, the caller MUST provide a buffer
1436 * large enough to hold a chunk-size line, including any extensions.
1438 * 2. When you are ready to read a body (if any), call ap_should_client_block().
1439 * This will tell the module whether or not to read input. If it is 0,
1440 * the module should assume that there is no message body to read.
1442 * 3. Finally, call ap_get_client_block in a loop. Pass it a buffer and its size.
1443 * It will put data into the buffer (not necessarily a full buffer), and
1444 * return the length of the input block. When it is done reading, it will
1445 * return 0 if EOF, or -1 if there was an error.
1446 * If an error occurs on input, we force an end to keepalive.
1448 * This step also sends a 100 Continue response to HTTP/1.1 clients if appropriate.
1451 AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy)
1453 const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
1454 const char *lenp = apr_table_get(r->headers_in, "Content-Length");
1456 r->read_body = read_policy;
1457 r->read_chunked = 0;
1461 if (strcasecmp(tenc, "chunked")) {
1462 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1463 "Unknown Transfer-Encoding %s", tenc);
1464 return HTTP_NOT_IMPLEMENTED;
1466 if (r->read_body == REQUEST_CHUNKED_ERROR) {
1467 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1468 "chunked Transfer-Encoding forbidden: %s", r->uri);
1469 return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
1472 r->read_chunked = 1;
1477 if (apr_strtoff(&r->remaining, lenp, &endstr, 10)
1478 || *endstr || r->remaining < 0) {
1480 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1481 "Invalid Content-Length");
1482 return HTTP_BAD_REQUEST;
1486 if ((r->read_body == REQUEST_NO_BODY)
1487 && (r->read_chunked || (r->remaining > 0))) {
1488 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1489 "%s with body is not allowed for %s", r->method, r->uri);
1490 return HTTP_REQUEST_ENTITY_TOO_LARGE;
1495 /* Make sure ap_getline() didn't leave any droppings. */
1496 core_request_config *req_cfg =
1497 (core_request_config *)ap_get_module_config(r->request_config,
1499 AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(req_cfg->bb));
1506 AP_DECLARE(int) ap_should_client_block(request_rec *r)
1508 /* First check if we have already read the request body */
1510 if (r->read_length || (!r->read_chunked && (r->remaining <= 0))) {
1517 /* get_client_block is called in a loop to get the request message body.
1518 * This is quite simple if the client includes a content-length
1519 * (the normal case), but gets messy if the body is chunked. Note that
1520 * r->remaining is used to maintain state across calls and that
1521 * r->read_length is the total number of bytes given to the caller
1522 * across all invocations. It is messy because we have to be careful not
1523 * to read past the data provided by the client, since these reads block.
1524 * Returns 0 on End-of-body, -1 on error or premature chunk end.
1527 AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer,
1531 apr_bucket_brigade *bb;
1533 if (r->remaining < 0 || (!r->read_chunked && r->remaining == 0)) {
1537 bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1539 r->connection->keepalive = AP_CONN_CLOSE;
1543 rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
1544 APR_BLOCK_READ, bufsiz);
1546 /* We lose the failure code here. This is why ap_get_client_block should
1549 if (rv != APR_SUCCESS) {
1550 /* if we actually fail here, we want to just return and
1551 * stop trying to read data from the client.
1553 r->connection->keepalive = AP_CONN_CLOSE;
1554 apr_brigade_destroy(bb);
1558 /* If this fails, it means that a filter is written incorrectly and that
1559 * it needs to learn how to properly handle APR_BLOCK_READ requests by
1560 * returning data when requested.
1562 AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(bb));
1564 /* Check to see if EOS in the brigade.
1566 * If so, we have to leave a nugget for the *next* ap_get_client_block
1569 if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
1570 if (r->read_chunked) {
1578 rv = apr_brigade_flatten(bb, buffer, &bufsiz);
1579 if (rv != APR_SUCCESS) {
1580 apr_brigade_destroy(bb);
1585 r->read_length += bufsiz;
1587 apr_brigade_destroy(bb);
1591 /* Filter to handle any error buckets on output */
1592 apr_status_t ap_http_outerror_filter(ap_filter_t *f,
1593 apr_bucket_brigade *b)
1595 request_rec *r = f->r;
1598 for (e = APR_BRIGADE_FIRST(b);
1599 e != APR_BRIGADE_SENTINEL(b);
1600 e = APR_BUCKET_NEXT(e))
1602 if (AP_BUCKET_IS_ERROR(e)) {
1604 * Start of error handling state tree. Just one condition
1607 if (((ap_bucket_error *)(e->data))->status == HTTP_BAD_GATEWAY) {
1608 /* stream aborted and we have not ended it yet */
1609 r->connection->keepalive = AP_CONN_CLOSE;
1614 return ap_pass_brigade(f->next, b);
1617 typedef struct kept_body_filter_ctx {
1619 apr_off_t remaining;
1623 * Initialisation of filter to handle a kept body on subrequests.
1625 * If a body is to be reinserted into a subrequest, any chunking will have
1626 * been removed from the body during storage. We need to change the request
1627 * from Transfer-Encoding: chunked to an explicit Content-Length.
1629 int ap_kept_body_filter_init(ap_filter_t *f) {
1630 apr_off_t length = 0;
1631 request_rec *r = f->r;
1632 apr_bucket_brigade *kept_body = r->kept_body;
1635 apr_table_unset(r->headers_in, "Transfer-Encoding");
1636 apr_brigade_length(kept_body, 1, &length);
1637 apr_table_set(r->headers_in, "Content-Length", apr_off_t_toa(r->pool, length));
1644 * Filter to handle a kept body on subrequests.
1646 * If a body has been previously kept by the request, and if a subrequest wants
1647 * to re-insert the body into the request, this input filter makes it happen.
1649 apr_status_t ap_kept_body_filter(ap_filter_t *f, apr_bucket_brigade *b,
1650 ap_input_mode_t mode, apr_read_type_e block,
1651 apr_off_t readbytes) {
1652 request_rec *r = f->r;
1653 apr_bucket_brigade *kept_body = r->kept_body;
1654 kept_body_ctx_t *ctx = f->ctx;
1655 apr_bucket *ec, *e2;
1658 /* just get out of the way of things we don't want. */
1659 if (!kept_body || (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE)) {
1660 return ap_get_brigade(f->next, b, mode, block, readbytes);
1663 /* set up the context if it does not already exist */
1665 f->ctx = ctx = apr_palloc(f->r->pool, sizeof(*ctx));
1667 apr_brigade_length(kept_body, 1, &ctx->remaining);
1670 /* kept_body is finished, send next filter */
1671 if (ctx->remaining <= 0) {
1672 return ap_get_brigade(f->next, b, mode, block, readbytes);
1675 /* send all of the kept_body, but no more */
1676 if (readbytes > ctx->remaining) {
1677 readbytes = ctx->remaining;
1680 /* send part of the kept_body */
1681 if ((rv = apr_brigade_partition(kept_body, ctx->offset, &ec)) != APR_SUCCESS) {
1682 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
1683 "apr_brigade_partition() failed on kept_body at %" APR_OFF_T_FMT, ctx->offset);
1686 if ((rv = apr_brigade_partition(kept_body, ctx->offset + readbytes, &e2)) != APR_SUCCESS) {
1687 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
1688 "apr_brigade_partition() failed on kept_body at %" APR_OFF_T_FMT, ctx->offset + readbytes);
1697 if (apr_bucket_copy(ec, &foo) != APR_SUCCESS) {
1698 /* As above; this should not fail since the bucket has
1699 * a known length, but just to be sure, this takes
1700 * care of uncopyable buckets that do somehow manage
1701 * to slip through. */
1702 /* XXX: check for failure? */
1703 apr_bucket_read(ec, &str, &len, APR_BLOCK_READ);
1704 apr_bucket_copy(ec, &foo);
1706 APR_BRIGADE_INSERT_TAIL(b, foo);
1707 ec = APR_BUCKET_NEXT(ec);
1710 ctx->remaining -= readbytes;
1711 ctx->offset += readbytes;