Commit afb6f730 authored by Andre Malo's avatar Andre Malo
Browse files

xml validation and drop the <pre>


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@532107 13f79535-47bb-0310-9956-ffa450edef68
parent 5a6908e8
Loading
Loading
Loading
Loading
+114 −92
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@
    <code>FLUSH</code> buckets.</p>

    <example><title>Example bucket brigade</title>
    <pre>HEAP FLUSH FILE EOS</pre></example>
    HEAP FLUSH FILE EOS</example>

    <p>This shows a bucket brigade which may be passed to a filter; it
    contains two metadata buckets (<code>FLUSH</code> and
@@ -118,13 +118,17 @@
    be prepared to accept an empty brigade, and do nothing.</p>

    <example><title>How to handle an empty brigade</title>
    
    <pre>apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
    if (APR_BRIGADE_EMPTY(bb)) {
        return APR_SUCCESS;
    }
    ....</pre></example>
    apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)<br />
    {<br />
    <indent>
        if (APR_BRIGADE_EMPTY(bb)) {<br />
        <indent>
            return APR_SUCCESS;<br />
        </indent>
        }<br />
        ....<br />
    </indent>
    </example>

  </section>

@@ -143,7 +147,7 @@
    <p>There are a variety of functions and macros for traversing and
    manipulating bucket brigades; see the <a
    href="http://apr.apache.org/docs/apr-util/trunk/group___a_p_r___util___bucket___brigades.html">apr_bucket.h</a>
    header for complete coverage.  Commonly used macros include:
    header for complete coverage.  Commonly used macros include:</p>

    <dl>
      <dt><code>APR_BRIGADE_FIRST(bb)</code></dt>
@@ -158,7 +162,7 @@
      <dt><code>APR_BUCKET_PREV(e)</code></dt>
      <dd>gives the bucket before bucket e</dd>

    </dl></p>
    </dl>

    <p>The <code>apr_bucket_brigade</code> structure itself is
    allocated out of a pool, so if a filter creates a new brigade, it
@@ -193,7 +197,7 @@

    <p>When dealing with non-metadata buckets, it is important to
    understand that the "<code>apr_bucket *</code>" object is an
    abstract <em>representation</em> of data:
    abstract <em>representation</em> of data:</p>

    <ol>
      <li>The amount of data represented by the bucket may or may not
@@ -208,7 +212,7 @@
      represents data stored in a file on disk.</li>
    </ol>

    Filters read the data from a bucket using the
    <p>Filters read the data from a bucket using the
    <code>apr_bucket_read</code> function.  When this function is
    invoked, the bucket may <em>morph</em> into a different bucket
    type, and may also insert a new bucket into the bucket brigade.
@@ -219,7 +223,7 @@
    single <code>FILE</code> bucket representing an entire file, 24
    kilobytes in size:</p>

    <example><pre>FILE(0K-24K)</pre></example>
    <example>FILE(0K-24K)</example>

    <p>When this bucket is read, it will read a block of data from the
    file, morph into a <code>HEAP</code> bucket to represent that
@@ -228,7 +232,7 @@
    after the <code>apr_bucket_read</code> call, the brigade looks
    like:</p>

    <example><pre>HEAP(8K) FILE(8K-24K)</pre></example>
    <example>HEAP(8K) FILE(8K-24K)</example>

  </section>

@@ -241,21 +245,24 @@
    loop is critical to producing a well-behaved output filter.</p>

    <p>Taking an example which loops through the entire brigade as
    follows:
    follows:</p>

    <example><title>Bad output filter -- do not imitate!</title>
    <pre>apr_bucket *e = APR_BRIGADE_FIRST(bb);
const char *data;
apr_size_t len;

while (e != APR_BRIGADE_SENTINEL(bb)) {
   apr_bucket_read(e, &amp;data, &amp;length, APR_BLOCK_READ);
   e = APR_BUCKET_NEXT(e);
}

return ap_pass_brigade(bb);</pre></example>

    The above implementation would consume memory proportional to
    apr_bucket *e = APR_BRIGADE_FIRST(bb);<br />
const char *data;<br />
apr_size_t len;<br />
<br />
while (e != APR_BRIGADE_SENTINEL(bb)) {<br />
<indent>
    apr_bucket_read(e, &amp;data, &amp;length, APR_BLOCK_READ);<br />
    e = APR_BUCKET_NEXT(e);<br />
</indent>
}<br />
<br />
return ap_pass_brigade(bb);
    </example>

    <p>The above implementation would consume memory proportional to
    content size.  If passed a <code>FILE</code> bucket, for example,
    the entire file contents would be read into memory as each
    <code>apr_bucket_read</code> call morphed a <code>FILE</code>
@@ -267,23 +274,25 @@ return ap_pass_brigade(bb);</pre></example>
    href="#state">Maintaining state</a> section.</p>

    <example><title>Better output filter</title>

    <pre>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, &amp;data, &amp;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);
}</pre></example>
apr_bucket *e;<br />
const char *data;<br />
apr_size_t len;<br />
<br />
while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {<br />
<indent>
   rv = apr_bucket_read(e, &amp;data, &amp;length, APR_BLOCK_READ);<br />
   if (rv) ...;<br />
   /* Remove bucket e from bb. */<br />
   APR_BUCKET_REMOVE(e);<br />
   /* Insert it into  temporary brigade. */<br />
   APR_BRIGADE_INSERT_HEAD(tmpbb, e);<br />
   /* Pass brigade downstream. */<br />
   rv = ap_pass_brigade(f->next, tmpbb);<br />
   if (rv) ...;<br />
   apr_brigade_cleanup(tmpbb);<br />
</indent>
}
    </example>

  </section>

