You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2005/07/13 15:59:33 UTC

svn commit: r216156 - /httpd/httpd/trunk/modules/proxy/mod_proxy_http.c

Author: wrowe
Date: Wed Jul 13 06:59:32 2005
New Revision: 216156

URL: http://svn.apache.org/viewcvs?rev=216156&view=rev
Log:

  send_request_body and indentation made it very difficult to follow
  all the mistakes in this code.  Fold send_request_body into reindent
  to make the pattern clear and skip some extra string handling.
  Little functional change, that comes next.

Modified:
    httpd/httpd/trunk/modules/proxy/mod_proxy_http.c

Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_http.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/proxy/mod_proxy_http.c?rev=216156&r1=216155&r2=216156&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy_http.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy_http.c Wed Jul 13 06:59:32 2005
@@ -525,94 +525,6 @@
     return status;
 }
 
-static apr_status_t send_request_body(apr_pool_t *p,
-                                      request_rec *r,
-                                      proxy_conn_rec *conn,
-                                      conn_rec *origin,
-                                      apr_bucket_brigade *header_brigade,
-                                      int force10)
-{
-    enum {RB_INIT, RB_STREAM_CL, RB_STREAM_CHUNKED, RB_SPOOL_CL} rb_method = RB_INIT;
-    const char *old_cl_val, *te_val;
-    int cl_zero; /* client sent "Content-Length: 0", which we forward on to server */
-    apr_status_t status;
-
-    /* send CL or use chunked encoding?
-     *
-     * . CL is the most friendly to the origin server since it is the
-     *   most widely supported
-     * . CL stinks if we don't know the length since we have to buffer
-     *   the data in memory or on disk until we get the entire data
-     *
-     * special cases to check for:
-     * . if we're using HTTP/1.0 to origin server, then we must send CL
-     * . if client sent C-L and there are no input resource filters, the
-     *   the body size can't change so we send the same CL and stream the
-     *   body
-     * . if client used chunked or proxy-sendchunks is set, we'll use
-     *   chunked
-     *
-     * normal case:
-     *   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
-     *
-     * special envvars to override the normal decision:
-     * . proxy-sendchunks
-     *   use chunked encoding; not compatible with force-proxy-request-1.0
-     * . proxy-sendcl
-     *   spool the request body to compute C-L
-     * . proxy-sendunchangedcl
-     *   use C-L from client and spool the request body
-     */
-    old_cl_val = apr_table_get(r->headers_in, "Content-Length");
-    cl_zero = old_cl_val && !strcmp(old_cl_val, "0");
-
-    if (!force10
-        && !cl_zero
-        && apr_table_get(r->subprocess_env, "proxy-sendchunks")) {
-        rb_method = RB_STREAM_CHUNKED;
-    }
-    else if (!cl_zero
-             && apr_table_get(r->subprocess_env, "proxy-sendcl")) {
-        rb_method = RB_SPOOL_CL;
-    }
-    else {
-        if (old_cl_val &&
-            (r->input_filters == r->proto_input_filters
-             || cl_zero
-             || apr_table_get(r->subprocess_env, "proxy-sendunchangedcl"))) {
-            rb_method = RB_STREAM_CL;
-        }
-        else if (force10) {
-            rb_method = RB_SPOOL_CL;
-        }
-        else if ((te_val = apr_table_get(r->headers_in, "Transfer-Encoding"))
-                  && !strcasecmp(te_val, "chunked")) {
-            rb_method = RB_STREAM_CHUNKED;
-        }
-        else {
-            rb_method = RB_SPOOL_CL;
-        }
-    }
-
-    switch(rb_method) {
-    case RB_STREAM_CHUNKED:
-        status = stream_reqbody_chunked(p, r, conn, origin, header_brigade);
-        break;
-    case RB_STREAM_CL:
-        status = stream_reqbody_cl(p, r, conn, origin, header_brigade, old_cl_val);
-        break;
-    case RB_SPOOL_CL:
-        status = spool_reqbody_cl(p, r, conn, origin, header_brigade);
-        break;
-    default:
-        ap_assert(1 != 1);
-    }
-
-    return status;
-}
-
 static
 apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r,
                                    proxy_conn_rec *conn, conn_rec *origin, 
@@ -628,6 +540,11 @@
     int counter;
     apr_status_t status;
     apr_bucket_brigade *header_brigade;
+    enum rb_methods {RB_INIT, RB_STREAM_CL, RB_STREAM_CHUNKED, RB_SPOOL_CL};
+    rb_method = RB_INIT;
+    const char *old_cl_val = NULL;
+    const char *old_te_val = NULL;
+    int cl_zero; /* client sent "Content-Length: 0", which we forward */
     int force10;
 
     header_brigade = apr_brigade_create(p, origin->bucket_alloc);
