#include "h2_private.h"
#include "h2_conn_ctx.h"
+#include "h2_headers.h"
#include "h2_util.h"
#include "h2_bucket_beam.h"
} while (0)
-/* registry for bucket converting `h2_bucket_beamer` functions */
-static apr_array_header_t *beamers;
-
-static apr_status_t cleanup_beamers(void *dummy)
-{
- (void)dummy;
- beamers = NULL;
- return APR_SUCCESS;
-}
-
-void h2_register_bucket_beamer(h2_bucket_beamer *beamer)
-{
- if (!beamers) {
- apr_pool_cleanup_register(apr_hook_global_pool, NULL,
- cleanup_beamers, apr_pool_cleanup_null);
- beamers = apr_array_make(apr_hook_global_pool, 10,
- sizeof(h2_bucket_beamer*));
- }
- APR_ARRAY_PUSH(beamers, h2_bucket_beamer*) = beamer;
-}
-
-static apr_bucket *h2_beam_bucket(h2_bucket_beam *beam,
- apr_bucket_brigade *dest,
- const apr_bucket *src)
-{
- apr_bucket *b = NULL;
- int i;
- if (beamers) {
- for (i = 0; i < beamers->nelts && b == NULL; ++i) {
- h2_bucket_beamer *beamer;
-
- beamer = APR_ARRAY_IDX(beamers, i, h2_bucket_beamer*);
- b = beamer(beam, dest, src);
- }
- }
- return b;
-}
-
static int is_empty(h2_bucket_beam *beam);
static apr_off_t get_buffered_data_len(h2_bucket_beam *beam);
else if (APR_BUCKET_IS_FLUSH(bsender)) {
brecv = apr_bucket_flush_create(bb->bucket_alloc);
}
+ else if (H2_BUCKET_IS_HEADERS(bsender)) {
+ brecv = h2_bucket_headers_clone(bsender, bb->p, bb->bucket_alloc);
+ }
else if (AP_BUCKET_IS_ERROR(bsender)) {
ap_bucket_error *eb = (ap_bucket_error *)bsender;
brecv = ap_bucket_error_create(eb->status, eb->data,
bb->p, bb->bucket_alloc);
}
- else {
- /* Does someone else know how to make a proxy for
- * the bucket? Ask the callbacks registered for this. */
- brecv = h2_beam_bucket(beam, bb, bsender);
- while (brecv && brecv != APR_BRIGADE_SENTINEL(bb)) {
- ++transferred;
- remain -= brecv->length;
- brecv = APR_BUCKET_NEXT(brecv);
- }
- brecv = NULL;
- }
}
else if (bsender->length == 0) {
/* nop */
apr_bucket_shared_copy
};
-apr_bucket *h2_bucket_headers_beam(struct h2_bucket_beam *beam,
- apr_bucket_brigade *dest,
- const apr_bucket *src)
+apr_bucket *h2_bucket_headers_clone(apr_bucket *src, apr_pool_t *p, apr_bucket_alloc_t *list)
{
- if (H2_BUCKET_IS_HEADERS(src)) {
- h2_headers *src_headers = ((h2_bucket_headers *)src->data)->headers;
- apr_bucket *b = h2_bucket_headers_create(dest->bucket_alloc,
- h2_headers_clone(dest->p, src_headers));
- APR_BRIGADE_INSERT_TAIL(dest, b);
- return b;
- }
- return NULL;
+ h2_headers *src_headers;
+
+ AP_DEBUG_ASSERT(H2_BUCKET_IS_HEADERS(src));
+ src_headers = ((h2_bucket_headers *)src->data)->headers;
+ return h2_bucket_headers_create(list, h2_headers_clone(p, src_headers));
}
h2_headers *h2_bucket_headers_get(apr_bucket *b);
-apr_bucket *h2_bucket_headers_beam(struct h2_bucket_beam *beam,
- apr_bucket_brigade *dest,
- const apr_bucket *src);
+apr_bucket *h2_bucket_headers_clone(apr_bucket *src,
+ apr_pool_t *p,
+ apr_bucket_alloc_t *list);
/**
* Create the headers from the given status and headers