Author: rjung Date: Thu Jul 10 23:27:52 2014 New Revision: 1609589 URL: http://svn.apache.org/r1609589 Log: BZ 56661: Fix Servlet API getLocalAddr().
Forward local IP address which is not part of AJP protocol via custom request attribute named "AJP_LOCAL_ADDR". Currently Tomcat will handle getLocalAddr(U) like getLocalName(). Tomcat versions can now check for the new attribute and use it if available. Likely to be used by forthcoming TC 6.0.41, 7.0.55 and 8.0.11. Modified: tomcat/jk/trunk/native/apache-1.3/mod_jk.c tomcat/jk/trunk/native/apache-2.0/mod_jk.c tomcat/jk/trunk/native/common/jk_ajp_common.c tomcat/jk/trunk/native/common/jk_ajp_common.h tomcat/jk/trunk/native/common/jk_service.h tomcat/jk/trunk/native/iis/jk_isapi_plugin.c tomcat/jk/trunk/native/netscape/jk_nsapi_plugin.c tomcat/jk/trunk/xdocs/generic_howto/proxy.xml 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=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/native/apache-1.3/mod_jk.c (original) +++ tomcat/jk/trunk/native/apache-1.3/mod_jk.c Thu Jul 10 23:27:52 2014 @@ -71,6 +71,7 @@ #define JK_ENV_REMOTE_USER ("JK_REMOTE_USER") #define JK_ENV_AUTH_TYPE ("JK_AUTH_TYPE") #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_HTTPS ("HTTPS") #define JK_ENV_CERTS ("SSL_CLIENT_CERT") @@ -181,6 +182,7 @@ typedef struct char *remote_user_indicator; char *auth_type_indicator; char *local_name_indicator; + char *local_addr_indicator; char *local_port_indicator; /* @@ -827,6 +829,12 @@ static int init_ws_service(apache_privat s->server_name = get_env_string(r, (char *)ap_get_server_name(r), conf->local_name_indicator, 0); + /* get the local IP address */ + /* s->local_addr = r->connection->local_ip; */ + /* XXX : a la jk2 */ + s->local_addr = get_env_string(r, r->connection->local_ip, + conf->local_addr_indicator, 0); + /* get the real port (otherwise redirect failed) */ /* s->server_port = htons( r->connection->local_addr.sin_port ); */ /* XXX : a la jk2 */ @@ -1906,6 +1914,16 @@ static const char *jk_set_local_name_ind return NULL; } +static const char *jk_set_local_addr_indicator(cmd_parms * cmd, + void *dummy, 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->local_addr_indicator = ap_pstrdup(cmd->pool, indicator); + return NULL; +} + static const char *jk_set_local_port_indicator(cmd_parms * cmd, void *dummy, char *indicator) { @@ -2315,6 +2333,8 @@ static const command_rec jk_cmds[] = { "Name of the Apache environment that contains the type of authentication"}, {"JkLocalNameIndicator", jk_set_local_name_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the local name"}, + {"JkLocalAddrIndicator", jk_set_local_addr_indicator, NULL, RSRC_CONF, TAKE1, + "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"}, @@ -2667,6 +2687,7 @@ static void *create_jk_config(ap_pool * c->remote_user_indicator = JK_ENV_REMOTE_USER; c->auth_type_indicator = JK_ENV_AUTH_TYPE; c->local_name_indicator = JK_ENV_LOCAL_NAME; + c->local_addr_indicator = JK_ENV_LOCAL_ADDR; c->local_port_indicator = JK_ENV_LOCAL_PORT; /* 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=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/native/apache-2.0/mod_jk.c (original) +++ tomcat/jk/trunk/native/apache-2.0/mod_jk.c Thu Jul 10 23:27:52 2014 @@ -106,6 +106,7 @@ #define JK_ENV_REMOTE_USER ("JK_REMOTE_USER") #define JK_ENV_AUTH_TYPE ("JK_AUTH_TYPE") #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_HTTPS ("HTTPS") #define JK_ENV_CERTS ("SSL_CLIENT_CERT") @@ -211,6 +212,7 @@ typedef struct char *remote_user_indicator; char *auth_type_indicator; char *local_name_indicator; + char *local_addr_indicator; char *local_port_indicator; /* @@ -889,6 +891,10 @@ static int init_ws_service(apache_privat s->server_name = get_env_string(r, (char *)ap_get_server_name(r), conf->local_name_indicator, 0); + /* get the local IP address */ + s->local_addr = get_env_string(r, r->connection->local_ip, + conf->local_addr_indicator, 0); + /* get the real port (otherwise redirect failed) */ /* XXX: use apache API for getting server port * @@ -2006,6 +2012,16 @@ static const char *jk_set_local_name_ind return NULL; } +static const char *jk_set_local_addr_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->local_addr_indicator = apr_pstrdup(cmd->pool, indicator); + return NULL; +} + static const char *jk_set_local_port_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { @@ -2449,6 +2465,8 @@ static const command_rec jk_cmds[] = { "Name of the Apache environment that contains the type of authentication"), AP_INIT_TAKE1("JkLocalNameIndicator", jk_set_local_name_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the local name"), + AP_INIT_TAKE1("JkLocalAddrIndicator", jk_set_local_addr_indicator, NULL, RSRC_CONF, + "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"), @@ -2901,6 +2919,7 @@ static void *create_jk_config(apr_pool_t c->remote_user_indicator = JK_ENV_REMOTE_USER; c->auth_type_indicator = JK_ENV_AUTH_TYPE; c->local_name_indicator = JK_ENV_LOCAL_NAME; + c->local_addr_indicator = JK_ENV_LOCAL_ADDR; c->local_port_indicator = JK_ENV_LOCAL_PORT; /* Modified: tomcat/jk/trunk/native/common/jk_ajp_common.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp_common.c?rev=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/native/common/jk_ajp_common.c (original) +++ tomcat/jk/trunk/native/common/jk_ajp_common.c Thu Jul 10 23:27:52 2014 @@ -604,6 +604,22 @@ static int ajp_marshal_into_msgb(jk_msg_ JK_TRACE_EXIT(l); return JK_FALSE; } + /* Forward the local ip address information, which was forgotten + * from the builtin data of the AJP 13 protocol. + * Since the servlet spec allows to retrieve it via getLocalAddr(), + * we provide the address to the Tomcat connector as a request + * attribute. Modern Tomcat versions know how to retrieve + * the local address from this attribute. + */ + if (jk_b_append_byte(msg, SC_A_REQ_ATTRIBUTE) || + jk_b_append_string(msg, SC_A_REQ_LOCAL_ADDR) || + jk_b_append_string(msg, s->local_addr)) { + jk_log(l, JK_LOG_ERROR, + "failed appending the local address %s", + s->local_addr); + JK_TRACE_EXIT(l); + return JK_FALSE; + } /* Forward activation information from the load balancer. * It can be used by the backend to deny access by requests, * which come with a session id but for an invalid session. Modified: tomcat/jk/trunk/native/common/jk_ajp_common.h URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp_common.h?rev=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/native/common/jk_ajp_common.h (original) +++ tomcat/jk/trunk/native/common/jk_ajp_common.h Thu Jul 10 23:27:52 2014 @@ -72,11 +72,17 @@ extern "C" /* * AJP private request attributes - * + */ +/* * The following request attribute is recognized by Tomcat * to contain the forwarded remote port. */ #define SC_A_REQ_REMOTE_PORT ("AJP_REMOTE_PORT") +/* + * The following request attribute is recognized by Tomcat + * to contain the forwarded local ip address. + */ +#define SC_A_REQ_LOCAL_ADDR ("AJP_LOCAL_ADDR") /* * JK public request attributes Modified: tomcat/jk/trunk/native/common/jk_service.h URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_service.h?rev=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/native/common/jk_service.h (original) +++ tomcat/jk/trunk/native/common/jk_service.h Thu Jul 10 23:27:52 2014 @@ -168,6 +168,7 @@ struct jk_ws_service const char *auth_type; const char *query_string; const char *server_name; + const char *local_addr; unsigned server_port; char *server_software; jk_uint64_t content_length; /* 64 bit integer that represents the content */ Modified: tomcat/jk/trunk/native/iis/jk_isapi_plugin.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/iis/jk_isapi_plugin.c?rev=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/native/iis/jk_isapi_plugin.c (original) +++ tomcat/jk/trunk/native/iis/jk_isapi_plugin.c Thu Jul 10 23:27:52 2014 @@ -3180,6 +3180,7 @@ static int init_ws_service(isapi_private GET_SERVER_VARIABLE_VALUE("REMOTE_ADDR", s->remote_addr); GET_SERVER_VARIABLE_VALUE("REMOTE_PORT", s->remote_port); GET_SERVER_VARIABLE_VALUE("SERVER_NAME", s->server_name); + GET_SERVER_VARIABLE_VALUE("LOCAL_ADDR", s->local_addr); GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT", s->server_port, 80); GET_SERVER_VARIABLE_VALUE("SERVER_SOFTWARE", s->server_software); GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT_SECURE", s->is_ssl, 0); Modified: tomcat/jk/trunk/native/netscape/jk_nsapi_plugin.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/netscape/jk_nsapi_plugin.c?rev=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/native/netscape/jk_nsapi_plugin.c (original) +++ tomcat/jk/trunk/native/netscape/jk_nsapi_plugin.c Thu Jul 10 23:27:52 2014 @@ -492,6 +492,8 @@ static int init_ws_service(nsapi_private s->query_string = pblock_findval("query", private_data->rq->reqpb); + /* Local address is not available from NSAPI. */ + s->local_addr = server_hostname; s->server_name = server_hostname; #ifdef NETWARE @@ -503,7 +505,7 @@ static int init_ws_service(nsapi_private s->server_port = atoi(tmp); else #endif - s->server_port = server_portnum; + s->server_port = server_portnum; s->server_software = system_version(); s->uw_map = uw_map; Modified: tomcat/jk/trunk/xdocs/generic_howto/proxy.xml URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/generic_howto/proxy.xml?rev=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/xdocs/generic_howto/proxy.xml (original) +++ tomcat/jk/trunk/xdocs/generic_howto/proxy.xml Thu Jul 10 23:27:52 2014 @@ -62,18 +62,29 @@ metadata whenever the application asks f <p>The following list contains the communication metadata handled by AJP and the ServletRequest/HttpServletRequest API calls which can be used to retrieve them: <ul> -<li>local name: <code>getLocalName()</code> and <code>getLocalAddr</code>. +<li>local name: <code>getLocalName()</code>. This is also equal to <code>getServerName()</code>, unless a <code>Host</code> header is contained in the request. In this case the server name is taken from that header. </li> -<li>local port: <code>getLocalPort()</code> +<li>local IP address: <code>getLocalAddr()</code>. +The local IP address was initially not supported. It is available when using mod_jk 1.2.41 +with Apache or IIS (not for the NSAPI plugin) together with Tomcat version at least +6.0.42, 7.0.55 or 8.0.11. For older versions, <code>getLocalAddr()</code> +will incorrectly return the same result as <code>getLocalName()</code>. +As a workaround you can forward the local IP address by setting +<code>JkEnvVar SERVER_ADDR</code> and then either using +<code>request.getAttribute("SERVER_ADDR")</code> instead of <code>getLocalAddr()</code> +or wrapping the request using a filter and overriding <code>getLocalAddr()</code> with +<code>request.getAttribute("SERVER_ADDR")</code>. +</li> +<li>local port: <code>getLocalPort()</code>. This is also equal to <code>getServerPort()</code>, unless a <code>Host</code> header is contained in the request. In this case the server port is taken from that header if it contains an explicit port, or is equal to the default port of the scheme used. </li> <li>client address: <code>getRemoteAddr()</code> </li> -<li>client port: <code>getRemotePort()</code> +<li>client port: <code>getRemotePort()</code>. The remote port was initially not supported. It is available when using mod_jk 1.2.32 with Apache or IIS (not for the NSAPI plugin) together with Tomcat version at least 5.5.28, 6.0.20 or 7.0.0. For older versions, <code>getRemotePort()</code> Modified: tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml?rev=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml (original) +++ tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml Thu Jul 10 23:27:52 2014 @@ -44,6 +44,11 @@ <br /> <subsection name="Native"> <changelog> + <fix> + <bug>56661</bug>: Fix Servlet API getLocalAddr(). + Works for Tomcat 6.0.41, 7.0.55 and 8.0.11 and Apache and ISAPI + plugins. (rjung) + </fix> <update> Status: Log old and new values when changing worker attributes. (rjung) Modified: tomcat/jk/trunk/xdocs/reference/apache.xml URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/reference/apache.xml?rev=1609589&r1=1609588&r2=1609589&view=diff ============================================================================== --- tomcat/jk/trunk/xdocs/reference/apache.xml (original) +++ tomcat/jk/trunk/xdocs/reference/apache.xml Thu Jul 10 23:27:52 2014 @@ -358,6 +358,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="JkLocalAddrIndicator" required="false"><p> +Name of the Apache environment variable which can be used to overwrite +the forwarded local IP address. +Use this only if you need to adjust the data (see the +<a href="../generic_howto/proxy.html">proxy</a> documentation). +<br/> +The default value is "JK_LOCAL_ADDR". +<br/> +This directive has been added in version 1.2.41 of mod_jk. +</p></attribute> <attribute name="JkLocalPortIndicator" required="false"><p> Name of the Apache environment variable which can be used to overwrite the forwarded local port. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org