OK, thanks Stefan, will look at it.

On Tue, Feb 12, 2019 at 11:12 AM ste...@eissing.org <ste...@eissing.org> wrote:
>
> Yann,
>
> this works fine in my tests on trunk. However on 2.4.x I get often errors 
> when uploading data without content-length.
>
> Scenario from the h2 test suite, HTTP/2 on the front, old skool HTTP/1.1 
> proxy to itself:
>
> >  while true; do nghttp -v --expect-continue --data=gen/tmp/updata 
> > -H'Content-Type: multipart/form-data; boundary=DSAJKcd9876' 
> > --no-content-length http://test.example.org:12345/proxy/upload.py; done | 
> > fgrep 400
>
> [  0.009] recv (stream_id=13) :status: 400
> <title>400 Bad Request</title>
> [  0.007] recv (stream_id=13) :status: 400
> <title>400 Bad Request</title>
> ...
>
>
> /etc/hosts
>
> 127.0.0.1       test.example.org        test
>
> httpd config:
>
>     ProxyPass "/proxy" "balancer://http-local"
>     ProxyPassReverse "/proxy" "balancer://http-local"
>
>     <Proxy "balancer://http-local">
>         BalancerMember "http://127.0.0.1:12345"; hcmethod=GET hcuri=/ ttl=4
>     </Proxy>
>
>
> > cat gen/tmp/updata
> --DSAJKcd9876
> Content-Disposition: form-data; name="xxx"; filename="xxxxx"
> Content-Type: text/plain
>
> testing mod_h2
> --DSAJKcd9876
> Content-Disposition: form-data; name="file"; filename="data-1k"
> Content-Type: application/octet-stream
> Content-Transfer-Encoding: binary
>
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
> 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
>
> --DSAJKcd9876--
>
>
>
> > Am 11.02.2019 um 22:55 schrieb yla...@apache.org:
> >
> > Author: ylavic
> > Date: Mon Feb 11 21:55:43 2019
> > New Revision: 1853407
> >
> > URL: http://svn.apache.org/viewvc?rev=1853407&view=rev
> > Log:
> > mod_proxy_http: rework the flushing strategy when forwarding the request 
> > body.
> >
> > Since the forwarding of 100-continue (end to end) in r1836588, we depended 
> > on
> > reading all of the requested HUGE_STRING_LEN bytes to avoid the flushes, but
> > this is a bit fragile.
> >
> > This commit introduces the new stream_reqbody_read() function which will 
> > try a
> > nonblocking read first and, if it fails with EAGAIN, will flush on the 
> > backend
> > side before blocking for the next client side read.
> >
> > We can then use it in stream_reqbody_{chunked,cl}() to flush client 
> > forwarded
> > data only when necessary. This both allows "optimal" flushing and simplifies
> > code (note that spool_reqbody_cl() also makes use of the new function but 
> > not
> > its nonblocking/flush functionality, thus only for consistency with the two
> > others, simplification and common error handling).
> >
> > Also, since proxy_http_req_t::flushall/subprocess_env::proxy-flushall are 
> > now
> > meaningless (and unused) on the backend side, they are renamed respectively 
> > to
> > prefetch_nonblocking/proxy-prefetch-nonblocking, and solely determine 
> > whether
> > to prefetch in nonblocking mode or not. These flags were trunk only and may
> > not be really useful if we decided to prefetch in nonblocking mode in any 
> > case,
> > but for 2.4.x the opt-in looks wise.
> >
> > Modified:
> >    httpd/httpd/trunk/modules/http2/mod_proxy_http2.c
> >    httpd/httpd/trunk/modules/proxy/mod_proxy_http.c
> >
> > Modified: httpd/httpd/trunk/modules/http2/mod_proxy_http2.c
> > URL: 
> > http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/mod_proxy_http2.c?rev=1853407&r1=1853406&r2=1853407&view=diff
> > ==============================================================================
> > --- httpd/httpd/trunk/modules/http2/mod_proxy_http2.c (original)
> > +++ httpd/httpd/trunk/modules/http2/mod_proxy_http2.c Mon Feb 11 21:55:43 
> > 2019
> > @@ -77,7 +77,6 @@ typedef struct h2_proxy_ctx {
> >
> >     unsigned standalone : 1;
> >     unsigned is_ssl : 1;
> > -    unsigned flushall : 1;
> >
> >     apr_status_t r_status;     /* status of our first request work */
> >     h2_proxy_session *session; /* current http2 session against backend */
> > @@ -509,7 +508,6 @@ static int proxy_http2_handler(request_r
> >     ctx->is_ssl     = is_ssl;
> >     ctx->worker     = worker;
> >     ctx->conf       = conf;
> > -    ctx->flushall   = apr_table_get(r->subprocess_env, "proxy-flushall")? 
> > 1 : 0;
> >     ctx->r_status   = HTTP_SERVICE_UNAVAILABLE;
> >
> >     h2_proxy_fifo_set_create(&ctx->requests, ctx->pool, 100);
> >
> > Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_http.c
> > URL: 
> > http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy_http.c?rev=1853407&r1=1853406&r2=1853407&view=diff
> > ==============================================================================
> > --- httpd/httpd/trunk/modules/proxy/mod_proxy_http.c (original)
> > +++ httpd/httpd/trunk/modules/proxy/mod_proxy_http.c Mon Feb 11 21:55:43 
> > 2019
> > @@ -250,34 +250,80 @@ typedef struct {
> >     apr_bucket_brigade *header_brigade;
> >     apr_bucket_brigade *input_brigade;
> >     char *old_cl_val, *old_te_val;
> > -    apr_off_t cl_val, bytes_spooled;
> > +    apr_off_t cl_val;
> >
> >     rb_methods rb_method;
> >
> >     int expecting_100;
> >     unsigned int do_100_continue:1,
> > -                 flushall:1;
> > +                 prefetch_nonblocking:1;
> > } proxy_http_req_t;
> >
> > +/* Read what's in the client pipe. If nonblocking is set and read is 
> > EAGAIN,
> > + * pass a FLUSH bucket to the backend and read again in blocking mode.
> > + */
> > +static int stream_reqbody_read(proxy_http_req_t *req, apr_bucket_brigade 
> > *bb,
> > +                               int nonblocking)
> > +{
> > +    request_rec *r = req->r;
> > +    proxy_conn_rec *p_conn = req->backend;
> > +    apr_bucket_alloc_t *bucket_alloc = req->bucket_alloc;
> > +    apr_read_type_e block = nonblocking ? APR_NONBLOCK_READ : 
> > APR_BLOCK_READ;
> > +    apr_status_t status;
> > +    int rv;
> > +
> > +    for (;;) {
> > +        status = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
> > +                                block, HUGE_STRING_LEN);
> > +        if (block == APR_BLOCK_READ
> > +                || (!APR_STATUS_IS_EAGAIN(status)
> > +                    && (status != APR_SUCCESS || !APR_BRIGADE_EMPTY(bb)))) 
> > {
> > +            break;
> > +        }
> > +
> > +        /* Flush and retry (blocking) */
> > +        apr_brigade_cleanup(bb);
> > +        rv = ap_proxy_pass_brigade(bucket_alloc, r, p_conn, req->origin, 
> > bb, 1);
> > +        if (rv != OK) {
> > +            return rv;
> > +        }
> > +        block = APR_BLOCK_READ;
> > +    }
> > +
> > +    if (status != APR_SUCCESS) {
> > +        conn_rec *c = r->connection;
> > +        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02608)
> > +                      "read request body failed to %pI (%s)"
> > +                      " from %s (%s)", p_conn->addr,
> > +                      p_conn->hostname ? p_conn->hostname: "",
> > +                      c->client_ip, c->remote_host ? c->remote_host: "");
> > +        return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
> > +    }
> > +
> > +    return OK;
> > +}
> > +
> > static int stream_reqbody_chunked(proxy_http_req_t *req)
> > {
> >     request_rec *r = req->r;
> >     int seen_eos = 0, rv = OK;
> >     apr_size_t hdr_len;
> >     apr_off_t bytes;
> > -    apr_status_t status;
> >     char chunk_hdr[20];  /* must be here due to transient bucket. */
> >     proxy_conn_rec *p_conn = req->backend;
> >     apr_bucket_alloc_t *bucket_alloc = req->bucket_alloc;
> >     apr_bucket_brigade *header_brigade = req->header_brigade;
> >     apr_bucket_brigade *input_brigade = req->input_brigade;
> > -    apr_bucket_brigade *bb;
> >     apr_bucket *e;
> >
> > -    while (APR_BRIGADE_EMPTY(input_brigade)
> > -           || !APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade)))
> > -    {
> > -        int flush = req->flushall;
> > +    do {
> > +        if (APR_BRIGADE_EMPTY(input_brigade)
> > +                && APR_BRIGADE_EMPTY(header_brigade)) {
> > +            rv = stream_reqbody_read(req, input_brigade, 1);
> > +            if (rv != OK) {
> > +                return rv;
> > +            }
> > +        }
> >
> >         if (!APR_BRIGADE_EMPTY(input_brigade)) {
> >             /* If this brigade contains EOS, either stop or remove it. */
> > @@ -290,12 +336,6 @@ static int stream_reqbody_chunked(proxy_
> >             }
> >
> >             apr_brigade_length(input_brigade, 1, &bytes);
> > -
> > -            /* Flush only if we did not get the requested #bytes. */
> > -            if (bytes < HUGE_STRING_LEN) {
> > -                flush = 0;
> > -            }
> > -
> >             hdr_len = apr_snprintf(chunk_hdr, sizeof(chunk_hdr),
> >                                    "%" APR_UINT64_T_HEX_FMT CRLF,
> >                                    (apr_uint64_t)bytes);
> > @@ -312,108 +352,62 @@ static int stream_reqbody_chunked(proxy_
> >             APR_BRIGADE_INSERT_TAIL(input_brigade, e);
> >         }
> >
> > -        if (!APR_BRIGADE_EMPTY(header_brigade)) {
> > -            /* we never sent the header brigade, so go ahead and
> > -             * take care of that now
> > -             */
> > -            bb = header_brigade;
> > -            APR_BRIGADE_CONCAT(bb, input_brigade);
> > -
> > -            /* Flush now since we have the header and (enough of) the
> > -             * prefeched body, or racing KeepAliveTimeout on the backend
> > -             * side may kill our connection while we read more client data.
> > -             */
> > -            flush = 1;
> > -        }
> > -        else {
> > -            bb = input_brigade;
> > -        }
> > +        /* If we never sent the header brigade, so go ahead and
> > +         * take care of that now by prepending it.
> > +         */
> > +        APR_BRIGADE_PREPEND(input_brigade, header_brigade);
> >
> > -        /* Once we hit EOS, flush below this loop with the EOS chunk. */
> > +        /* No flush here since it's done either on the next loop depending
> > +         * on stream_reqbody_read(), or after the loop with the EOS chunk.
> > +         */
> >         rv = ap_proxy_pass_brigade(bucket_alloc, r, p_conn, req->origin,
> > -                                   bb, flush && !seen_eos);
> > +                                   input_brigade, 0);
> >         if (rv != OK) {
> >             return rv;
> >         }
> > -
> > -        if (seen_eos) {
> > -            break;
> > -        }
> > -
> > -        status = ap_get_brigade(r->input_filters, input_brigade,
> > -                                AP_MODE_READBYTES, APR_BLOCK_READ,
> > -                                HUGE_STRING_LEN);
> > -
> > -        if (status != APR_SUCCESS) {
> > -            conn_rec *c = r->connection;
> > -            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02608)
> > -                          "read request body failed to %pI (%s)"
> > -                          " from %s (%s)", p_conn->addr,
> > -                          p_conn->hostname ? p_conn->hostname: "",
> > -                          c->client_ip, c->remote_host ? c->remote_host: 
> > "");
> > -            return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
> > -        }
> > -    }
> > -
> > -    if (!APR_BRIGADE_EMPTY(header_brigade)) {
> > -        /* we never sent the header brigade because there was no request 
> > body;
> > -         * send it now
> > -         */
> > -        bb = header_brigade;
> > -    }
> > -    else {
> > -        if (!APR_BRIGADE_EMPTY(input_brigade)) {
> > -            /* input brigade still has an EOS which we can't pass to the 
> > output_filters. */
> > -            e = APR_BRIGADE_LAST(input_brigade);
> > -            AP_DEBUG_ASSERT(APR_BUCKET_IS_EOS(e));
> > -            apr_bucket_delete(e);
> > -        }
> > -        bb = input_brigade;
> > -    }
> > +    } while (!seen_eos);
> >
> >     e = apr_bucket_immortal_create(ZERO_ASCII CRLF_ASCII
> >                                    /* <trailers> */
> >                                    CRLF_ASCII,
> >                                    5, bucket_alloc);
> > -    APR_BRIGADE_INSERT_TAIL(bb, e);
> > +    APR_BRIGADE_INSERT_TAIL(input_brigade, e);
> >
> >     if (apr_table_get(r->subprocess_env, "proxy-sendextracrlf")) {
> >         e = apr_bucket_immortal_create(CRLF_ASCII, 2, bucket_alloc);
> > -        APR_BRIGADE_INSERT_TAIL(bb, e);
> > +        APR_BRIGADE_INSERT_TAIL(input_brigade, e);
> >     }
> >
> >     /* Now we have headers-only, or the chunk EOS mark; flush it */
> > -    return ap_proxy_pass_brigade(bucket_alloc, r, p_conn, req->origin, bb, 
> > 1);
> > +    return ap_proxy_pass_brigade(bucket_alloc, r, p_conn, req->origin,
> > +                                 input_brigade, 1);
> > }
> >
> > static int stream_reqbody_cl(proxy_http_req_t *req)
> > {
> >     request_rec *r = req->r;
> > -    int seen_eos = 0, rv = 0;
> > -    apr_status_t status = APR_SUCCESS;
> > +    int seen_eos = 0, rv = OK;
> >     proxy_conn_rec *p_conn = req->backend;
> >     apr_bucket_alloc_t *bucket_alloc = req->bucket_alloc;
> >     apr_bucket_brigade *header_brigade = req->header_brigade;
> >     apr_bucket_brigade *input_brigade = req->input_brigade;
> > -    apr_bucket_brigade *bb;
> >     apr_bucket *e;
> >     apr_off_t bytes;
> >     apr_off_t bytes_streamed = 0;
> >
> > -    while (APR_BRIGADE_EMPTY(input_brigade)
> > -           || !APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade)))
> > -    {
> > -        int flush = req->flushall;
> > +    do {
> > +        if (APR_BRIGADE_EMPTY(input_brigade)
> > +                && APR_BRIGADE_EMPTY(header_brigade)) {
> > +            rv = stream_reqbody_read(req, input_brigade, 1);
> > +            if (rv != OK) {
> > +                return rv;
> > +            }
> > +        }
> >
> >         if (!APR_BRIGADE_EMPTY(input_brigade)) {
> >             apr_brigade_length(input_brigade, 1, &bytes);
> >             bytes_streamed += bytes;
> >
> > -            /* Flush only if we did not get the requested #bytes. */
> > -            if (bytes < HUGE_STRING_LEN) {
> > -                flush = 0;
> > -            }
> > -
> >             /* If this brigade contains EOS, either stop or remove it. */
> >             if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
> >                 seen_eos = 1;
> > @@ -448,48 +442,18 @@ static int stream_reqbody_cl(proxy_http_
> >             }
> >         }
> >
> > -        if (!APR_BRIGADE_EMPTY(header_brigade)) {
> > -            /* we never sent the header brigade, so go ahead and
> > -             * take care of that now
> > -             */
> > -            bb = header_brigade;
> > -            APR_BRIGADE_CONCAT(bb, input_brigade);
> > -
> > -            /* Flush now since we have the header and (enough of) the
> > -             * prefeched body, or racing KeepAliveTimeout on the backend
> > -             * side may kill our connection while we read more client data.
> > -             */
> > -            flush = 1;
> > -        }
> > -        else {
> > -            bb = input_brigade;
> > -        }
> > +        /* If we never sent the header brigade, so go ahead and
> > +         * take care of that now by prepending it.
> > +         */
> > +        APR_BRIGADE_PREPEND(input_brigade, header_brigade);
> >
> > -        /* Once we hit EOS, we are ready to flush. */
> > +        /* Flush here on EOS because we won't stream_reqbody_read() again 
> > */
> >         rv = ap_proxy_pass_brigade(bucket_alloc, r, p_conn, req->origin,
> > -                                   input_brigade, flush || seen_eos);
> > +                                   input_brigade, seen_eos);
> >         if (rv != OK) {
> >             return rv;
> >         }
> > -
> > -        if (seen_eos) {
> > -            break;
> > -        }
> > -
> > -        status = ap_get_brigade(r->input_filters, input_brigade,
> > -                                AP_MODE_READBYTES, APR_BLOCK_READ,
> > -                                HUGE_STRING_LEN);
> > -
> > -        if (status != APR_SUCCESS) {
> > -            conn_rec *c = r->connection;
> > -            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02609)
> > -                          "read request body failed to %pI (%s)"
> > -                          " from %s (%s)", p_conn->addr,
> > -                          p_conn->hostname ? p_conn->hostname: "",
> > -                          c->client_ip, c->remote_host ? c->remote_host: 
> > "");
> > -            return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
> > -        }
> > -    }
> > +    } while (!seen_eos);
> >
> >     if (bytes_streamed != req->cl_val) {
> >         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01087)
> > @@ -498,22 +462,14 @@ static int stream_reqbody_cl(proxy_http_
> >         return HTTP_BAD_REQUEST;
> >     }
> >
> > -    if (!APR_BRIGADE_EMPTY(header_brigade)) {
> > -        /* we never sent the header brigade since there was no request
> > -         * body; send it now with the flush flag
> > -         */
> > -        return ap_proxy_pass_brigade(bucket_alloc, r, p_conn, req->origin,
> > -                                     header_brigade, 1);
> > -    }
> > -
> >     return OK;
> > }
> >
> > -static int spool_reqbody_cl(proxy_http_req_t *req)
> > +static int spool_reqbody_cl(proxy_http_req_t *req, apr_off_t 
> > *bytes_spooled)
> > {
> >     apr_pool_t *p = req->p;
> >     request_rec *r = req->r;
> > -    int seen_eos = 0;
> > +    int seen_eos = 0, rv = OK;
> >     apr_status_t status = APR_SUCCESS;
> >     apr_bucket_alloc_t *bucket_alloc = req->bucket_alloc;
> >     apr_bucket_brigade *input_brigade = req->input_brigade;
> > @@ -524,17 +480,18 @@ static int spool_reqbody_cl(proxy_http_r
> >     apr_off_t limit;
> >
> >     body_brigade = apr_brigade_create(p, bucket_alloc);
> > +    *bytes_spooled = 0;
> >
> >     limit = ap_get_limit_req_body(r);
> >
> > -    if (APR_BRIGADE_EMPTY(input_brigade)) {
> > -        status = ap_get_brigade(r->input_filters, input_brigade,
> > -                                AP_MODE_READBYTES, APR_BLOCK_READ,
> > -                                HUGE_STRING_LEN);
> > -    }
> > -    while (status == APR_SUCCESS
> > -           && !APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade)))
> > -    {
> > +    do {
> > +        if (APR_BRIGADE_EMPTY(input_brigade)) {
> > +            rv = stream_reqbody_read(req, input_brigade, 0);
> > +            if (rv != OK) {
> > +                return rv;
> > +            }
> > +        }
> > +
> >         /* If this brigade contains EOS, either stop or remove it. */
> >         if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
> >             seen_eos = 1;
> > @@ -546,13 +503,13 @@ static int spool_reqbody_cl(proxy_http_r
> >
> >         apr_brigade_length(input_brigade, 1, &bytes);
> >
> > -        if (req->bytes_spooled + bytes > MAX_MEM_SPOOL) {
> > +        if (*bytes_spooled + bytes > MAX_MEM_SPOOL) {
> >             /*
> >              * LimitRequestBody does not affect Proxy requests (Should it?).
> >              * Let it take effect if we decide to store the body in a
> >              * temporary file on disk.
> >              */
> > -            if (limit && (req->bytes_spooled + bytes > limit)) {
> > +            if (limit && (*bytes_spooled + bytes > limit)) {
> >                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01088)
> >                               "Request body is larger than the configured "
> >                               "limit of %" APR_OFF_T_FMT, limit);
> > @@ -622,23 +579,8 @@ static int spool_reqbody_cl(proxy_http_r
> >
> >         }
> >
> > -        req->bytes_spooled += bytes;
> > -
> > -        if (seen_eos) {
> > -            break;
> > -        }
> > -
> > -        status = ap_get_brigade(r->input_filters, input_brigade,
> > -                                AP_MODE_READBYTES, APR_BLOCK_READ,
> > -                                HUGE_STRING_LEN);
> > -    }
> > -    if (status != APR_SUCCESS) {
> > -        conn_rec *c = r->connection;
> > -        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02610)
> > -                      "read request body failed from %s (%s)",
> > -                      c->client_ip, c->remote_host ? c->remote_host: "");
> > -        return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
> > -    }
> > +        *bytes_spooled += bytes;
> > +    } while (!seen_eos);
> >
> >     APR_BRIGADE_CONCAT(input_brigade, body_brigade);
> >     if (tmpfile) {
> > @@ -740,7 +682,7 @@ static int ap_proxy_http_prefetch(proxy_
> >      * reasonable size.
> >      */
> >     temp_brigade = apr_brigade_create(p, bucket_alloc);
> > -    block = req->flushall ? APR_NONBLOCK_READ : APR_BLOCK_READ;
> > +    block = req->prefetch_nonblocking ? APR_NONBLOCK_READ : APR_BLOCK_READ;
> >     do {
> >         status = ap_get_brigade(r->input_filters, temp_brigade,
> >                                 AP_MODE_READBYTES, block,
> > @@ -791,7 +733,7 @@ static int ap_proxy_http_prefetch(proxy_
> >      */
> >     } while ((bytes_read < MAX_MEM_SPOOL - 80)
> >               && !APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))
> > -              && !req->flushall);
> > +              && !req->prefetch_nonblocking);
> >
> >     /* Use chunked request body encoding or send a content-length body?
> >      *
> > @@ -899,16 +841,12 @@ static int ap_proxy_http_prefetch(proxy_
> >         /* If we have to spool the body, do it now, before connecting or
> >          * reusing the backend connection.
> >          */
> > -        rv = spool_reqbody_cl(req);
> > +        rv = spool_reqbody_cl(req, &bytes);
> >         if (rv != OK) {
> >             return rv;
> >         }
> > -        if (bytes_read > 0
> > -                || req->old_te_val
> > -                || req->old_cl_val
> > -                || req->bytes_spooled) {
> > -            add_cl(p, bucket_alloc, header_brigade,
> > -                   apr_off_t_toa(p, req->bytes_spooled));
> > +        if (bytes || req->old_te_val || req->old_cl_val) {
> > +            add_cl(p, bucket_alloc, header_brigade, apr_off_t_toa(p, 
> > bytes));
> >         }
> >     }
> >
> > @@ -2138,15 +2076,15 @@ static int proxy_http_handler(request_re
> >          * req->expecting_100 (i.e. cleared only if mod_proxy_http sent the
> >          * "100 Continue" according to its policy).
> >          */
> > -        req->do_100_continue = req->flushall = 1;
> > +        req->do_100_continue = req->prefetch_nonblocking = 1;
> >         req->expecting_100 = r->expecting_100;
> >         r->expecting_100 = 0;
> >     }
> >     /* Should we block while prefetching the body or try nonblocking and 
> > flush
> >      * data to the backend ASAP?
> >      */
> > -    else if (apr_table_get(r->subprocess_env, "proxy-flushall")) {
> > -        req->flushall = 1;
> > +    else if (apr_table_get(r->subprocess_env, 
> > "proxy-prefetch-nonblocking")) {
> > +        req->prefetch_nonblocking = 1;
> >     }
> >
> >     /*
> >
> >
>

Reply via email to