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

Reply via email to