protected Map<String, List<String>> headers;
+ protected int localPort;
+
protected String remoteAddr;
protected String remoteHost;
protected boolean secure;
protected int serverPort;
-
+
public XForwardedRequest(HttpServletRequest request) {
super(request);
+ this.localPort = request.getLocalPort();
this.remoteAddr = request.getRemoteAddr();
this.remoteHost = request.getRemoteHost();
this.scheme = request.getScheme();
}
@Override
+ public int getLocalPort() {
+ return localPort;
+ }
+
+ @Override
public String getRemoteAddr() {
return this.remoteAddr;
}
}
+ public void setLocalPort(int localPort) {
+ this.localPort = localPort;
+ }
+
public void setRemoteAddr(String remoteAddr) {
this.remoteAddr = remoteAddr;
}
protected static final String PROTOCOL_HEADER_HTTPS_VALUE_PARAMETER = "protocolHeaderHttpsValue";
+ protected static final String PORT_HEADER_PARAMETER = "portHeader";
+
+ protected static final String CHANGE_LOCAL_PORT_PARAMETER = "changeLocalPort";
+
protected static final String PROXIES_HEADER_PARAMETER = "proxiesHeader";
protected static final String REMOTE_IP_HEADER_PARAMETER = "remoteIpHeader";
private String protocolHeaderHttpsValue = "https";
+ private String portHeader = null;
+
+ private boolean changeLocalPort = false;
+
/**
* @see #setProxiesHeader(String)
*/
} else if (protocolHeaderHttpsValue.equalsIgnoreCase(protocolHeaderValue)) {
xRequest.setSecure(true);
xRequest.setScheme("https");
- xRequest.setServerPort(httpsServerPort);
+ setPorts(xRequest, httpsServerPort);
} else {
xRequest.setSecure(false);
xRequest.setScheme("http");
- xRequest.setServerPort(httpServerPort);
+ setPorts(xRequest, httpServerPort);
}
}
}
+ private void setPorts(XForwardedRequest xrequest, int defaultPort) {
+ int port = defaultPort;
+ if (getPortHeader() != null) {
+ String portHeaderValue = xrequest.getHeader(getPortHeader());
+ if (portHeaderValue != null) {
+ try {
+ port = Integer.parseInt(portHeaderValue);
+ } catch (NumberFormatException nfe) {
+ log.debug("Invalid port value [" + portHeaderValue +
+ "] provided in header [" + getPortHeader() + "]");
+ }
+ }
+ }
+ xrequest.setServerPort(port);
+ if (isChangeLocalPort()) {
+ xrequest.setLocalPort(port);
+ }
+ }
+
/**
* Wrap the incoming <code>request</code> in a {@link XForwardedRequest} if the http header <code>x-forwareded-for</code> is not empty.
*/
}
}
+ public boolean isChangeLocalPort() {
+ return changeLocalPort;
+ }
+
public int getHttpsServerPort() {
return httpsServerPort;
}
return protocolHeader;
}
+ public String getPortHeader() {
+ return portHeader;
+ }
+
public String getProtocolHeaderHttpsValue() {
return protocolHeaderHttpsValue;
}
setProtocolHeaderHttpsValue(filterConfig.getInitParameter(PROTOCOL_HEADER_HTTPS_VALUE_PARAMETER));
}
+ if (filterConfig.getInitParameter(PORT_HEADER_PARAMETER) != null) {
+ setPortHeader(filterConfig.getInitParameter(PORT_HEADER_PARAMETER));
+ }
+
+ if (filterConfig.getInitParameter(CHANGE_LOCAL_PORT_PARAMETER) != null) {
+ setChangeLocalPort(Boolean.parseBoolean(filterConfig.getInitParameter(CHANGE_LOCAL_PORT_PARAMETER)));
+ }
+
if (filterConfig.getInitParameter(PROXIES_HEADER_PARAMETER) != null) {
setProxiesHeader(filterConfig.getInitParameter(PROXIES_HEADER_PARAMETER));
}
/**
* <p>
+ * If <code>true</code>, the return values for both {@link
+ * ServletRequest#getLocalPort()} and {@link ServletRequest#getServerPort()}
+ * wil be modified by this Filter rather than just
+ * {@link ServletRequest#getServerPort()}.
+ * </p>
+ * <p>
+ * Default value : <code>false</code>
+ * </p>
+ */
+ public void setChangeLocalPort(boolean changeLocalPort) {
+ this.changeLocalPort = changeLocalPort;
+ }
+
+ /**
+ * <p>
* Server Port value if the {@link #protocolHeader} indicates HTTP (i.e. {@link #protocolHeader} is not null and
* has a value different of {@link #protocolHeaderHttpsValue}).
* </p>
/**
* <p>
+ * Header that holds the incoming port, usally named
+ * <code>X-Forwarded-Port</code>. If <code>null</code>,
+ * {@link #httpServerPort} or {@link #httpsServerPort} will be used.
+ * </p>
+ * <p>
+ * Default value : <code>null</code>
+ * </p>
+ */
+ public void setPortHeader(String portHeader) {
+ this.portHeader = portHeader;
+ }
+
+ /**
+ * <p>
* Header that holds the incoming protocol, usally named <code>X-Forwarded-Proto</code>. If <code>null</code>, request.scheme and
* request.secure will not be modified.
* </p>
default of <code>null</code> is used.</p>
</attribute>
+ <attribute name="portHeader" required="false">
+ <p>Name of the HTTP Header read by this valve that holds the port
+ used by the client to connect to the proxy. If not specified, the
+ default of <code>null</code> is used.</p>
+ </attribute>
+
<attribute name="protocolHeaderHttpsValue" required="false">
<p>Value of the <strong>protocolHeader</strong> to indicate that it is
an HTTPS request. If not specified, the default of <code>https</code> is
</attribute>
<attribute name="httpServerPort" required="false">
- <p>Value returned by <code>ServletRequest.getServerPort()</code>
- when the <strong>protocolHeader</strong> indicates <code>http</code>
- protocol. If not specified, the default of <code>80</code> is
- used.</p>
+ <p>Value returned by <code>ServletRequest.getServerPort()</code>
+ when the <strong>protocolHeader</strong> indicates <code>http</code>
+ protocol and no <strong>portHeader</strong> is present. If not
+ specified, the default of <code>80</code> is used.</p>
</attribute>
<attribute name="httpsServerPort" required="false">
- <p>Value returned by <code>ServletRequest.getServerPort()</code>
- when the <strong>protocolHeader</strong> indicates <code>https</code>
- protocol. If not specified, the default of <code>443</code> is
- used.</p>
+ <p>Value returned by <code>ServletRequest.getServerPort()</code>
+ when the <strong>protocolHeader</strong> indicates <code>https</code>
+ protocol and no <strong>portHeader</strong> is present. If not
+ specified, the default of <code>443</code> is used.</p>
+ </attribute>
+
+ <attribute name="changeLocalPort" required="false">
+ <p>If <code>true</code>, the value returned by
+ <code>ServletRequest.getLocalPort()</code> and
+ <code>ServletRequest.getServerPort()</code> is modified by the this
+ filter. If not specified, the default of <code>false</code> is used.</p>
</attribute>
</attributes>