You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by rj...@apache.org on 2015/01/02 16:15:53 UTC

svn commit: r1649064 - in /tomcat/jk/trunk: native/apache-1.3/mod_jk.c native/apache-2.0/mod_jk.c xdocs/miscellaneous/changelog.xml xdocs/reference/apache.xml

Author: rjung
Date: Fri Jan  2 15:15:52 2015
New Revision: 1649064

URL: http://svn.apache.org/r1649064
Log:
BZ 34526: Apache: Improve compatibility with
mod_deflate request body inflation.

An automatic detection of mod_deflate inflation
is not implemented. Allow to use the new Apache
environment variable JK_IGNORE_CL instead, to
let mod_jk ignore an existing Content-Length
request header.

All body data that can be read from the web server
will be send to the backend. No Content-Length
header will be send to the backend.

Modified:
    tomcat/jk/trunk/native/apache-1.3/mod_jk.c
    tomcat/jk/trunk/native/apache-2.0/mod_jk.c
    tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
    tomcat/jk/trunk/xdocs/reference/apache.xml

Modified: tomcat/jk/trunk/native/apache-1.3/mod_jk.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/apache-1.3/mod_jk.c?rev=1649064&r1=1649063&r2=1649064&view=diff
==============================================================================
--- tomcat/jk/trunk/native/apache-1.3/mod_jk.c (original)
+++ tomcat/jk/trunk/native/apache-1.3/mod_jk.c Fri Jan  2 15:15:52 2015
@@ -73,6 +73,7 @@
 #define JK_ENV_LOCAL_NAME           ("JK_LOCAL_NAME")
 #define JK_ENV_LOCAL_ADDR           ("JK_LOCAL_ADDR")
 #define JK_ENV_LOCAL_PORT           ("JK_LOCAL_PORT")
+#define JK_ENV_IGNORE_CL            ("JK_IGNORE_CL")
 #define JK_ENV_HTTPS                ("HTTPS")
 #define JK_ENV_CERTS                ("SSL_CLIENT_CERT")
 #define JK_ENV_CIPHER               ("SSL_CIPHER")
@@ -186,6 +187,14 @@ typedef struct
     char *local_port_indicator;
 
     /*
+     * Configurable environment variable to force
+     * ignoring a request Content-Length header
+     * (useful to make mod_deflate request inflation
+     * compatible with mod_jk).
+     */
+    char *ignore_cl_indicator;
+
+    /*
      * SSL Support
      */
     int ssl_enable;
