1 /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * 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.
19 #include "apr_strings.h"
20 #include "apr_pools.h"
21 #include "apr_tables.h"
22 #include "apr_buckets.h"
23 #include "apr_errno.h"
24 #define APR_WANT_MEMFUNC
25 #define APR_WANT_STRFUNC
28 #if APR_HAVE_SYS_UIO_H
32 static apr_status_t brigade_cleanup(void *data)
34 return apr_brigade_cleanup(data);
37 APU_DECLARE(apr_status_t) apr_brigade_cleanup(void *data)
39 apr_bucket_brigade *b = data;
43 * Bah! We can't use APR_RING_FOREACH here because this bucket has
44 * gone away when we dig inside it to get the next one.
46 while (!APR_BRIGADE_EMPTY(b)) {
47 e = APR_BRIGADE_FIRST(b);
51 * We don't need to free(bb) because it's allocated from a pool.
56 APU_DECLARE(apr_status_t) apr_brigade_destroy(apr_bucket_brigade *b)
58 apr_pool_cleanup_kill(b->p, b, brigade_cleanup);
59 return apr_brigade_cleanup(b);
62 APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p,
63 apr_bucket_alloc_t *list)
65 apr_bucket_brigade *b;
67 b = apr_palloc(p, sizeof(*b));
69 b->bucket_alloc = list;
71 APR_RING_INIT(&b->list, apr_bucket, link);
73 apr_pool_cleanup_register(b->p, b, brigade_cleanup, apr_pool_cleanup_null);
77 APU_DECLARE(apr_bucket_brigade *) apr_brigade_split(apr_bucket_brigade *b,
80 apr_bucket_brigade *a;
83 a = apr_brigade_create(b->p, b->bucket_alloc);
84 /* Return an empty brigade if there is nothing left in
85 * the first brigade to split off
87 if (e != APR_BRIGADE_SENTINEL(b)) {
88 f = APR_RING_LAST(&b->list);
89 APR_RING_UNSPLICE(e, f, link);
90 APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link);
93 APR_BRIGADE_CHECK_CONSISTENCY(a);
94 APR_BRIGADE_CHECK_CONSISTENCY(b);
99 APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
101 apr_bucket **after_point)
109 /* this could cause weird (not necessarily SEGV) things to happen */
113 *after_point = APR_BRIGADE_FIRST(b);
117 APR_BRIGADE_CHECK_CONSISTENCY(b);
119 APR_BRIGADE_FOREACH(e, b) {
120 if ((e->length == (apr_size_t)(-1)) && (point > (apr_size_t)(-1))) {
121 /* XXX: point is too far out to simply split this bucket,
122 * we must fix this bucket's size and keep going... */
123 rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ);
124 if (rv != APR_SUCCESS) {
129 if ((point < e->length) || (e->length == (apr_size_t)(-1))) {
130 /* We already checked e->length -1 above, so we now
131 * trust e->length < MAX_APR_SIZE_T.
132 * First try to split the bucket natively... */
133 if ((rv = apr_bucket_split(e, (apr_size_t)point))
135 *after_point = APR_BUCKET_NEXT(e);
139 /* if the bucket cannot be split, we must read from it,
140 * changing its type to one that can be split */
141 rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ);
142 if (rv != APR_SUCCESS) {
147 /* this assumes that len == e->length, which is okay because e
148 * might have been morphed by the apr_bucket_read() above, but
149 * if it was, the length would have been adjusted appropriately */
150 if (point < e->length) {
151 rv = apr_bucket_split(e, (apr_size_t)point);
152 *after_point = APR_BUCKET_NEXT(e);
156 if (point == e->length) {
157 *after_point = APR_BUCKET_NEXT(e);
162 *after_point = APR_BRIGADE_SENTINEL(b);
163 return APR_INCOMPLETE;
166 APU_DECLARE(apr_status_t) apr_brigade_length(apr_bucket_brigade *bb,
167 int read_all, apr_off_t *length)
172 APR_BRIGADE_FOREACH(bkt, bb) {
173 if (bkt->length == (apr_size_t)(-1)) {
183 if ((status = apr_bucket_read(bkt, &ignore, &len,
184 APR_BLOCK_READ)) != APR_SUCCESS) {
189 total += bkt->length;
196 APU_DECLARE(apr_status_t) apr_brigade_flatten(apr_bucket_brigade *bb,
197 char *c, apr_size_t *len)
199 apr_size_t actual = 0;
202 APR_BRIGADE_FOREACH(b, bb) {
207 status = apr_bucket_read(b, &str, &str_len, APR_BLOCK_READ);
208 if (status != APR_SUCCESS) {
212 /* If we would overflow. */
213 if (str_len + actual > *len) {
214 str_len = *len - actual;
217 /* XXX: It appears that overflow of the final bucket
218 * is DISCARDED without any warning to the caller.
220 * No, we only copy the data up to their requested size. -- jre
222 memcpy(c, str, str_len);
227 /* This could probably be actual == *len, but be safe from stray
229 if (actual >= *len) {
238 APU_DECLARE(apr_status_t) apr_brigade_pflatten(apr_bucket_brigade *bb,
247 apr_brigade_length(bb, 1, &actual);
249 /* XXX: This is dangerous beyond belief. At least in the
250 * apr_brigade_flatten case, the user explicitly stated their
251 * buffer length - so we don't up and palloc 4GB for a single
252 * file bucket. This API must grow a useful max boundry,
253 * either compiled-in or preset via the *len value.
255 * Shouldn't both fn's grow an additional return value for
256 * the case that the brigade couldn't be flattened into the
257 * provided or allocated buffer (such as APR_EMOREDATA?)
258 * Not a failure, simply an advisory result.
260 total = (apr_size_t)actual;
262 *c = apr_palloc(pool, total);
264 rv = apr_brigade_flatten(bb, *c, &total);
266 if (rv != APR_SUCCESS) {
274 APU_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut,
275 apr_bucket_brigade *bbIn,
276 apr_read_type_e block,
279 apr_off_t readbytes = 0;
281 while (!APR_BRIGADE_EMPTY(bbIn)) {
288 e = APR_BRIGADE_FIRST(bbIn);
289 rv = apr_bucket_read(e, &str, &len, block);
291 if (rv != APR_SUCCESS) {
295 pos = memchr(str, APR_ASCII_LF, len);
296 /* We found a match. */
298 apr_bucket_split(e, pos - str + 1);
299 APR_BUCKET_REMOVE(e);
300 APR_BRIGADE_INSERT_TAIL(bbOut, e);
303 APR_BUCKET_REMOVE(e);
304 if (APR_BUCKET_IS_METADATA(e) || len > APR_BUCKET_BUFF_SIZE/4) {
305 APR_BRIGADE_INSERT_TAIL(bbOut, e);
309 rv = apr_brigade_write(bbOut, NULL, NULL, str, len);
310 if (rv != APR_SUCCESS) {
314 apr_bucket_destroy(e);
317 /* We didn't find an APR_ASCII_LF within the maximum line length. */
318 if (readbytes >= maxbytes) {
327 APU_DECLARE(apr_status_t) apr_brigade_to_iovec(apr_bucket_brigade *b,
328 struct iovec *vec, int *nvec)
337 APR_BRIGADE_FOREACH(e, b) {
341 rv = apr_bucket_read(e, (const char **)&vec->iov_base, &iov_len,
343 if (rv != APR_SUCCESS)
345 vec->iov_len = iov_len; /* set indirectly in case size differs */
353 APU_DECLARE(apr_status_t) apr_brigade_vputstrs(apr_bucket_brigade *b,
354 apr_brigade_flush flush,
359 const char *str = va_arg(va, const char *);
365 rv = apr_brigade_write(b, flush, ctx, str, strlen(str));
366 if (rv != APR_SUCCESS)
373 APU_DECLARE(apr_status_t) apr_brigade_putc(apr_bucket_brigade *b,
374 apr_brigade_flush flush, void *ctx,
377 return apr_brigade_write(b, flush, ctx, &c, 1);
380 APU_DECLARE(apr_status_t) apr_brigade_write(apr_bucket_brigade *b,
381 apr_brigade_flush flush,
383 const char *str, apr_size_t nbyte)
385 apr_bucket *e = APR_BRIGADE_LAST(b);
386 apr_size_t remaining = APR_BUCKET_BUFF_SIZE;
389 if (!APR_BRIGADE_EMPTY(b) && APR_BUCKET_IS_HEAP(e)) {
390 apr_bucket_heap *h = e->data;
392 /* HEAP bucket start offsets are always in-memory, safe to cast */
393 remaining = h->alloc_len - (e->length + (apr_size_t)e->start);
394 buf = h->base + e->start + e->length;
397 if (nbyte > remaining) {
398 /* either a buffer bucket exists but is full,
399 * or no buffer bucket exists and the data is too big
400 * to buffer. In either case, we should flush. */
402 e = apr_bucket_transient_create(str, nbyte, b->bucket_alloc);
403 APR_BRIGADE_INSERT_TAIL(b, e);
404 return flush(b, ctx);
407 e = apr_bucket_heap_create(str, nbyte, NULL, b->bucket_alloc);
408 APR_BRIGADE_INSERT_TAIL(b, e);
413 /* we don't have a buffer, but the data is small enough
414 * that we don't mind making a new buffer */
415 buf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->bucket_alloc);
416 e = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE,
417 apr_bucket_free, b->bucket_alloc);
418 APR_BRIGADE_INSERT_TAIL(b, e);
419 e->length = 0; /* We are writing into the brigade, and
420 * allocating more memory than we need. This
421 * ensures that the bucket thinks it is empty just
422 * after we create it. We'll fix the length
423 * once we put data in it below.
427 /* there is a sufficiently big buffer bucket available now */
428 memcpy(buf, str, nbyte);
434 APU_DECLARE(apr_status_t) apr_brigade_writev(apr_bucket_brigade *b,
435 apr_brigade_flush flush,
437 const struct iovec *vec,
441 apr_size_t total_len;
445 /* Compute the total length of the data to be written.
448 for (i = 0; i < nvec; i++) {
449 total_len += vec[i].iov_len;
452 /* If the data to be written is very large, try to convert
453 * the iovec to transient buckets rather than copying.
455 if (total_len > APR_BUCKET_BUFF_SIZE) {
457 for (i = 0; i < nvec; i++) {
458 e = apr_bucket_transient_create(vec[i].iov_base,
461 APR_BRIGADE_INSERT_TAIL(b, e);
463 return flush(b, ctx);
466 for (i = 0; i < nvec; i++) {
467 e = apr_bucket_heap_create((const char *) vec[i].iov_base,
468 vec[i].iov_len, NULL,
470 APR_BRIGADE_INSERT_TAIL(b, e);
478 /* If there is a heap bucket at the end of the brigade
479 * already, copy into the existing bucket.
481 e = APR_BRIGADE_LAST(b);
482 if (!APR_BRIGADE_EMPTY(b) && APR_BUCKET_IS_HEAP(e)) {
483 apr_bucket_heap *h = e->data;
484 apr_size_t remaining = h->alloc_len -
485 (e->length + (apr_size_t)e->start);
486 buf = h->base + e->start + e->length;
488 if (remaining >= total_len) {
489 /* Simple case: all the data will fit in the
490 * existing heap bucket
492 for (; i < nvec; i++) {
493 apr_size_t len = vec[i].iov_len;
494 memcpy(buf, (const void *) vec[i].iov_base, len);
497 e->length += total_len;
501 /* More complicated case: not all of the data
502 * will fit in the existing heap bucket. The
503 * total data size is <= APR_BUCKET_BUFF_SIZE,
504 * so we'll need only one additional bucket.
506 const char *start_buf = buf;
507 for (; i < nvec; i++) {
508 apr_size_t len = vec[i].iov_len;
509 if (len > remaining) {
512 memcpy(buf, (const void *) vec[i].iov_base, len);
516 e->length += (buf - start_buf);
517 total_len -= (buf - start_buf);
520 apr_status_t rv = flush(b, ctx);
521 if (rv != APR_SUCCESS) {
526 /* Now fall through into the case below to
527 * allocate another heap bucket and copy the
528 * rest of the array. (Note that i is not
529 * reset to zero here; it holds the index
530 * of the first vector element to be
531 * written to the new bucket.)
536 /* Allocate a new heap bucket, and copy the data into it.
537 * The checks above ensure that the amount of data to be
538 * written here is no larger than APR_BUCKET_BUFF_SIZE.
540 buf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->bucket_alloc);
541 e = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE,
542 apr_bucket_free, b->bucket_alloc);
543 for (; i < nvec; i++) {
544 apr_size_t len = vec[i].iov_len;
545 memcpy(buf, (const void *) vec[i].iov_base, len);
548 e->length = total_len;
549 APR_BRIGADE_INSERT_TAIL(b, e);
554 APU_DECLARE(apr_status_t) apr_brigade_puts(apr_bucket_brigade *bb,
555 apr_brigade_flush flush, void *ctx,
558 apr_size_t len = strlen(str);
559 apr_bucket *bkt = APR_BRIGADE_LAST(bb);
560 if (!APR_BRIGADE_EMPTY(bb) && APR_BUCKET_IS_HEAP(bkt)) {
561 /* If there is enough space available in a heap bucket
562 * at the end of the brigade, copy the string directly
563 * into the heap bucket
565 apr_bucket_heap *h = bkt->data;
566 apr_size_t bytes_avail = h->alloc_len - bkt->length;
568 if (bytes_avail >= len) {
569 char *buf = h->base + bkt->start + bkt->length;
570 memcpy(buf, str, len);
576 /* If the string could not be copied into an existing heap
577 * bucket, delegate the work to apr_brigade_write(), which
578 * knows how to grow the brigade
580 return apr_brigade_write(bb, flush, ctx, str, len);
583 APU_DECLARE_NONSTD(apr_status_t) apr_brigade_putstrs(apr_bucket_brigade *b,
584 apr_brigade_flush flush,
591 rv = apr_brigade_vputstrs(b, flush, ctx, va);
596 APU_DECLARE_NONSTD(apr_status_t) apr_brigade_printf(apr_bucket_brigade *b,
597 apr_brigade_flush flush,
599 const char *fmt, ...)
605 rv = apr_brigade_vprintf(b, flush, ctx, fmt, ap);
610 struct brigade_vprintf_data_t {
611 apr_vformatter_buff_t vbuff;
613 apr_bucket_brigade *b; /* associated brigade */
614 apr_brigade_flush *flusher; /* flushing function */
617 char *cbuff; /* buffer to flush from */
620 static apr_status_t brigade_flush(apr_vformatter_buff_t *buff)
622 /* callback function passed to ap_vformatter to be
623 * called when vformatter needs to buff and
624 * buff.curpos > buff.endpos
627 /* "downcast," have really passed a brigade_vprintf_data_t* */
628 struct brigade_vprintf_data_t *vd = (struct brigade_vprintf_data_t*)buff;
629 apr_status_t res = APR_SUCCESS;
631 res = apr_brigade_write(vd->b, *vd->flusher, vd->ctx, vd->cbuff,
632 APR_BUCKET_BUFF_SIZE);
634 if(res != APR_SUCCESS) {
638 vd->vbuff.curpos = vd->cbuff;
639 vd->vbuff.endpos = vd->cbuff + APR_BUCKET_BUFF_SIZE;
644 APU_DECLARE(apr_status_t) apr_brigade_vprintf(apr_bucket_brigade *b,
645 apr_brigade_flush flush,
647 const char *fmt, va_list va)
649 /* the cast, in order of appearance */
650 struct brigade_vprintf_data_t vd;
651 char buf[APR_BUCKET_BUFF_SIZE];
654 vd.vbuff.curpos = buf;
655 vd.vbuff.endpos = buf + APR_BUCKET_BUFF_SIZE;
661 written = apr_vformatter(brigade_flush, &vd.vbuff, fmt, va);
667 /* write out what remains in the buffer */
668 return apr_brigade_write(b, flush, ctx, buf, vd.vbuff.curpos - buf);