apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "William A. Rowe, Jr." <wr...@covalent.net>
Subject Re: bug in apr_brigade.c
Date Thu, 24 Jan 2002 14:07:25 GMT
From: "Greg Stein" <gstein@lyra.org>
Sent: Thursday, January 24, 2002 3:30 AM


> On Wed, Jan 23, 2002 at 12:07:33PM -0600, William A. Rowe, Jr. wrote:
>
> > 'bucket' is a unit that _may_ be read into memory (although it need not)
> > while the 'brigade' may obviously be huge.
>
> No. A bucket is a unit of data. Totally unrelated to reading into memory.
>
> It is *entirely* feasible to create a bucket that represents 20G of data and
> then shove that out a socket.

Yes, it is feasable.  Is it practical?

While the patches below did not introduce complete solutions (later we divided
up the file into sendfile buckets in MAX_SENDFILE chunks), it provided one
of the possible resolutions of the issue.

Sure, I wrote parts of the patch you describe.  The net cost?  Many more lines
of code to deal with testing the size before we slurp it into memory.

Justin hadn't realized this definition, or he wouldn't have given up on
implementing LARGEFILE support.  The [common] code builds 32/64 bit
apr_size_t/apr_off_t cleanly.  sendfile does not need to implement apr_off_t
sendfiles, because that is no longer the definition of a bucket to sendfile.

But he is right... if we have consistent apr_off_t sizes for both buckets and
brigades, the task is far more onerous.  Our code makes the consistent,
implicit assumption that you can morph a bucket type into another bucket type.
That assumption becomes faulty, buggy, or introduces segfaults as soon as you
introduces buckets >apr_size_t.

So I respect your point that it could be done.  The question is, does it
provide us any significant benefit worth adding the overhead to support it?

> > We've been through this; read the threads please.  But long story short, a
>
> That's a cop out. "read the threads" ... how is a person to start? There are
> a billion threads on buckets, brigades, filtering, etc.

fair enough - but this horse has been thoroughly whipped.

http://www.google.com/search?as_q=apr_off_t+brigade+apr_size_t+bucket&num=10&btnG=Google+Search&as_epq=&as_oq=&as_eq=&lr=&as_ft=i&as
_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=apachelabs.org&safe=off

should provide a reasonable overview.

Bill




