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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org