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 |
*/ |