> wrowe       01/07/24 13:36:03
>
>   Modified:    .        CHANGES
>                buckets  apr_brigade.c apr_buckets.c apr_buckets_file.c
>                         apr_buckets_pipe.c apr_buckets_refcount.c
>                         apr_buckets_simple.c apr_buckets_socket.c
>                include  apr_buckets.h
>   Log:
>     Consistently use apr_size_t for the bucket size, and apr_off_t to manipulate
>     brigades (which may consist of several buckets near MAX(apr_size_t) length.)
>
>   Revision  Changes    Path
>   1.23      +4 -0      apr-util/CHANGES
>
>   Index: CHANGES
>   ===================================================================
>   RCS file: /home/cvs/apr-util/CHANGES,v
>   retrieving revision 1.22
>   retrieving revision 1.23
>   diff -u -r1.22 -r1.23
>   --- CHANGES 2001/06/27 20:14:58 1.22
>   +++ CHANGES 2001/07/24 20:36:03 1.23
>   @@ -1,5 +1,9 @@
>    Changes with APR-util b1
>
>   +  *) The apr_bucket lengths are now consistently apr_size_t, while any
>   +     apr_brigade lengths (short of a read) are consistently apr_off_t.
>   +     This is required for APR_HAS_LARGE_FILES handling.  [William Rowe]
>   +
>      *) apr_bucket_file_create() and apr_bucket_file_make() now take a pool
>         parameter which is the pool into which any needed data structures
>         should be created during file_read().  This is used for MMAPing the
>
>
>
>   1.19      +20 -9     apr-util/buckets/apr_brigade.c
>
>   Index: apr_brigade.c
>   ===================================================================
>   RCS file: /home/cvs/apr-util/buckets/apr_brigade.c,v
>   retrieving revision 1.18
>   retrieving revision 1.19
>   diff -u -r1.18 -r1.19
>   --- apr_brigade.c 2001/06/20 01:17:28 1.18
>   +++ apr_brigade.c 2001/07/24 20:36:03 1.19
>   @@ -146,17 +146,28 @@
>        }
>
>        APR_BRIGADE_FOREACH(e, b) {
>   -        if ((point < e->length) || (e->length == -1)) {
>   -            /* try to split the bucket natively */
>   -            if ((rv = apr_bucket_split(e, point)) != APR_ENOTIMPL) {
>   +        if ((point > (apr_size_t)(-1)) && (e->length == (apr_size_t)(-1)))
{
>   +            /* XXX: point is too far out to simply split this bucket,
>   +             * we must fix this bucket's size and keep going... */
>   +            if ((rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ))
>   +                    != APR_SUCCESS) {
>   +                return rv;
>   +            }
>   +        }
>   +        if ((point < e->length) || (e->length == (apr_size_t)(-1))) {
>   +            /* We already checked e->length -1 above, so we now
>   +             * trust e->length < MAX_APR_SIZE_T.
>   +             * First try to split the bucket natively... */
>   +            if ((rv = apr_bucket_split(e, (apr_size_t)point))
>   +                    != APR_ENOTIMPL) {
>                    *after_point = APR_BUCKET_NEXT(e);
>                    return rv;
>                }
>
>                /* if the bucket cannot be split, we must read from it,
>                 * changing its type to one that can be split */
>   -            if ((rv = apr_bucket_read(e, &s, &len,
>   -                                      APR_BLOCK_READ)) != APR_SUCCESS) {
>   +            if ((rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ))
>   +                    != APR_SUCCESS) {
>                    return rv;
>                }
>
>   @@ -164,7 +175,7 @@
>                 * might have been morphed by the apr_bucket_read() above, but
>                 * if it was, the length would have been adjusted appropriately */
>                if (point < e->length) {
>   -                rv = apr_bucket_split(e, point);
>   +                rv = apr_bucket_split(e, (apr_size_t)point);
>                    *after_point = APR_BUCKET_NEXT(e);
>                    return rv;
>                }
>   @@ -179,13 +190,13 @@
>    }
>
>    APU_DECLARE(apr_status_t) apr_brigade_length(apr_bucket_brigade *bb,
>   -                                             int read_all, apr_ssize_t *length)
>   +                                             int read_all, apr_off_t *length)
>    {
>   -    apr_ssize_t total = 0;
>   +    apr_off_t total = 0;
>        apr_bucket *bkt;
>
>        APR_BRIGADE_FOREACH(bkt, bb) {
>   -        if (bkt->length == -1) {
>   +        if (bkt->length == (apr_size_t)(-1)) {
>                const char *ignore;
>                apr_size_t len;
>                apr_status_t status;
>
>
>
>   1.52      +1 -1      apr-util/buckets/apr_buckets.c
>
>   Index: apr_buckets.c
>   ===================================================================
>   RCS file: /home/cvs/apr-util/buckets/apr_buckets.c,v
>   retrieving revision 1.51
>   retrieving revision 1.52
>   diff -u -r1.51 -r1.52
>   --- apr_buckets.c 2001/06/13 19:16:05 1.51
>   +++ apr_buckets.c 2001/07/24 20:36:03 1.52
>   @@ -67,7 +67,7 @@
>    }
>
>    APU_DECLARE_NONSTD(apr_status_t) apr_bucket_split_notimpl(apr_bucket *data,
>   -                                                          apr_off_t point)
>   +                                                          apr_size_t point)
>    {
>        return APR_ENOTIMPL;
>    }
>
>
>
>   1.51      +3 -3      apr-util/buckets/apr_buckets_file.c
>
>   Index: apr_buckets_file.c
>   ===================================================================
>   RCS file: /home/cvs/apr-util/buckets/apr_buckets_file.c,v
>   retrieving revision 1.50
>   retrieving revision 1.51
>   diff -u -r1.50 -r1.51
>   --- apr_buckets_file.c 2001/07/19 12:35:44 1.50
>   +++ apr_buckets_file.c 2001/07/24 20:36:03 1.51
>   @@ -93,7 +93,7 @@
>    }
>
>    #if APR_HAS_MMAP
>   -static int file_make_mmap(apr_bucket *e, apr_off_t filelength,
>   +static int file_make_mmap(apr_bucket *e, apr_size_t filelength,
>                               apr_off_t fileoffset, apr_pool_t *p)
>    {
>        apr_bucket_file *a = e->data;
>   @@ -130,7 +130,7 @@
>        apr_bucket *b = NULL;
>        char *buf;
>        apr_status_t rv;
>   -    apr_off_t filelength = e->length;  /* bytes remaining in file past offset */
>   +    apr_size_t filelength = e->length;  /* bytes remaining in file past offset
*/
>        apr_off_t fileoffset = e->start;
>    #if APR_HAS_THREADS && !APR_HAS_XTHREAD_FILES
>        apr_int32_t flags;
>   @@ -237,7 +237,7 @@
>        apr_file_t *f = a->fd;
>        apr_pool_t *curpool = apr_file_pool_get(f);
>    #if APR_HAS_MMAP
>   -    apr_off_t filelength = data->length;  /* bytes remaining in file past offset
*/
>   +    apr_size_t filelength = data->length;  /* bytes remaining in file past offset
*/
>        apr_off_t fileoffset = data->start;
>    #endif
>
>
>
>
>   1.37      +1 -1      apr-util/buckets/apr_buckets_pipe.c
>
>   Index: apr_buckets_pipe.c
>   ===================================================================
>   RCS file: /home/cvs/apr-util/buckets/apr_buckets_pipe.c,v
>   retrieving revision 1.36
>   retrieving revision 1.37
>   diff -u -r1.36 -r1.37
>   --- apr_buckets_pipe.c 2001/06/19 18:48:29 1.36
>   +++ apr_buckets_pipe.c 2001/07/24 20:36:03 1.37
>   @@ -135,7 +135,7 @@
>         * buckets created by pipe_read() above.
>         */
>        b->type     = &apr_bucket_type_pipe;
>   -    b->length   = -1;
>   +    b->length   = (apr_size_t)(-1);
>        b->start    = -1;
>        b->data     = p;
>
>
>
>
>   1.17      +2 -2      apr-util/buckets/apr_buckets_refcount.c
>
>   Index: apr_buckets_refcount.c
>   ===================================================================
>   RCS file: /home/cvs/apr-util/buckets/apr_buckets_refcount.c,v
>   retrieving revision 1.16
>   retrieving revision 1.17
>   diff -u -r1.16 -r1.17
>   --- apr_buckets_refcount.c 2001/02/28 17:52:44 1.16
>   +++ apr_buckets_refcount.c 2001/07/24 20:36:03 1.17
>   @@ -55,7 +55,7 @@
>    #include "apr_buckets.h"
>
>    APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_split(apr_bucket *a,
>   -                                                         apr_off_t point)
>   +                                                         apr_size_t point)
>    {
>        apr_bucket_refcount *r = a->data;
>        apr_status_t rv;
>   @@ -91,7 +91,7 @@
>
>    APU_DECLARE(apr_bucket *) apr_bucket_shared_make(apr_bucket *b, void *data,
>                                                     apr_off_t start,
>   -                                                 apr_off_t length)
>   +                                                 apr_size_t length)
>    {
>        apr_bucket_refcount *r = data;
>
>
>
>
>   1.30      +2 -2      apr-util/buckets/apr_buckets_simple.c
>
>   Index: apr_buckets_simple.c
>   ===================================================================
>   RCS file: /home/cvs/apr-util/buckets/apr_buckets_simple.c,v
>   retrieving revision 1.29
>   retrieving revision 1.30
>   diff -u -r1.29 -r1.30
>   --- apr_buckets_simple.c 2001/06/19 18:48:32 1.29
>   +++ apr_buckets_simple.c 2001/07/24 20:36:03 1.30
>   @@ -67,12 +67,12 @@
>    }
>
>    APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_split(apr_bucket *a,
>   -                                                         apr_off_t point)
>   +                                                         apr_size_t point)
>    {
>        apr_bucket *b;
>        apr_status_t rv;
>
>   -    if (point < 0 || point > a->length) {
>   +    if ((point > a->length) || (a->length == (apr_size_t)(-1))) {
>    return APR_EINVAL;
>        }
>
>
>
>
>   1.26      +1 -1      apr-util/buckets/apr_buckets_socket.c
>
>   Index: apr_buckets_socket.c
>   ===================================================================
>   RCS file: /home/cvs/apr-util/buckets/apr_buckets_socket.c,v
>   retrieving revision 1.25
>   retrieving revision 1.26
>   diff -u -r1.25 -r1.26
>   --- apr_buckets_socket.c 2001/06/19 18:48:33 1.25
>   +++ apr_buckets_socket.c 2001/07/24 20:36:03 1.26
>   @@ -130,7 +130,7 @@
>         * so it will disappear when the connection is finished.
>         */
>        b->type     = &apr_bucket_type_socket;
>   -    b->length   = -1;
>   +    b->length   = (apr_size_t)(-1);
>        b->start    = -1;
>        b->data     = p;
>
>
>
>
>   1.103     +18 -18    apr-util/include/apr_buckets.h
>
>   Index: apr_buckets.h
>   ===================================================================
>   RCS file: /home/cvs/apr-util/include/apr_buckets.h,v
>   retrieving revision 1.102
>   retrieving revision 1.103
>   diff -u -r1.102 -r1.103
>   --- apr_buckets.h 2001/07/24 18:54:48 1.102
>   +++ apr_buckets.h 2001/07/24 20:36:03 1.103
>   @@ -201,9 +201,9 @@
>         *  as with pipe and socket buckets), then APR_ENOTIMPL is returned.
>         * @param e The bucket to split
>         * @param point The offset of the first byte in the new bucket
>   -     * @deffunc apr_status_t split(apr_bucket *e, apr_off_t point)
>   +     * @deffunc apr_status_t split(apr_bucket *e, apr_size_t point)
>         */
>   -    apr_status_t (*split)(apr_bucket *e, apr_off_t point);
>   +    apr_status_t (*split)(apr_bucket *e, apr_size_t point);
>
>        /**
>         * Copy the bucket structure (not the data), assuming that this is
>   @@ -233,15 +233,15 @@
>        /** The length of the data in the bucket.  This could have been implemented
>         *  with a function, but this is an optimization, because the most
>         *  common thing to do will be to get the length.  If the length is unknown,
>   -     *  the value of this field will be -1.
>   +     *  the value of this field will be (apr_size_t)(-1).
>         */
>   -    apr_off_t length;
>   +    apr_size_t length;
>        /** The start of the data in the bucket relative to the private base
>         *  pointer.  The vast majority of bucket types allow a fixed block of
>         *  data to be referenced by multiple buckets, each bucket pointing to
>         *  a different segment of the data.  That segment starts at base+start
>         *  and ends at base+start+length.
>   -     *  If the length == -1, then start == -1.
>   +     *  If the length == (apr_size_t)(-1), then start == -1.
>         */
>        apr_off_t start;
>        /** type-dependent data hangs off this pointer */
>   @@ -652,10 +652,10 @@
>     * appropriate, and/or modify start on last element
>     * @param b The brigade to consume data from
>     * @param nbytes The number of bytes to consume
>   - * @deffunc void apr_brigade_consume(apr_bucket_brigade *b, apr_size_t nbytes)
>   + * @deffunc void apr_brigade_consume(apr_bucket_brigade *b, apr_off_t nbytes)
>     */
>    APU_DECLARE(void) apr_brigade_consume(apr_bucket_brigade *b,
>   -                                      apr_size_t nbytes);
>   +                                      apr_off_t nbytes);
>    #endif
>
>    /**
>   @@ -663,11 +663,11 @@
>     * @param bb The brigade to compute the length of
>     * @param read_all Read unknown-length buckets to force a size
>     @ @param length Set to length of the brigade, or -1 if it has unknown-length buckets
>   - * @deffunc apr_status_t apr_brigade_length(apr_bucket_brigade *bb, int read_all,
apr_ssize_t *length)
>   + * @deffunc apr_status_t apr_brigade_length(apr_bucket_brigade *bb, int read_all,
apr_off_t *length)
>     */
>    APU_DECLARE(apr_status_t) apr_brigade_length(apr_bucket_brigade *bb,
>                                                 int read_all,
>   -                                             apr_ssize_t *length);
>   +                                             apr_off_t *length);
>
>    /**
>     * create an iovec of the elements in a bucket_brigade... return number
>   @@ -820,7 +820,7 @@
>     * Split one bucket in two.
>     * @param e The bucket to split
>     * @param point The offset to split the bucket at
>   - * @deffunc apr_status_t apr_bucket_split(apr_bucket *e, apr_off_t point)
>   + * @deffunc apr_status_t apr_bucket_split(apr_bucket *e, apr_size_t point)
>     */
>    #define apr_bucket_split(e,point) (e)->type->split(e, point)
>
>   @@ -864,10 +864,10 @@
>     * @param data The bucket to split
>     * @param point The location to split the bucket
>     * @return APR_ENOTIMPL
>   - * @deffunc apr_status_t apr_bucket_split_notimpl(apr_bucket *data, apr_off_t point)
>   + * @deffunc apr_status_t apr_bucket_split_notimpl(apr_bucket *data, apr_size_t point)
>     */
>    APU_DECLARE_NONSTD(apr_status_t) apr_bucket_split_notimpl(apr_bucket *data,
>   -                                                          apr_off_t point);
>   +                                                          apr_size_t point);
>
>    /**
>     * A place holder function that signifies that the copy function was not
>   @@ -969,10 +969,10 @@
>     * @return APR_EINVAL if the point is not within the bucket;
>     *         APR_ENOMEM if allocation failed;
>     *         or APR_SUCCESS
>   - * @deffunc apr_status_t apr_bucket_simple_split(apr_bucket *b, apr_off_t point)
>   + * @deffunc apr_status_t apr_bucket_simple_split(apr_bucket *b, apr_size_t point)
>     */
>    APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_split(apr_bucket *b,
>   -                                                         apr_off_t point);
>   +                                                         apr_size_t point);
>
>    /**
>     * Copy a simple bucket.  Most non-reference-counting buckets that allow
>   @@ -1004,11 +1004,11 @@
>     *              relative to the private base pointer
>     * @param length The length of the data in the bucket
>     * @return The new bucket, or NULL if allocation failed
>   - * @deffunc apr_bucket *apr_bucket_shared_make(apr_bucket_refcount *r, void *data,
apr_off_t start, apr_off_t length)
>   + * @deffunc apr_bucket *apr_bucket_shared_make(apr_bucket_refcount *r, void *data,
apr_off_t start, apr_size_t length)
>     */
>    APU_DECLARE(apr_bucket *) apr_bucket_shared_make(apr_bucket *b, void *data,
>                     apr_off_t start,
>   -                                                 apr_off_t length);
>   +                                                 apr_size_t length);
>
>    /**
>     * Decrement the refcount of the data in the bucket. This function
>   @@ -1031,10 +1031,10 @@
>     * @return APR_EINVAL if the point is not within the bucket;
>     *         APR_ENOMEM if allocation failed;
>     *         or APR_SUCCESS
>   - * @deffunc apr_status_t apr_bucket_shared_split(apr_bucket *b, apr_off_t point)
>   + * @deffunc apr_status_t apr_bucket_shared_split(apr_bucket *b, apr_size_t point)
>     */
>    APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_split(apr_bucket *b,
>   -                                                         apr_off_t point);
>   +                                                         apr_size_t point);
>
>    /**
>     * Copy a refcounted bucket, incrementing the reference count. Most
>
>
>
>

> wrowe       01/07/24 13:38:02
>
>   Modified:    modules/cache mod_file_cache.c
>                modules/generators mod_asis.c mod_autoindex.c
>                modules/http http_protocol.c
>                server   core.c
>   Log:
>     Changes to respect the new apr bucket and brigade length types (either
>     apr_size_t for bucket lengths, or apr_off_t for aggregate brigade lengths.)
>
>   Revision  Changes    Path
>   1.59      +4 -1      httpd-2.0/modules/cache/mod_file_cache.c
>
>   Index: mod_file_cache.c
>   ===================================================================
>   RCS file: /home/cvs/httpd-2.0/modules/cache/mod_file_cache.c,v
>   retrieving revision 1.58
>   retrieving revision 1.59
>   diff -u -r1.58 -r1.59
>   --- mod_file_cache.c 2001/07/18 19:41:20 1.58
>   +++ mod_file_cache.c 2001/07/24 20:38:01 1.59
>   @@ -222,7 +222,10 @@
>
>    #if APR_HAS_MMAP
>        if (mmap) {
>   -         /* MMAPFile directive. MMAP'ing the file */
>   +        /* MMAPFile directive. MMAP'ing the file
>   +         * XXX: APR_HAS_LARGE_FILES issue; need to reject this request if
>   +         * size is greater than MAX(apr_size_t) (perhaps greater than 1M?).
>   +         */
>            if ((rc = apr_mmap_create(&new_file->mm, fd, 0, new_file->finfo.size,
>                                      APR_MMAP_READ, cmd->pool)) != APR_SUCCESS)

