On Sat, May 30, 2020 at 2:14 PM Yann Ylavic <[email protected]> wrote:
>
> Thoughts? (before I propose a patch..)

FWIW, the patch would look like the attached one.

Still with the aim of modernization, could we remove "proxy-sendextracrlf"?
Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c	(revision 1878280)
+++ modules/proxy/mod_proxy_http.c	(working copy)
@@ -749,40 +749,24 @@ static int ap_proxy_http_prefetch(proxy_http_req_t
         }
     }
 
-    /* Use chunked request body encoding or send a content-length body?
+    /* The request body can be streamed (using either content-length or
+     * chunked transfer-encoding), or spooled to memory/disk (MAX_MEM_SPOOL)
+     * then sent (thus using content-length with known length).
      *
-     * Prefer C-L when:
+     * We favor streaming when possible, that is:
      *
-     *   We have no request body (handled by RB_STREAM_CL)
+     *   The whole body (including empty/no body) was received on prefetch,
+     *   i.e. input brigade contains EOS; handled by RB_STREAM_CL.
      *
-     *   We have a request body length <= MAX_MEM_SPOOL
+     *   There are only proto input filters, which means no filter should
+     *   change the body length; handled by RB_STREAM_CL or RB_STREAM_CHUNKED
+     *   according to respectively C-L or T-E received from the client.
      *
-     *   The administrator has setenv force-proxy-request-1.0
+     *   The administrator did not SetEnv proxy-no-chunked, which allows us
+     *   to stream each input chunk using T-E; handled by RB_STREAM_CHUNKED.
      *
-     *   The client sent a C-L body, and the administrator has
-     *   not setenv proxy-sendchunked or has set setenv proxy-sendcl
-     *
-     *   The client sent a T-E body, and the administrator has
-     *   setenv proxy-sendcl, and not setenv proxy-sendchunked
-     *
-     * If both proxy-sendcl and proxy-sendchunked are set, the
-     * behavior is the same as if neither were set, large bodies
-     * that can't be read will be forwarded in their original
-     * form of C-L, or T-E.
-     *
-     * To ensure maximum compatibility, setenv proxy-sendcl
-     * To reduce server resource use,   setenv proxy-sendchunked
-     *
-     * Then address specific servers with conditional setenv
-     * options to restore the default behavior where desirable.
-     *
-     * We have to compute content length by reading the entire request
-     * body; if request body is not small, we'll spool the remaining
-     * input to a temporary file.  Chunked is always preferable.
-     *
-     * We can only trust the client-provided C-L if the T-E header
-     * is absent, and the filters are unchanged (the body won't
-     * be resized by another content filter).
+     * Otherwise, we have to compute content length by spooling the entire
+     * request body; handled by RB_SPOOL_CL.
      */
     if (!APR_BRIGADE_EMPTY(input_brigade)
         && APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
@@ -799,42 +783,23 @@ static int ap_proxy_http_prefetch(proxy_http_req_t
         }
         req->rb_method = RB_STREAM_CL;
     }
-    else if (req->old_te_val) {
-        if (req->force10
-             || (apr_table_get(r->subprocess_env, "proxy-sendcl")
-                  && !apr_table_get(r->subprocess_env, "proxy-sendchunks")
-                  && !apr_table_get(r->subprocess_env, "proxy-sendchunked"))) {
-            req->rb_method = RB_SPOOL_CL;
-        }
-        else {
+    else if (r->input_filters == r->proto_input_filters
+             || (!req->force10 && !apr_table_get(r->subprocess_env,
+                                                 "proxy-no-chunked"))) {
+        if (!req->old_cl_val || r->input_filters != r->proto_input_filters) {
             req->rb_method = RB_STREAM_CHUNKED;
         }
-    }
-    else if (req->old_cl_val) {
-        if (r->input_filters == r->proto_input_filters) {
-            if (!ap_parse_strict_length(&req->cl_val, req->old_cl_val)) {
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01085)
-                              "could not parse request Content-Length (%s)",
-                              req->old_cl_val);
-                return HTTP_BAD_REQUEST;
-            }
+        else if (ap_parse_strict_length(&req->cl_val, req->old_cl_val)) {
             req->rb_method = RB_STREAM_CL;
         }
-        else if (!req->force10
-                  && (apr_table_get(r->subprocess_env, "proxy-sendchunks")
-                      || apr_table_get(r->subprocess_env, "proxy-sendchunked"))
-                  && !apr_table_get(r->subprocess_env, "proxy-sendcl")) {
-            req->rb_method = RB_STREAM_CHUNKED;
-        }
         else {
-            req->rb_method = RB_SPOOL_CL;
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01085)
+                          "could not parse request Content-Length (%s)",
+                          req->old_cl_val);
+            return HTTP_BAD_REQUEST;
         }
     }
     else {
-        /* This is an appropriate default; very efficient for no-body
-         * requests, and has the behavior that it will not add any C-L
-         * when the old_cl_val is NULL.
-         */
         req->rb_method = RB_SPOOL_CL;
     }
 

Reply via email to