]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
let httpd handle CL/TE for non-http handlers
authorEric Covener <covener@apache.org>
Wed, 3 Apr 2024 12:10:49 +0000 (12:10 +0000)
committerEric Covener <covener@apache.org>
Wed, 3 Apr 2024 12:10:49 +0000 (12:10 +0000)
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

include/util_script.h
modules/aaa/mod_authnz_fcgi.c
modules/generators/mod_cgi.c
modules/generators/mod_cgid.c
modules/http/http_filters.c
modules/proxy/ajp_header.c
modules/proxy/mod_proxy_fcgi.c
modules/proxy/mod_proxy_scgi.c
modules/proxy/mod_proxy_uwsgi.c

index 3566bd38253b3a3b2322c3fd96576c6cc940fdd3..0557c7fdda68341d0a5d9287d69ba9b9281203c8 100644 (file)
@@ -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
index 1aadcc2e97ac9d3026a947a1165f40a572508369..69743f142a44475d724d4324275634c068e90a9f 100644 (file)
@@ -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
                                        */
index 63711b2eb09defba47517bbba2b58a2bb27c89fa..1f7778617e9a9141486fbcae58949dd659d81024 100644 (file)
@@ -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);
 
             /*
index 2258a683b75187e4851771d3431c605e85a057a9..4bab59f932739585e49d9873ef0b133d0038901c 100644 (file)
@@ -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);
 
             /*
index 1a8df347bec90c48f1b634a0ac6a864534f55db1..cef601cae36371bc3e6870c2430d5547d27000a0 100644 (file)
@@ -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);
index a09a2e43a363eae2c7093cacabcbc5a6f7689c59..0266a7dafc2ee302e94da4e5976fca9f61055042 100644 (file)
@@ -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[] = {
@@ -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;
 }
 
index 831bd15ae9d48019b355779291ccb9755473e8e4..d420df6a77a507c3ded5b65e22537d1e0aa3a0a4 100644 (file)
@@ -779,6 +779,15 @@ recv_again:
 
                             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;
index 5444a5c4270b36a05a8df894fd9445695007a2d4..d63c8338a55195947efb77c2e2112d4ba97c76ca 100644 (file)
@@ -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;
index fd76c955084199e0ef98694a7bbdc1ac49326910..4e57196bade3dcf81685dd5410c38443cec21c95 100644 (file)
@@ -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));
     }