@@ -299,26 +308,33 @@ while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {
    href="#brigade">Brigade structure</a> section.</p>
    
  <example><title>Example code to maintain filter state</title>

  <pre>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 = ...;
    }
    ...</pre></example>
struct dummy_state {<br />
<indent>
   apr_bucket_brigade *tmpbb;<br />
   int filter_state;<br />
   ....<br />
</indent>
};<br />
<br />
apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)<br />
{<br />
<indent>
    struct dummy_state *state;<br />
<br />
    state = f->ctx;<br />
    if (state == NULL) {<br />
    <indent>
       /* First invocation for this response: initialise state structure.
        */<br />
       f->ctx = state = apr_palloc(sizeof *state, f->r->pool);<br />
<br />
       state->tmpbb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);<br />
       state->filter_state = ...;<br />
    </indent>
    }<br />
    ...
</indent>
    </example>

  </section>
  
@@ -343,7 +359,7 @@ apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)
    used, which will move all the buckets into a separate brigade
    containing buckets with a lifetime as long as the given pool
    argument.  This function must be used with care, taking into
    account the following points:
    account the following points:</p>

    <ol>
      <li>On return, <code>ap_save_brigade</code> 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 <a
      href="#brigade">Brigade structure</a> section.</li>
    </ol></p>
    </ol>

    <note type="warning">Filters must ensure that any buffered data is
    processed and passed down the filter chain during the last
@@ -395,32 +411,38 @@ apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)

    <example>
      <title>Example code using non-blocking bucket reads</title>

<pre>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, &amp;data, &amp;length, mode);
    if (rv == APR_EAGAIN &amp;&amp; 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 */
apr_bucket *e;<br />
apr_read_type_e mode = APR_NONBLOCK_READ;<br />
<br />
while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {<br />
<indent>
    apr_status_t rv;<br />
<br />
    rv = apr_bucket_read(e, &amp;data, &amp;length, mode);<br />
    if (rv == APR_EAGAIN &amp;&amp; mode == APR_NONBLOCK_READ) {<br />
    <indent>
        /* Pass down a brigade containing a flush bucket: */<br />
        APR_BRIGADE_INSERT_TAIL(tmpbb, apr_bucket_flush_create(...));<br />
        rv = ap_pass_brigade(f->next, tmpbb);<br />
        apr_brigade_cleanup(tmpbb);<br />
        if (rv != APR_SUCCESS) return rv;<br />
<br />
        /* Retry, using a blocking read. */<br />
        mode = APR_BLOCK_READ;<br />
        continue;<br />
    </indent>
    } else if (rv != APR_SUCCESS) {<br />
    <indent>
        /* handle errors */<br />
    </indent>
    }<br />
<br />
    /* Next time, try a non-blocking read first. */<br />
    mode = APR_NONBLOCK_READ;<br />
    ...<br />
</indent>
}

    /* Next time, try a non-blocking read first. */
    mode = APR_NONBLOCK_READ;
    ...
}</pre></example>
    </example>

  </section>

+2 −3
Original line number Diff line number Diff line
@@ -468,9 +468,8 @@ expressions</description>
	and later.</compatibility>
<usage>
    <p>This directive adds a member to a load balancing group. It must be used
    within a <directive module="mod_proxy">&lt;Proxy <var
    >balancer://</var>...&gt;</directive> container directive, and can take any
    of the parameters available to 
    within a <code>&lt;Proxy <var>balancer://</var>...&gt;</code> container
    directive, and can take any of the parameters available to
    <directive module="mod_proxy">ProxyPass</directive> directives.</p>
    <p>One additional parameter is available only to <directive
    module="mod_proxy">BalancerMember</directive> directives: