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;
    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;

        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;

                /* We can't pass this EOS to the output_filters. */
                e = APR_BRIGADE_LAST(input_brigade);
                apr_bucket_delete(e);

                if (apr_table_get(r->subprocess_env, "proxy-sendextracrlf")) {
                    e = apr_bucket_immortal_create(CRLF_ASCII, 2,
                                                   bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(input_brigade, e);
                }
            }

            /* C-L < bytes streamed?!?
             * We will error out after the body is completely
             * consumed, but we can't stream more bytes at the
             * back end since they would in part be interpreted
             * as another request!  If nothing is sent, then
             * just send nothing.
             *
             * Prevents HTTP Response Splitting.
             */
            if (bytes_streamed > req->cl_val) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01086)
                              "read more bytes of request body than expected "
                              "(got %" APR_OFF_T_FMT ", expected "
                              "%" APR_OFF_T_FMT ")",
                              bytes_streamed, req->cl_val);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }

        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;
        }

        /* Once we hit EOS, we are ready to flush. */
        rv = ap_proxy_pass_brigade(bucket_alloc, r, p_conn, req->origin,
                                   input_brigade, flush || 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);
        }
    }

    if (bytes_streamed != req->cl_val) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01087)
                      "client %s given Content-Length did not match"
                      " number of body bytes read", r->connection->client_ip);
        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;
}