Skip to content

Commit 61645ea

Browse files
committed
let httpd handle CL/TE for non-http handlers
Submitted By: ylavic, covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1916769 13f79535-47bb-0310-9956-ffa450edef68
1 parent 2115548 commit 61645ea

File tree

8 files changed

+68
-3
lines changed

8 files changed

+68
-3
lines changed

include/util_script.h

+2
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer,
265265
*/
266266
AP_DECLARE(void) ap_args_to_table(request_rec *r, apr_table_t **table);
267267

268+
#define AP_TRUST_CGILIKE_CL_ENVVAR "ap_trust_cgilike_cl"
269+
268270
#ifdef __cplusplus
269271
}
270272
#endif

modules/aaa/mod_authnz_fcgi.c

+8
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,14 @@ static apr_status_t handle_response(const fcgi_provider_conf *conf,
570570
"parsing -> %d/%d",
571571
fn, status, r->status);
572572

573+
/* FCGI has its own body framing mechanism which we don't
574+
* match against any provided Content-Length, so let the
575+
* core determine C-L vs T-E based on what's actually sent.
576+
*/
577+
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
578+
apr_table_unset(r->headers_out, "Content-Length");
579+
apr_table_unset(r->headers_out, "Transfer-Encoding");
580+
573581
if (rspbuf) { /* caller wants to see response body,
574582
* if any
575583
*/

modules/generators/cgi_common.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "httpd.h"
2828
#include "util_filter.h"
29+
#include "util_script.h"
2930

3031
static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgi_pfn_gtv;
3132
static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgi_pfn_ps;
@@ -428,9 +429,18 @@ static int cgi_handle_response(request_rec *r, int nph, apr_bucket_brigade *bb,
428429
char sbuf[MAX_STRING_LEN];
429430
int ret;
430431

431-
if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
432-
APLOG_MODULE_INDEX)))
433-
{
432+
ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
433+
APLOG_MODULE_INDEX);
434+
435+
/* xCGI has its own body framing mechanism which we don't
436+
* match against any provided Content-Length, so let the
437+
* core determine C-L vs T-E based on what's actually sent.
438+
*/
439+
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
440+
apr_table_unset(r->headers_out, "Content-Length");
441+
apr_table_unset(r->headers_out, "Transfer-Encoding");
442+
443+
if (ret != OK) {
434444
/* In the case of a timeout reading script output, clear
435445
* the brigade to avoid a second attempt to read the
436446
* output. */

modules/http/http_filters.c

+12
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,18 @@ static APR_INLINE int check_headers(request_rec *r)
810810
struct check_header_ctx ctx;
811811
core_server_config *conf =
812812
ap_get_core_module_config(r->server->module_config);
813+
const char *val;
814+
815+
if ((val = apr_table_get(r->headers_out, "Transfer-Encoding"))) {
816+
if (apr_table_get(r->headers_out, "Content-Length")) {
817+
apr_table_unset(r->headers_out, "Content-Length");
818+
r->connection->keepalive = AP_CONN_CLOSE;
819+
}
820+
if (!ap_is_chunked(r->pool, val)) {
821+
r->connection->keepalive = AP_CONN_CLOSE;
822+
return 0;
823+
}
824+
}
813825

814826
ctx.r = r;
815827
ctx.strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);

modules/proxy/ajp_header.c

+10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "ajp_header.h"
1818
#include "ajp.h"
1919

20+
#include "util_script.h"
21+
2022
APLOG_USE_MODULE(proxy_ajp);
2123

2224
static const char *response_trans_headers[] = {
@@ -669,6 +671,14 @@ static apr_status_t ajp_unmarshal_response(ajp_msg_t *msg,
669671
}
670672
}
671673

674+
/* AJP has its own body framing mechanism which we don't
675+
* match against any provided Content-Length, so let the
676+
* core determine C-L vs T-E based on what's actually sent.
677+
*/
678+
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
679+
apr_table_unset(r->headers_out, "Content-Length");
680+
apr_table_unset(r->headers_out, "Transfer-Encoding");
681+
672682
return APR_SUCCESS;
673683
}
674684

modules/proxy/mod_proxy_fcgi.c

+9
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,15 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf,
779779

780780
status = ap_scan_script_header_err_brigade_ex(r, ob,
781781
NULL, APLOG_MODULE_INDEX);
782+
783+
/* FCGI has its own body framing mechanism which we don't
784+
* match against any provided Content-Length, so let the
785+
* core determine C-L vs T-E based on what's actually sent.
786+
*/
787+
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
788+
apr_table_unset(r->headers_out, "Content-Length");
789+
apr_table_unset(r->headers_out, "Transfer-Encoding");
790+
782791
/* suck in all the rest */
783792
if (status != OK) {
784793
apr_bucket *tmp_b;

modules/proxy/mod_proxy_scgi.c

+8
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,14 @@ static int pass_response(request_rec *r, proxy_conn_rec *conn)
390390
return status;
391391
}
392392

393+
/* SCGI has its own body framing mechanism which we don't
394+
* match against any provided Content-Length, so let the
395+
* core determine C-L vs T-E based on what's actually sent.
396+
*/
397+
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
398+
apr_table_unset(r->headers_out, "Content-Length");
399+
apr_table_unset(r->headers_out, "Transfer-Encoding");
400+
393401
conf = ap_get_module_config(r->per_dir_config, &proxy_scgi_module);
394402
if (conf->sendfile && conf->sendfile != scgi_sendfile_off) {
395403
short err = 1;

modules/proxy/mod_proxy_uwsgi.c

+6
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,12 @@ static int uwsgi_response(request_rec *r, proxy_conn_rec * backend,
404404
return HTTP_BAD_GATEWAY;
405405
}
406406

407+
/* T-E wins over C-L */
408+
if (apr_table_get(r->headers_out, "Transfer-Encoding")) {
409+
apr_table_unset(r->headers_out, "Content-Length");
410+
backend->close = 1;
411+
}
412+
407413
if ((buf = apr_table_get(r->headers_out, "Content-Type"))) {
408414
ap_set_content_type(r, apr_pstrdup(r->pool, buf));
409415
}

0 commit comments

Comments
 (0)