@@ -914,6 +923,11 @@ static int init_ws_service(apache_privat
     s->method = (char *)r->method;
     s->content_length = get_content_length(r);
     s->is_chunked = r->read_chunked;
+    if (s->content_length > 0 &&
+        get_env_string(r, NULL, conf->ignore_cl_indicator, 0) != NULL) {
+        s->content_length = 0;
+        s->is_chunked = 1;
+    }
     s->no_more_chunks = 0;
     s->query_string = r->args;
 
@@ -1063,6 +1077,7 @@ static int init_ws_service(apache_privat
         array_header *t = ap_table_elts(r->headers_in);
         if (t && t->nelts) {
             int i;
+            int off = 0;
             table_entry *elts = (table_entry *) t->elts;
             s->num_headers = t->nelts;
             /* allocate an extra header slot in case we need to add a content-length header */
@@ -1074,12 +1089,17 @@ static int init_ws_service(apache_privat
                 return JK_FALSE;
             for (i = 0; i < t->nelts; i++) {
                 char *hname = ap_pstrdup(r->pool, elts[i].key);
-                s->headers_values[i] = ap_pstrdup(r->pool, elts[i].val);
-                s->headers_names[i] = hname;
-                if (need_content_length_header &&
-                    !strcasecmp(s->headers_names[i], "content-length")) {
-                    need_content_length_header = JK_FALSE;
+                if (!strcasecmp(hname, "content-length")) {
+                    if (need_content_length_header) {
+                        need_content_length_header = JK_FALSE;
+                    } else if (s->is_chunked) {
+                        s->num_headers--;
+                        off++;
+                        continue;
+                    }
                 }
+                s->headers_values[i - off] = ap_pstrdup(r->pool, elts[i].val);
+                s->headers_names[i - off] = hname;
             }
             /* Add a content-length = 0 header if needed.
              * Ajp13 assumes an absent content-length header means an unknown,
@@ -2002,6 +2022,16 @@ static const char *jk_set_local_port_ind
     return NULL;
 }
 
+static const char *jk_set_ignore_cl_indicator(cmd_parms * cmd,
+                                              void *dummy, const char *indicator)
+{
+    server_rec *s = cmd->server;
+    jk_server_conf_t *conf =
+        (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module);
+    conf->ignore_cl_indicator = ap_pstrdup(cmd->pool, indicator);
+    return NULL;
+}
+
 /*
  * JkExtractSSL Directive Handling
  *
@@ -2419,6 +2449,9 @@ static const command_rec jk_cmds[] = {
      "Name of the Apache environment that contains the local IP address"},
     {"JkLocalPortIndicator", jk_set_local_port_indicator, NULL, RSRC_CONF, TAKE1,
      "Name of the Apache environment that contains the local port"},
+    {"JkIgnoreCLIndicator", jk_set_ignore_cl_indicator, NULL, RSRC_CONF, TAKE1,
+     "Name of the Apache environment that forces to ignore a request "
+     "Content-Length header"},
 
     /*
      * Apache has multiple SSL modules (for example apache_ssl, stronghold
@@ -2772,6 +2805,8 @@ static void *create_jk_config(ap_pool *
         c->local_addr_indicator = JK_ENV_LOCAL_ADDR;
         c->local_port_indicator = JK_ENV_LOCAL_PORT;
 
+        c->ignore_cl_indicator = JK_ENV_IGNORE_CL;
+
         /*
          * By default we will try to gather SSL info.
          * Disable this functionality through JkExtractSSL
@@ -2851,6 +2886,9 @@ static void *merge_jk_config(ap_pool * p
     if (!overrides->local_port_indicator)
         overrides->local_port_indicator = base->local_port_indicator;
 
+    if (!overrides->ignore_cl_indicator)
+        overrides->ignore_cl_indicator = base->ignore_cl_indicator;
+
     if (overrides->ssl_enable == JK_UNSET)
         overrides->ssl_enable = base->ssl_enable;
     if (!overrides->https_indicator)

Modified: tomcat/jk/trunk/native/apache-2.0/mod_jk.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/apache-2.0/mod_jk.c?rev=1649064&r1=1649063&r2=1649064&view=diff
==============================================================================
--- tomcat/jk/trunk/native/apache-2.0/mod_jk.c (original)
+++ tomcat/jk/trunk/native/apache-2.0/mod_jk.c Fri Jan  2 15:15:52 2015
@@ -108,6 +108,7 @@
 #define JK_ENV_LOCAL_NAME           ("JK_LOCAL_NAME")
 #define JK_ENV_LOCAL_ADDR           ("JK_LOCAL_ADDR")
 #define JK_ENV_LOCAL_PORT           ("JK_LOCAL_PORT")
+#define JK_ENV_IGNORE_CL            ("JK_IGNORE_CL")
 #define JK_ENV_HTTPS                ("HTTPS")
 #define JK_ENV_CERTS                ("SSL_CLIENT_CERT")
 #define JK_ENV_CIPHER               ("SSL_CIPHER")
@@ -216,6 +217,14 @@ typedef struct
     char *local_port_indicator;
 
     /*
+     * Configurable environment variable to force
+     * ignoring a request Content-Length header
+     * (useful to make mod_deflate request inflation
+     * compatible with mod_jk).
+     */
+    char *ignore_cl_indicator;
+
+    /*
      * SSL Support
      */
     int ssl_enable;
@@ -970,6 +979,11 @@ static int init_ws_service(apache_privat
     s->method = (char *)r->method;
     s->content_length = get_content_length(r);
     s->is_chunked = r->read_chunked;
+    if (s->content_length > 0 &&
+        get_env_string(r, NULL, conf->ignore_cl_indicator, 0) != NULL) {
+        s->content_length = 0;
+        s->is_chunked = 1;
+    }
     s->no_more_chunks = 0;
 #if defined(AS400) && !defined(AS400_UTF8)
     /* Get the query string that is not translated to EBCDIC  */
@@ -1124,6 +1138,7 @@ static int init_ws_service(apache_privat
         const apr_array_header_t *t = apr_table_elts(r->headers_in);
         if (t && t->nelts) {
             int i;
+            int off = 0;
             apr_table_entry_t *elts = (apr_table_entry_t *) t->elts;
             s->num_headers = t->nelts;
             /* allocate an extra header slot in case we need to add a content-length header */
@@ -1135,12 +1150,17 @@ static int init_ws_service(apache_privat
                 return JK_FALSE;
             for (i = 0; i < t->nelts; i++) {
                 char *hname = apr_pstrdup(r->pool, elts[i].key);
-                s->headers_values[i] = apr_pstrdup(r->pool, elts[i].val);
-                s->headers_names[i] = hname;
-                if (need_content_length_header &&
-                    !strcasecmp(s->headers_names[i], "content-length")) {
-                    need_content_length_header = JK_FALSE;
+                if (!strcasecmp(hname, "content-length")) {
+                    if (need_content_length_header) {
+                        need_content_length_header = JK_FALSE;
+                    } else if (s->is_chunked) {
+                        s->num_headers--;
+                        off++;
+                        continue;
+                    }
                 }
+                s->headers_values[i - off] = apr_pstrdup(r->pool, elts[i].val);
+                s->headers_names[i - off] = hname;
             }
             /* Add a content-length = 0 header if needed.
              * Ajp13 assumes an absent content-length header means an unknown,
@@ -2090,6 +2110,16 @@ static const char *jk_set_local_port_ind
     return NULL;
 }
 
+static const char *jk_set_ignore_cl_indicator(cmd_parms * cmd,
+                                              void *dummy, const char *indicator)
+{
+    server_rec *s = cmd->server;
+    jk_server_conf_t *conf =
+        (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module);
+    conf->ignore_cl_indicator = apr_pstrdup(cmd->pool, indicator);
+    return NULL;
+}
+
 /*
  * JkExtractSSL Directive Handling
  *
@@ -2541,6 +2571,9 @@ static const command_rec jk_cmds[] = {
                   "Name of the Apache environment that contains the local IP address"),
     AP_INIT_TAKE1("JkLocalPortIndicator", jk_set_local_port_indicator, NULL, RSRC_CONF,
                   "Name of the Apache environment that contains the local port"),
+    AP_INIT_TAKE1("JkIgnoreCLIndicator", jk_set_ignore_cl_indicator, NULL, RSRC_CONF,
+                  "Name of the Apache environment that forces to ignore a request "
+                  "Content-Length header"),
 
     /*
      * Apache has multiple SSL modules (for example apache_ssl, stronghold
@@ -2994,6 +3027,8 @@ static void *create_jk_config(apr_pool_t
         c->local_addr_indicator = JK_ENV_LOCAL_ADDR;
         c->local_port_indicator = JK_ENV_LOCAL_PORT;
 
+        c->ignore_cl_indicator = JK_ENV_IGNORE_CL;
+
         /*
          * By default we will try to gather SSL info.
          * Disable this functionality through JkExtractSSL
@@ -3076,6 +3111,9 @@ static void *merge_jk_config(apr_pool_t
     if (!overrides->local_port_indicator)
         overrides->local_port_indicator = base->local_port_indicator;
 
+    if (!overrides->ignore_cl_indicator)
+        overrides->ignore_cl_indicator = base->ignore_cl_indicator;
+
     if (overrides->ssl_enable == JK_UNSET)
         overrides->ssl_enable = base->ssl_enable;
     if (!overrides->https_indicator)

Modified: tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml?rev=1649064&r1=1649063&r2=1649064&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml (original)
+++ tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml Fri Jan  2 15:15:52 2015
@@ -157,6 +157,13 @@
         <bug>56452</bug>: Fix crash in debug logging for IPv6 adresses.
         Patch contributed by Christopher Schultz. (rjung)
       </fix>
+      <fix>
+        <bug>34526</bug>: Apache: Improve compatibility with mod_deflate
+        request body inflation. An automatic detection of mod_deflate
+        inflation is not implemented. Use the new Apache environment variable
+        JK_IGNORE_CL instead, to let mod_jk ignore an existing Content-Length
+        request header. (rjung)
+      </fix>
     </changelog>
   </subsection>
 </section>

Modified: tomcat/jk/trunk/xdocs/reference/apache.xml
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/reference/apache.xml?rev=1649064&r1=1649063&r2=1649064&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/reference/apache.xml (original)
+++ tomcat/jk/trunk/xdocs/reference/apache.xml Fri Jan  2 15:15:52 2015
@@ -369,6 +369,16 @@ The default value is "JK_LOCAL_NAME".
 <br/>
 This directive has been added in version 1.2.28 of mod_jk.
 </p></attribute>
+<attribute name="JkIgnoreCLIndicator" required="false"><p>
+Name of the Apache environment variable which forces to
+ignore an existing Content-Length request header. This can be
+used to make mod_jk conpatible with mod_deflate request body
+inflation (see <a href="#Advanced Environment Variables">below</a>).
+<br/>
+The default value is "JK_IGNORE_CL".
+<br/>
+This directive has been added in version 1.2.41 of mod_jk.
+</p></attribute>
 <attribute name="JkLocalAddrIndicator" required="false"><p>
 Name of the Apache environment variable which can be used to overwrite
 the forwarded local IP address.
@@ -1246,6 +1256,29 @@ then the request will not count as a new
 come with a session id.
 This is available since version 1.2.33.
 </p>
+<p>
+The environment variable
+<b>JK_IGNORE_CL</b> can be set to force ignoring the request
+Content-Length header (if it exists). mod_jk will then stream
+the request body until the web server indicates that the full body
+was read. No Content-Length header will be send to the backend.
+This is available since version 1.2.41.
+</p>
+<p>
+This feature can be used to make mod_jk compatible with filters
+which change the size of the request body. One such filter is
+mod_deflate when used to inflate the body of a request with gzip
+encoded body. In this case mod_jk will by default forward a truncated
+body, because it gets the wrong body size from the web server.
+Telling mod_jk to ignore the Content-Length header will result
+in streaming all request body data it can read from the web server
+to the backend.
+</p>
+<p>
+You should only set the <b>JK_IGNORE_CL</b> environment variables
+for requests that actually need it. Unfortunately there's no way
+for mod_jk to detect the need automatically.
+</p>
 </subsection>
  </section>
 </body>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org