@@ -790,34 +707,42 @@
         if (headers_in[counter].key == NULL 
              || headers_in[counter].val == NULL
 
-        /* Clear out hop-by-hop request headers not to send
-         * RFC2616 13.5.1 says we should strip these headers
-         */
-                /* Already sent */
+            /* Already sent */
              || !strcasecmp(headers_in[counter].key, "Host")
 
+            /* Clear out hop-by-hop request headers not to send
+             * RFC2616 13.5.1 says we should strip these headers
+             */
              || !strcasecmp(headers_in[counter].key, "Keep-Alive")
              || !strcasecmp(headers_in[counter].key, "TE")
              || !strcasecmp(headers_in[counter].key, "Trailer")
-             || !strcasecmp(headers_in[counter].key, "Transfer-Encoding")
              || !strcasecmp(headers_in[counter].key, "Upgrade")
 
-            /* We'll add appropriate Content-Length later, if appropriate.
+            /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be 
+             * suppressed if THIS server requested the authentication,
+             * not when a frontend proxy requested it!
+             *
+             * The solution to this problem is probably to strip out
+             * the Proxy-Authorisation header in the authorisation
+             * code itself, not here. This saves us having to signal
+             * somehow whether this request was authenticated or not.
              */
-             || !strcasecmp(headers_in[counter].key, "Content-Length")
-        /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be 
-         * suppressed if THIS server requested the authentication,
-         * not when a frontend proxy requested it!
-         *
-         * The solution to this problem is probably to strip out
-         * the Proxy-Authorisation header in the authorisation
-         * code itself, not here. This saves us having to signal
-         * somehow whether this request was authenticated or not.
-         */
              || !strcasecmp(headers_in[counter].key,"Proxy-Authorization")
              || !strcasecmp(headers_in[counter].key,"Proxy-Authenticate")) {
             continue;
         }
+
+        /* Skip Transfer-Encoding and Content-Length for now.
+         */
+        if (!strcasecmp(headers_in[counter].key, "Transfer-Encoding")) {
+            old_te_val = headers_in[counter].key;
+            continue;
+        }
+        if (!strcasecmp(headers_in[counter].key, "Content-Length")) {
+            old_cl_val = headers_in[counter].key;
+            continue;
+        }
+
         /* for sub-requests, ignore freshness/expiry headers */
         if (r->main) {
             if (headers_in[counter].key == NULL
@@ -839,8 +764,77 @@
         APR_BRIGADE_INSERT_TAIL(header_brigade, e);
     }
 
+    /* send CL or use chunked encoding?
+     *
+     * . CL is the most friendly to the origin server since it is the
+     *   most widely supported
+     * . CL stinks if we don't know the length since we have to buffer
+     *   the data in memory or on disk until we get the entire data
+     *
+     * special cases to check for:
+     * . if we're using HTTP/1.0 to origin server, then we must send CL
+     * . if client sent C-L and there are no input resource filters, the
+     *   the body size can't change so we send the same CL and stream the
+     *   body
+     * . if client used chunked or proxy-sendchunks is set, we'll use
+     *   chunked
+     *
+     * normal case:
+     *   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
+     *
+     * special envvars to override the normal decision:
+     * . proxy-sendchunks
+     *   use chunked encoding; not compatible with force-proxy-request-1.0
+     * . proxy-sendcl
+     *   spool the request body to compute C-L
+     * . proxy-sendunchangedcl
+     *   use C-L from client and spool the request body
+     */
+    cl_zero = old_cl_val && !strcmp(old_cl_val, "0");
+
+    if (!force10
+        && !cl_zero
+        && apr_table_get(r->subprocess_env, "proxy-sendchunks")) {
+        rb_method = RB_STREAM_CHUNKED;
+    }
+    else if (!cl_zero
+             && apr_table_get(r->subprocess_env, "proxy-sendcl")) {
+        rb_method = RB_SPOOL_CL;
+    }
+    else {
+        if (old_cl_val &&
+            (r->input_filters == r->proto_input_filters
+             || cl_zero
+             || apr_table_get(r->subprocess_env, "proxy-sendunchangedcl"))) {
+            rb_method = RB_STREAM_CL;
+        }
+        else if (force10) {
+            rb_method = RB_SPOOL_CL;
+        }
+        else if (old_te_val && !strcasecmp(te_val, "chunked")) {
+            rb_method = RB_STREAM_CHUNKED;
+        }
+        else {
+            rb_method = RB_SPOOL_CL;
+        }
+    }
+
     /* send the request data, if any. */
-    status = send_request_body(p, r, conn, origin, header_brigade, force10);
+    switch(rb_method) {
+    case RB_STREAM_CHUNKED:
+        status = stream_reqbody_chunked(p, r, conn, origin, header_brigade);
+        break;
+    case RB_STREAM_CL:
+        status = stream_reqbody_cl(p, r, conn, origin, header_brigade, old_cl_val);
+        break;
+    case RB_SPOOL_CL:
+        status = spool_reqbody_cl(p, r, conn, origin, header_brigade);
+        break;
+    default:
+        ap_assert(1 != 1);
+    }
     if (status != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
                      "proxy: pass request data failed to %pI (%s)",