Hello :)
This patch adds support for X-Forwarded-For (or any other) http request header
holding ip address of real client so that request.getRemoteAddr() return
correct address if tomcat is running behind apache or any other reverse http
proxy.
Best regards, Brane
Index: java/org/apache/catalina/connector/RequestFacade.java
===
--- java/org/apache/catalina/connector/RequestFacade.java (revision 832150)
+++ java/org/apache/catalina/connector/RequestFacade.java (working copy)
@@ -477,6 +477,20 @@
throw new IllegalStateException(
sm.getString("requestFacade.nullRequest"));
}
+
+// is this forwarded request?
+if (request.getConnector().getForwarded()) {
+String header = request.getConnector().getForwardedForHeader();
+if (header != null) {
+// check for header in request
+String v = request.getHeader(header);
+// if header is found, return its value,
+// otherwise fallback to original behaviour
+if (v != null && v.length() > 0) {
+return v;
+}
+}
+}
return request.getRemoteAddr();
}
@@ -489,6 +503,20 @@
sm.getString("requestFacade.nullRequest"));
}
+// is this forwarded request?
+if (request.getConnector().getForwarded()) {
+String header = request.getConnector().getForwardedForHeader();
+if (header != null) {
+// check for header in request
+String v = request.getHeader(header);
+// if header is found, return its value,
+// otherwise fallback to original behaviour
+if (v != null && v.length() > 0) {
+return v;
+}
+}
+}
+
return request.getRemoteHost();
}
@@ -929,6 +957,12 @@
sm.getString("requestFacade.nullRequest"));
}
+// is this forwarded request?
+if (request.getConnector().getForwarded()) {
+// it's impossible to identify remote port...
+return -1;
+}
+
return request.getRemotePort();
}
Index: java/org/apache/catalina/connector/Connector.java
===
--- java/org/apache/catalina/connector/Connector.java (revision 832150)
+++ java/org/apache/catalina/connector/Connector.java (working copy)
@@ -184,8 +184,21 @@
*/
protected boolean secure = false;
+/**
+ * If true use hostHeader or else check the headers for retrieving information
+ * from the original request to control what is returned by
+ * ServletRequest#getServerName() and ServletRequest#getServerPort()
+ * and ServletRequest#getRemoteAddr() (see Configuring mod_proxy). Default is false.
+ */
+protected boolean forwarded = false;
/**
+ * The forwarded for header to use. Default is X-Forwarded-For.
+ * This value is only used if forwarded is true.
+ */
+protected String forwardedForHeader = "X-Forwarded-For";
+
+/**
* The string manager for this package.
*/
protected StringManager sm =
@@ -848,6 +861,48 @@
setProperty("secure", Boolean.toString(secure));
}
+/**
+ * Returns forwarded status for this connector
+ */
+public boolean getForwarded() {
+return this.forwarded;
+}
+
+/**
+ * Sets forwarded flag.
+ * If true use hostHeader or else check the headers for retrieving information from the original
+ * request to control what is returned by ServletRequest#getServerName() and ServletRequest#getServerPort()
+ * and ServletRequest#getRemoteAddr() (see Configuring mod_proxy). Default is false.
+ *
+ * @param forwarded Forwarded flag
+ */
+public void setForwarded(boolean forwarded) {
+this.forwarded = forwarded;
+}
+
+/**
+ * Returns forwarded-for header name. This header is then
+ * used for HttpServletRequest#getRemoteAddr to determine
+ * IP address of final client.
+ */
+public String getForwardedForHeader() {
+return this.forwardedForHeader;
+}
+
+/**
+ * Sets forwarded-for http request header name. This header is used to
+ * to determine client's IP address by HttpServletRequest#getRemoteAddr
+ * if forwarded flag is true.
+ *
+ * @param name forwarded-for header name
+ */
+public void setForwardedForHeader(String name) {
+if (name == null || name.length() < 1) {
+throw new IllegalStateException("forwardedForHeader cannot be null or zero-length string.");
+}
+this.forwardedForHeader = name;
+}
+
/**
* Return the character encoding to be used for the