View | Details | Raw Unified | Return to bug 60330
Collapse All | Expand All

(-)modules/proxy/mod_proxy_http.c (-4 / +58 lines)
Lines 366-372 Link Here
366
                                      conn_rec *origin,
366
                                      conn_rec *origin,
367
                                      apr_bucket_brigade *header_brigade,
367
                                      apr_bucket_brigade *header_brigade,
368
                                      apr_bucket_brigade *input_brigade,
368
                                      apr_bucket_brigade *input_brigade,
369
                                      char *old_cl_val)
369
                                      const char *old_cl_val)
370
{
370
{
371
    int seen_eos = 0, rv = 0;
371
    int seen_eos = 0, rv = 0;
372
    apr_status_t status = APR_SUCCESS;
372
    apr_status_t status = APR_SUCCESS;
Lines 380-386 Link Here
380
    if (old_cl_val) {
380
    if (old_cl_val) {
381
        char *endstr;
381
        char *endstr;
382
382
383
        add_cl(p, bucket_alloc, header_brigade, old_cl_val);
383
        if (header_brigade) {
384
            add_cl(p, bucket_alloc, header_brigade, old_cl_val);
385
        }
384
        status = apr_strtoff(&cl_val, old_cl_val, &endstr, 10);
386
        status = apr_strtoff(&cl_val, old_cl_val, &endstr, 10);
385
387
386
        if (status || *endstr || endstr == old_cl_val || cl_val < 0) {
388
        if (status || *endstr || endstr == old_cl_val || cl_val < 0) {
Lines 390-396 Link Here
390
            return HTTP_BAD_REQUEST;
392
            return HTTP_BAD_REQUEST;
391
        }
393
        }
392
    }
394
    }
393
    terminate_headers(bucket_alloc, header_brigade);
395
    if (header_brigade) {
396
        terminate_headers(bucket_alloc, header_brigade);
397
    }
394
398
395
    while (!APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade)))
399
    while (!APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade)))
396
    {
400
    {
Lines 479-485 Link Here
479
        }
483
        }
480
    }
484
    }
481
485
482
    if (bytes_streamed != cl_val) {
486
    /* Do not fail if body was not read because request has expects 100-continue */
487
    if (bytes_streamed != cl_val &&
488
            !(r->expecting_100 && (r->proxyreq == PROXYREQ_REVERSE)) ) {
483
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01087)
489
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01087)
484
                      "client %s given Content-Length did not match"
490
                      "client %s given Content-Length did not match"
485
                      " number of body bytes read", r->connection->client_ip);
491
                      " number of body bytes read", r->connection->client_ip);
Lines 708-713 Link Here
708
        goto skip_body;
714
        goto skip_body;
709
    }
715
    }
710
716
717
    /*
718
     * A request with expects 100-continue should not
719
     * read the request body. The Content-Length header should
720
     * be part of the request.
721
     */
722
    if (r->expecting_100 && (r->proxyreq == PROXYREQ_REVERSE)) {
723
        rb_method = RB_STREAM_CL;
724
        e = apr_bucket_eos_create(input_brigade->bucket_alloc);
725
        APR_BRIGADE_INSERT_TAIL(input_brigade, e);
726
        goto skip_body;
727
    }
728
711
    /* WE only understand chunked.  Other modules might inject
729
    /* WE only understand chunked.  Other modules might inject
712
     * (and therefore, decode) other flavors but we don't know
730
     * (and therefore, decode) other flavors but we don't know
713
     * that the can and have done so unless they remove
731
     * that the can and have done so unless they remove
Lines 1209-1214 Link Here
1209
    apr_interval_time_t old_timeout = 0;
1227
    apr_interval_time_t old_timeout = 0;
1210
    proxy_dir_conf *dconf;
1228
    proxy_dir_conf *dconf;
1211
    int do_100_continue;
1229
    int do_100_continue;
1230
    apr_status_t status;
1231
    apr_bucket_alloc_t *bucket_alloc = c->bucket_alloc;
1232
    apr_bucket_brigade *input_brigade;
1233
    apr_off_t bytes_read = 0;
1234
    proxy_conn_rec *p_conn = backend;
1235
    const char* old_cl_val = NULL;
1236
    int rv = 0;
1212
1237
1213
    dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
1238
    dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
1214
1239
Lines 1537-1543 Link Here
1537
            if (!policy
1562
            if (!policy
1538
                    || (!strcasecmp(policy, "RFC") && ((r->expecting_100 = 1)))) {
1563
                    || (!strcasecmp(policy, "RFC") && ((r->expecting_100 = 1)))) {
1539
                ap_send_interim_response(r, 1);
1564
                ap_send_interim_response(r, 1);
1565
                /* Reading request body was skipped in ap_proxy_http_request
1566
                 * stream it now that 100-continue was sent from backend to client.
1567
                 */
1568
                input_brigade = apr_brigade_create(p, bucket_alloc);
1569
                status = ap_get_brigade(r->input_filters, input_brigade,
1570
                        AP_MODE_READBYTES, APR_BLOCK_READ,
1571
                        MAX_MEM_SPOOL - bytes_read);
1572
                if (status != APR_SUCCESS) {
1573
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01095)
1574
                                  "prefetch request body failed to %pI (%s)"
1575
                                  " from %s (%s)",
1576
                                  p_conn->addr, p_conn->hostname ? p_conn->hostname: "",
1577
                                  c->client_ip, c->remote_host ? c->remote_host: "");
1578
                    return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
1540
            }
1579
            }
1580
1581
            old_cl_val = apr_table_get(r->headers_in,"Content-Length");
1582
            if (NULL==old_cl_val) {
1583
                    return HTTP_INTERNAL_SERVER_ERROR;
1584
            }
1585
            rv = stream_reqbody_cl(p, r, p_conn, origin, NULL,
1586
                    input_brigade, old_cl_val);
1587
            if (rv != OK) {
1588
                /* apr_status_t value has been logged in lower level method */
1589
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01097)
1590
                              "pass request body failed to %pI (%s) from %s (%s)",
1591
                              p_conn->addr, p_conn->hostname ? p_conn->hostname: "",
1592
                              c->client_ip, c->remote_host ? c->remote_host: "");
1593
                    }
1594
            }
1541
            /* FIXME: refine this to be able to specify per-response-status
1595
            /* FIXME: refine this to be able to specify per-response-status
1542
             * policies and maybe also add option to bail out with 502
1596
             * policies and maybe also add option to bail out with 502
1543
             */
1597
             */

Return to bug 60330