Skip to content

Commit

Permalink
let httpd handle CL/TE for non-http handlers
Browse files Browse the repository at this point in the history
backport r1916769 from trunk:
Submitted By: ylavic, covener



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1916777 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
covener committed Apr 3, 2024
1 parent ee86d1d commit a29723c
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 6 deletions.
2 changes: 2 additions & 0 deletions include/util_script.h
Expand Up @@ -225,6 +225,8 @@ AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer,
*/
AP_DECLARE(void) ap_args_to_table(request_rec *r, apr_table_t **table);

#define AP_TRUST_CGILIKE_CL_ENVVAR "ap_trust_cgilike_cl"

#ifdef __cplusplus
}
#endif
Expand Down
8 changes: 8 additions & 0 deletions modules/aaa/mod_authnz_fcgi.c
Expand Up @@ -571,6 +571,14 @@ static apr_status_t handle_response(const fcgi_provider_conf *conf,
"parsing -> %d/%d",
fn, status, r->status);

/* FCGI has its own body framing mechanism which we don't
* match against any provided Content-Length, so let the
* core determine C-L vs T-E based on what's actually sent.
*/
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
apr_table_unset(r->headers_out, "Content-Length");
apr_table_unset(r->headers_out, "Transfer-Encoding");

if (rspbuf) { /* caller wants to see response body,
* if any
*/
Expand Down
15 changes: 12 additions & 3 deletions modules/generators/mod_cgi.c
Expand Up @@ -967,9 +967,18 @@ static int cgi_handler(request_rec *r)
char sbuf[MAX_STRING_LEN];
int ret;

if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
APLOG_MODULE_INDEX)))
{
ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
APLOG_MODULE_INDEX);

/* xCGI has its own body framing mechanism which we don't
* match against any provided Content-Length, so let the
* core determine C-L vs T-E based on what's actually sent.
*/
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
apr_table_unset(r->headers_out, "Content-Length");
apr_table_unset(r->headers_out, "Transfer-Encoding");

if (ret != OK) {
ret = log_script(r, conf, ret, dbuf, sbuf, bb, script_err);

/*
Expand Down
15 changes: 12 additions & 3 deletions modules/generators/mod_cgid.c
Expand Up @@ -1616,9 +1616,18 @@ static int cgid_handler(request_rec *r)
b = apr_bucket_eos_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);

if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
APLOG_MODULE_INDEX)))
{
ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
APLOG_MODULE_INDEX);

/* xCGI has its own body framing mechanism which we don't
* match against any provided Content-Length, so let the
* core determine C-L vs T-E based on what's actually sent.
*/
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
apr_table_unset(r->headers_out, "Content-Length");
apr_table_unset(r->headers_out, "Transfer-Encoding");

if (ret != OK) {
ret = log_script(r, conf, ret, dbuf, sbuf, bb, NULL);

/*
Expand Down
12 changes: 12 additions & 0 deletions modules/http/http_filters.c
Expand Up @@ -778,6 +778,18 @@ static APR_INLINE int check_headers(request_rec *r)
struct check_header_ctx ctx;
core_server_config *conf =
ap_get_core_module_config(r->server->module_config);
const char *val;

if ((val = apr_table_get(r->headers_out, "Transfer-Encoding"))) {
if (apr_table_get(r->headers_out, "Content-Length")) {
apr_table_unset(r->headers_out, "Content-Length");
r->connection->keepalive = AP_CONN_CLOSE;
}
if (!ap_is_chunked(r->pool, val)) {
r->connection->keepalive = AP_CONN_CLOSE;
return 0;
}
}

ctx.r = r;
ctx.strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
Expand Down
10 changes: 10 additions & 0 deletions modules/proxy/ajp_header.c
Expand Up @@ -17,6 +17,8 @@
#include "ajp_header.h"
#include "ajp.h"

#include "util_script.h"

APLOG_USE_MODULE(proxy_ajp);

static const char *response_trans_headers[] = {
Expand Down Expand Up @@ -669,6 +671,14 @@ static apr_status_t ajp_unmarshal_response(ajp_msg_t *msg,
}
}

/* AJP has its own body framing mechanism which we don't
* match against any provided Content-Length, so let the
* core determine C-L vs T-E based on what's actually sent.
*/
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
apr_table_unset(r->headers_out, "Content-Length");
apr_table_unset(r->headers_out, "Transfer-Encoding");

return APR_SUCCESS;
}

Expand Down
9 changes: 9 additions & 0 deletions modules/proxy/mod_proxy_fcgi.c
Expand Up @@ -779,6 +779,15 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf,

status = ap_scan_script_header_err_brigade_ex(r, ob,
NULL, APLOG_MODULE_INDEX);

/* FCGI has its own body framing mechanism which we don't
* match against any provided Content-Length, so let the
* core determine C-L vs T-E based on what's actually sent.
*/
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
apr_table_unset(r->headers_out, "Content-Length");
apr_table_unset(r->headers_out, "Transfer-Encoding");

/* suck in all the rest */
if (status != OK) {
apr_bucket *tmp_b;
Expand Down
8 changes: 8 additions & 0 deletions modules/proxy/mod_proxy_scgi.c
Expand Up @@ -390,6 +390,14 @@ static int pass_response(request_rec *r, proxy_conn_rec *conn)
return status;
}

/* SCGI has its own body framing mechanism which we don't
* match against any provided Content-Length, so let the
* core determine C-L vs T-E based on what's actually sent.
*/
if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
apr_table_unset(r->headers_out, "Content-Length");
apr_table_unset(r->headers_out, "Transfer-Encoding");

conf = ap_get_module_config(r->per_dir_config, &proxy_scgi_module);
if (conf->sendfile && conf->sendfile != scgi_sendfile_off) {
short err = 1;
Expand Down
6 changes: 6 additions & 0 deletions modules/proxy/mod_proxy_uwsgi.c
Expand Up @@ -404,6 +404,12 @@ static int uwsgi_response(request_rec *r, proxy_conn_rec * backend,
return HTTP_BAD_GATEWAY;
}

/* T-E wins over C-L */
if (apr_table_get(r->headers_out, "Transfer-Encoding")) {
apr_table_unset(r->headers_out, "Content-Length");
backend->close = 1;
}

if ((buf = apr_table_get(r->headers_out, "Content-Type"))) {
ap_set_content_type(r, apr_pstrdup(r->pool, buf));
}
Expand Down

0 comments on commit a29723c

Please sign in to comment.