>                apr_file_close(fd);
>
>
>
>   1.36      +3 -0      httpd-2.0/modules/generators/mod_asis.c
>
>   Index: mod_asis.c
>   ===================================================================
>   RCS file: /home/cvs/httpd-2.0/modules/generators/mod_asis.c,v
>   retrieving revision 1.35
>   retrieving revision 1.36
>   diff -u -r1.35 -r1.36
>   --- mod_asis.c 2001/02/28 15:24:05 1.35
>   +++ mod_asis.c 2001/07/24 20:38:01 1.36
>   @@ -118,6 +118,9 @@
>        }
>
>        if (!r->header_only) {
>   +        /* XXX: APR_HAS_LARGE_FILES issue; need to split into mutiple send_fd
>   +         * chunks, no greater than MAX(apr_size_t).
>   +         */
>    ap_send_fd(f, r, 0, r->finfo.size, &nbytes);
>        }
>
>
>
>
>   1.66      +1 -1      httpd-2.0/modules/generators/mod_autoindex.c
>
>   Index: mod_autoindex.c
>   ===================================================================
>   RCS file: /home/cvs/httpd-2.0/modules/generators/mod_autoindex.c,v
>   retrieving revision 1.65
>   retrieving revision 1.66
>   diff -u -r1.65 -r1.66
>   --- mod_autoindex.c 2001/07/07 16:21:53 1.65
>   +++ mod_autoindex.c 2001/07/24 20:38:01 1.66
>   @@ -703,7 +703,7 @@
>        char *icon;
>        char *alt;
>        char *desc;
>   -    off_t size;
>   +    apr_off_t size;
>        apr_time_t lm;
>        struct ent *next;
>        int ascending, version_sort;
>
>
>
>   1.332     +2 -2      httpd-2.0/modules/http/http_protocol.c
>
>   Index: http_protocol.c
>   ===================================================================
>   RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
>   retrieving revision 1.331
>   retrieving revision 1.332
>   diff -u -r1.331 -r1.332
>   --- http_protocol.c 2001/07/24 17:24:05 1.331
>   +++ http_protocol.c 2001/07/24 20:38:01 1.332
>   @@ -883,7 +883,7 @@
>    {
>        char tmp[] = "X-Pad: avoid browser bug" CRLF;
>        char crlf[] = CRLF;
>   -    apr_ssize_t len;
>   +    apr_off_t len;
>        apr_size_t buflen;
>
>        (void) apr_brigade_length(bb, 1, &len);
>   @@ -2272,7 +2272,7 @@
>        apr_off_t range_end;
>        char *current;
>        char *bound_head;
>   -    apr_ssize_t bb_length;
>   +    apr_off_t bb_length;
>        apr_off_t clength = 0;
>        apr_status_t rv;
>        int found = 0;
>
>
>
>   1.27      +5 -1      httpd-2.0/server/core.c
>
>   Index: core.c
>   ===================================================================
>   RCS file: /home/cvs/httpd-2.0/server/core.c,v
>   retrieving revision 1.26
>   retrieving revision 1.27
>   diff -u -r1.26 -r1.27
>   --- core.c 2001/07/18 20:45:35 1.26
>   +++ core.c 2001/07/24 20:38:01 1.27
>   @@ -2494,7 +2494,7 @@
>        apr_size_t bytes_written = 0;
>        apr_status_t rv;
>        apr_size_t n = len;
>   -    apr_size_t i = 0;
>   +    int i = 0;
>
>        *nbytes = 0;
>
>   @@ -2996,6 +2996,10 @@
>        }
>
>        bb = apr_brigade_create(r->pool);
>   +    /* XXX: APR_HAS_LARGE_FILES issue; need to split into mutiple buckets,
>   +     * no greater than MAX(apr_size_t), (perhaps more granular than that
>   +     * in case the brigade code/filters attempt to read it!)
>   +     */
>        e = apr_bucket_file_create(fd, 0, r->finfo.size, r->pool);
>
>        APR_BRIGADE_INSERT_HEAD(bb, e);
>
>
>
>


Mime
View raw message