From: André Malo
X-Git-Tag: 2.3.0~1831
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42eda3eb2c1c530ff9fb2efffa09fc4f61d3a536;p=thirdparty%2Fapache%2Fhttpd.git
xml validation and drop the
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@532107 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/docs/manual/developer/output-filters.xml b/docs/manual/developer/output-filters.xml
index 351f46a222d..3159677f944 100644
--- a/docs/manual/developer/output-filters.xml
+++ b/docs/manual/developer/output-filters.xml
@@ -82,7 +82,7 @@
FLUSH
buckets.
HEAP FLUSH FILE EOS
This shows a bucket brigade which may be passed to a filter; it
contains two metadata buckets (FLUSH
and
@@ -118,13 +118,17 @@
be prepared to accept an empty brigade, and do nothing.
apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb) -{ - if (APR_BRIGADE_EMPTY(bb)) { - return APR_SUCCESS; - } - ....
There are a variety of functions and macros for traversing and manipulating bucket brigades; see the apr_bucket.h - header for complete coverage. Commonly used macros include: + header for complete coverage. Commonly used macros include:
APR_BRIGADE_FIRST(bb)
APR_BUCKET_PREV(e)
The apr_bucket_brigade
structure itself is
allocated out of a pool, so if a filter creates a new brigade, it
@@ -193,7 +197,7 @@
When dealing with non-metadata buckets, it is important to
understand that the "apr_bucket *
" object is an
- abstract representation of data:
+ abstract representation of data:
Filters read the data from a bucket using the
apr_bucket_read
function. When this function is
invoked, the bucket may morph into a different bucket
type, and may also insert a new bucket into the bucket brigade.
@@ -219,7 +223,7 @@
single FILE
bucket representing an entire file, 24
kilobytes in size:
FILE(0K-24K)
When this bucket is read, it will read a block of data from the
file, morph into a HEAP
bucket to represent that
@@ -228,7 +232,7 @@
after the apr_bucket_read
call, the brigade looks
like:
HEAP(8K) FILE(8K-24K)
Taking an example which loops through the entire brigade as - follows: + follows:
apr_bucket *e = APR_BRIGADE_FIRST(bb); -const char *data; -apr_size_t len; - -while (e != APR_BRIGADE_SENTINEL(bb)) { - apr_bucket_read(e, &data, &length, APR_BLOCK_READ); - e = APR_BUCKET_NEXT(e); -} - -return ap_pass_brigade(bb);
The above implementation would consume memory proportional to
content size. If passed a FILE
bucket, for example,
the entire file contents would be read into memory as each
apr_bucket_read
call morphed a FILE
@@ -267,23 +274,25 @@ return ap_pass_brigade(bb);
href="#state">Maintaining state section.
apr_bucket *e; -const char *data; -apr_size_t len; - -while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) { - rv = apr_bucket_read(e, &data, &length, APR_BLOCK_READ); - if (rv) ...; - /* Remove bucket e from bb. */ - APR_BUCKET_REMOVE(e); - /* Insert it into temporary brigade. */ - APR_BRIGADE_INSERT_HEAD(tmpbb, e); - /* Pass brigade downstream. */ - rv = ap_pass_brigade(f->next, tmpbb); - if (rv) ...; - apr_brigade_cleanup(tmpbb); -}
struct dummy_state { - apr_bucket_brigade *tmpbb; - int filter_state; - .... -}; - -apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb) -{ - struct dummy_state *state; - - state = f->ctx; - if (state == NULL) { - /* First invocation for this response: initialise state structure. */ - f->ctx = state = apr_palloc(sizeof *state, f->r->pool); - - state->tmpbb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); - state->filter_state = ...; - } - ...-
ap_save_brigade
guarantees that all
@@ -363,7 +379,7 @@ apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)
the function will create a new brigade, which may cause memory
use to be proportional to content size as described in the Brigade structure section.apr_bucket *e; -apr_read_type_e mode = APR_NONBLOCK_READ; - -while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) { - apr_status_t rv; - - rv = apr_bucket_read(e, &data, &length, mode); - if (rv == APR_EAGAIN && mode == APR_NONBLOCK_READ) { - /* Pass down a brigade containing a flush bucket: */ - APR_BRIGADE_INSERT_TAIL(tmpbb, apr_bucket_flush_create(...)); - rv = ap_pass_brigade(f->next, tmpbb); - apr_brigade_cleanup(tmpbb); - if (rv != APR_SUCCESS) return rv; - - /* Retry, using a blocking read. */ - mode = APR_BLOCK_READ; - continue; - } else if (rv != APR_SUCCESS) { - /* handle errors */ - } - - /* Next time, try a non-blocking read first. */ - mode = APR_NONBLOCK_READ; - ... -}
This directive adds a member to a load balancing group. It must be used
- within a <Proxy balancer://...>
container
+ directive, and can take any of the parameters available to
One additional parameter is available only to