From 9f3b0223ab7e3159c4794e102f6b5e06dfc8710d Mon Sep 17 00:00:00 2001
From: Greg Wilkins <gregw@webtide.com>
Date: Wed, 8 May 2019 14:00:58 +0200
Subject: [PATCH] Issue #3630 Forwarded-Port

reformatted code
Avoid updating handles unless configuration is changed.

Signed-off-by: Greg Wilkins <gregw@webtide.com>
---
 .../server/ForwardedRequestCustomizer.java    | 216 ++++++++++--------
 1 file changed, 117 insertions(+), 99 deletions(-)

diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java
index 1e64892cbe9..be3990794ed 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java
@@ -43,7 +43,9 @@
 
 
 /* ------------------------------------------------------------ */
-/** Customize Requests for Proxy Forwarding.
+
+/**
+ * Customize Requests for Proxy Forwarding.
  * <p>
  * This customizer looks at at HTTP request for headers that indicate
  * it has been forwarded by one or more proxies.  Specifically handled are
@@ -59,7 +61,8 @@
  * so that the proxy is not seen as the other end point of the connection on which
  * the request came</p>
  * <p>Headers can also be defined so that forwarded SSL Session IDs and Cipher
- * suites may be customised</p> 
+ * suites may be customised</p>
+ *
  * @see <a href="http://en.wikipedia.org/wiki/X-Forwarded-For">Wikipedia: X-Forwarded-For</a>
  */
 public class ForwardedRequestCustomizer implements Customizer
@@ -76,9 +79,9 @@
     private String _forwardedHttpsHeader = "X-Proxied-Https";
     private String _forwardedCipherSuiteHeader = "Proxy-auth-cert";
     private String _forwardedSslSessionIdHeader = "Proxy-ssl-id";
-    private boolean _proxyAsAuthority=false;
-    private boolean _sslIsSecure=true;
-    private Trie <MethodHandle> _handles;
+    private boolean _proxyAsAuthority = false;
+    private boolean _sslIsSecure = true;
+    private Trie<MethodHandle> _handles;
 
     public ForwardedRequestCustomizer()
     {
@@ -97,7 +100,7 @@ public boolean getProxyAsAuthority()
 
     /**
      * @param proxyAsAuthority if true, use the proxy address obtained via
-     * {@code X-Forwarded-Server} or RFC7239 "by" as the request authority.
+     *                         {@code X-Forwarded-Server} or RFC7239 "by" as the request authority.
      */
     public void setProxyAsAuthority(boolean proxyAsAuthority)
     {
@@ -114,49 +117,47 @@ public void setForwardedOnly(boolean rfc7239only)
     {
         if (rfc7239only)
         {
-            if (_forwardedHeader==null)
-                _forwardedHeader=HttpHeader.FORWARDED.toString();
-            _forwardedHostHeader=null;
-            _forwardedServerHeader=null;
-            _forwardedForHeader=null;
-            _forwardedPortHeader=null;
-            _forwardedProtoHeader=null;
-            _forwardedHttpsHeader=null;
+            if (_forwardedHeader == null)
+                _forwardedHeader = HttpHeader.FORWARDED.toString();
+            _forwardedHostHeader = null;
+            _forwardedServerHeader = null;
+            _forwardedForHeader = null;
+            _forwardedPortHeader = null;
+            _forwardedProtoHeader = null;
+            _forwardedHttpsHeader = null;
         }
         else
         {
-            if (_forwardedHostHeader==null)
+            if (_forwardedHostHeader == null)
                 _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString();
-            if (_forwardedServerHeader==null)
+            if (_forwardedServerHeader == null)
                 _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString();
-            if (_forwardedForHeader==null)
+            if (_forwardedForHeader == null)
                 _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString();
-            if (_forwardedPortHeader==null)
+            if (_forwardedPortHeader == null)
                 _forwardedPortHeader = HttpHeader.X_FORWARDED_PORT.toString();
-            if (_forwardedProtoHeader==null)
+            if (_forwardedProtoHeader == null)
                 _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString();
-            if (_forwardedHttpsHeader==null)
+            if (_forwardedHttpsHeader == null)
                 _forwardedHttpsHeader = "X-Proxied-Https";
         }
 
         updateHandles();
     }
-    
+
     public String getForcedHost()
     {
         return _forcedHost.getValue();
     }
-    
+
     /**
      * Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
      *
-     * @param hostAndPort
-     *            The value of the host header to force.
+     * @param hostAndPort The value of the host header to force.
      */
     public void setForcedHost(String hostAndPort)
     {
         _forcedHost = new HostPortHttpField(hostAndPort);
-        updateHandles();
     }
 
     /**
@@ -168,13 +169,15 @@ public String getForwardedHeader()
     }
 
     /**
-     * @param forwardedHeader 
-     *            The header name for RFC forwarded (default Forwarded)
+     * @param forwardedHeader The header name for RFC forwarded (default Forwarded)
      */
     public void setForwardedHeader(String forwardedHeader)
     {
-        _forwardedHeader = forwardedHeader;
-        updateHandles();
+        if (_forwardedHeader == null || !_forwardedHeader.equals(forwardedHeader))
+        {
+            _forwardedHeader = forwardedHeader;
+            updateHandles();
+        }
     }
 
     public String getForwardedHostHeader()
@@ -183,13 +186,15 @@ public String getForwardedHostHeader()
     }
 
     /**
-     * @param forwardedHostHeader
-     *            The header name for forwarded hosts (default {@code X-Forwarded-Host})
+     * @param forwardedHostHeader The header name for forwarded hosts (default {@code X-Forwarded-Host})
      */
     public void setForwardedHostHeader(String forwardedHostHeader)
     {
-        _forwardedHostHeader = forwardedHostHeader;
-        updateHandles();
+        if (_forwardedHostHeader == null || !_forwardedHostHeader.equalsIgnoreCase(forwardedHostHeader))
+        {
+            _forwardedHostHeader = forwardedHostHeader;
+            updateHandles();
+        }
     }
 
     /**
@@ -201,13 +206,15 @@ public String getForwardedServerHeader()
     }
 
     /**
-     * @param forwardedServerHeader
-     *            The header name for forwarded server (default {@code X-Forwarded-Server})
+     * @param forwardedServerHeader The header name for forwarded server (default {@code X-Forwarded-Server})
      */
     public void setForwardedServerHeader(String forwardedServerHeader)
     {
-        _forwardedServerHeader = forwardedServerHeader;
-        updateHandles();
+        if (_forwardedServerHeader == null || !_forwardedServerHeader.equalsIgnoreCase(forwardedServerHeader))
+        {
+            _forwardedServerHeader = forwardedServerHeader;
+            updateHandles();
+        }
     }
 
     /**
@@ -219,13 +226,15 @@ public String getForwardedForHeader()
     }
 
     /**
-     * @param forwardedRemoteAddressHeader
-     *            The header name for forwarded for (default {@code X-Forwarded-For})
+     * @param forwardedRemoteAddressHeader The header name for forwarded for (default {@code X-Forwarded-For})
      */
     public void setForwardedForHeader(String forwardedRemoteAddressHeader)
     {
-        _forwardedForHeader = forwardedRemoteAddressHeader;
-        updateHandles();
+        if (_forwardedForHeader == null || !_forwardedForHeader.equalsIgnoreCase(forwardedRemoteAddressHeader))
+        {
+            _forwardedForHeader = forwardedRemoteAddressHeader;
+            updateHandles();
+        }
     }
 
     public String getForwardedPortHeader()
@@ -234,13 +243,15 @@ public String getForwardedPortHeader()
     }
 
     /**
-     * @param forwardedPortHeader
-     *            The header name for forwarded hosts (default {@code X-Forwarded-Port})
+     * @param forwardedPortHeader The header name for forwarded hosts (default {@code X-Forwarded-Port})
      */
     public void setForwardedPortHeader(String forwardedPortHeader)
     {
-        _forwardedHostHeader = forwardedPortHeader;
-        updateHandles();
+        if (_forwardedHostHeader == null || !_forwardedHostHeader.equalsIgnoreCase(forwardedPortHeader))
+        {
+            _forwardedHostHeader = forwardedPortHeader;
+            updateHandles();
+        }
     }
 
     /**
@@ -256,13 +267,15 @@ public String getForwardedProtoHeader()
     /**
      * Set the forwardedProtoHeader.
      *
-     * @param forwardedProtoHeader
-     *            the forwardedProtoHeader to set (default {@code X-Forwarded-Proto})
+     * @param forwardedProtoHeader the forwardedProtoHeader to set (default {@code X-Forwarded-Proto})
      */
     public void setForwardedProtoHeader(String forwardedProtoHeader)
     {
-        _forwardedProtoHeader = forwardedProtoHeader;
-        updateHandles();
+        if (_forwardedProtoHeader == null || !_forwardedProtoHeader.equalsIgnoreCase(forwardedProtoHeader))
+        {
+            _forwardedProtoHeader = forwardedProtoHeader;
+            updateHandles();
+        }
     }
 
     /**
@@ -274,13 +287,15 @@ public String getForwardedCipherSuiteHeader()
     }
 
     /**
-     * @param forwardedCipherSuite
-     *            The header name holding a forwarded cipher suite (default {@code Proxy-auth-cert})
+     * @param forwardedCipherSuiteHeader The header name holding a forwarded cipher suite (default {@code Proxy-auth-cert})
      */
-    public void setForwardedCipherSuiteHeader(String forwardedCipherSuite)
+    public void setForwardedCipherSuiteHeader(String forwardedCipherSuiteHeader)
     {
-        _forwardedCipherSuiteHeader = forwardedCipherSuite;
-        updateHandles();
+        if (_forwardedCipherSuiteHeader == null || !_forwardedCipherSuiteHeader.equalsIgnoreCase(forwardedCipherSuiteHeader))
+        {
+            _forwardedCipherSuiteHeader = forwardedCipherSuiteHeader;
+            updateHandles();
+        }
     }
 
     /**
@@ -292,13 +307,15 @@ public String getForwardedSslSessionIdHeader()
     }
 
     /**
-     * @param forwardedSslSessionId
-     *            The header name holding a forwarded SSL Session ID (default {@code Proxy-ssl-id})
+     * @param forwardedSslSessionIdHeader The header name holding a forwarded SSL Session ID (default {@code Proxy-ssl-id})
      */
-    public void setForwardedSslSessionIdHeader(String forwardedSslSessionId)
+    public void setForwardedSslSessionIdHeader(String forwardedSslSessionIdHeader)
     {
-        _forwardedSslSessionIdHeader = forwardedSslSessionId;
-        updateHandles();
+        if (_forwardedSslSessionIdHeader == null || !_forwardedSslSessionIdHeader.equalsIgnoreCase(forwardedSslSessionIdHeader))
+        {
+            _forwardedSslSessionIdHeader = forwardedSslSessionIdHeader;
+            updateHandles();
+        }
     }
 
     /**
@@ -314,10 +331,13 @@ public String getForwardedHttpsHeader()
      */
     public void setForwardedHttpsHeader(String forwardedHttpsHeader)
     {
-        _forwardedHttpsHeader = forwardedHttpsHeader;
-        updateHandles();
+        if (_forwardedHttpsHeader == null || !_forwardedHttpsHeader.equalsIgnoreCase(forwardedHttpsHeader))
+        {
+            _forwardedHttpsHeader = forwardedHttpsHeader;
+            updateHandles();
+        }
     }
-    
+
     /**
      * @return true if the presence of a SSL session or certificate header is sufficient
      * to indicate a secure request (default is true)
@@ -329,7 +349,7 @@ public boolean isSslIsSecure()
 
     /**
      * @param sslIsSecure true if the presence of a SSL session or certificate header is sufficient
-     * to indicate a secure request (default is true)
+     *                    to indicate a secure request (default is true)
      */
     public void setSslIsSecure(boolean sslIsSecure)
     {
@@ -362,13 +382,13 @@ public void customize(Connector connector, HttpConfiguration config, Request req
         {
             // Update host header
             httpFields.put(_forcedHost);
-            request.setAuthority(_forcedHost.getHost(),_forcedHost.getPort());
+            request.setAuthority(_forcedHost.getHost(), _forcedHost.getPort());
         }
-        else if (forwarded._rfc7239!=null && forwarded._rfc7239._host!=null)
+        else if (forwarded._rfc7239 != null && forwarded._rfc7239._host != null)
         {
             HostPortHttpField auth = forwarded._rfc7239._host;
             httpFields.put(auth);
-            request.setAuthority(auth.getHost(),auth.getPort());
+            request.setAuthority(auth.getHost(), auth.getPort());
         }
         else if (forwarded._forwardedHost != null)
         {
@@ -378,26 +398,26 @@ else if (forwarded._forwardedHost != null)
         }
         else if (_proxyAsAuthority)
         {
-            if (forwarded._rfc7239!=null && forwarded._rfc7239._by!=null)
+            if (forwarded._rfc7239 != null && forwarded._rfc7239._by != null)
             {
                 HostPortHttpField auth = forwarded._rfc7239._by;
                 httpFields.put(auth);
-                request.setAuthority(auth.getHost(),auth.getPort());
+                request.setAuthority(auth.getHost(), auth.getPort());
             }
             else if (forwarded._forwardedServer != null)
             {
-                request.setAuthority(forwarded._forwardedServer,request.getServerPort());
+                request.setAuthority(forwarded._forwardedServer, request.getServerPort());
             }
         }
 
         // handle remote end identifier
-        if (forwarded._rfc7239!=null && forwarded._rfc7239._for!=null)
+        if (forwarded._rfc7239 != null && forwarded._rfc7239._for != null)
         {
-            request.setRemoteAddr(InetSocketAddress.createUnresolved(forwarded._rfc7239._for.getHost(),forwarded._rfc7239._for.getPort()));
+            request.setRemoteAddr(InetSocketAddress.createUnresolved(forwarded._rfc7239._for.getHost(), forwarded._rfc7239._for.getPort()));
         }
         else if (forwarded._forwardedFor != null)
         {
-            int port = (forwarded._forwardedPort>0)
+            int port = (forwarded._forwardedPort > 0)
                 ? forwarded._forwardedPort
                 : (forwarded._forwardedFor.getPort() > 0)
                 ? forwarded._forwardedFor.getPort()
@@ -406,7 +426,7 @@ else if (forwarded._forwardedFor != null)
         }
 
         // handle protocol identifier
-        if (forwarded._rfc7239!=null && forwarded._rfc7239._proto!=null)
+        if (forwarded._rfc7239 != null && forwarded._rfc7239._proto != null)
         {
             request.setScheme(forwarded._rfc7239._proto);
             if (forwarded._rfc7239._proto.equals(config.getSecureScheme()))
@@ -418,7 +438,7 @@ else if (forwarded._forwardedProto != null)
             if (forwarded._forwardedProto.equals(config.getSecureScheme()))
                 request.setSecure(true);
         }
-        else if (forwarded._forwardedHttps !=null && ("on".equalsIgnoreCase(forwarded._forwardedHttps)||"true".equalsIgnoreCase(forwarded._forwardedHttps)))
+        else if (forwarded._forwardedHttps != null && ("on".equalsIgnoreCase(forwarded._forwardedHttps) || "true".equalsIgnoreCase(forwarded._forwardedHttps)))
         {
             request.setScheme(HttpScheme.HTTPS.asString());
             if (HttpScheme.HTTPS.asString().equals(config.getSecureScheme()))
@@ -441,7 +461,7 @@ protected String getLeftMost(String headerValue)
         }
 
         // The left-most value is the farthest downstream client
-        return headerValue.substring(0,commaIndex).trim();
+        return headerValue.substring(0, commaIndex).trim();
     }
 
     protected HostPort getRemoteAddr(String headerValue)
@@ -463,11 +483,11 @@ protected HostPort getRemoteAddr(String headerValue)
             return null;
         }
     }
-    
+
     @Override
     public String toString()
     {
-        return String.format("%s@%x",this.getClass().getSimpleName(),hashCode());
+        return String.format("%s@%x", this.getClass().getSimpleName(), hashCode());
     }
 
     @Deprecated
@@ -475,12 +495,11 @@ public String getHostHeader()
     {
         return _forcedHost.getValue();
     }
-    
+
     /**
      * Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
      *
-     * @param hostHeader
-     *            The value of the host header to force.
+     * @param hostHeader The value of the host header to force.
      */
     @Deprecated
     public void setHostHeader(String hostHeader)
@@ -494,7 +513,7 @@ public void setHostHeader(String hostHeader)
         HostPortHttpField _for;
         HostPortHttpField _host;
         String _proto;
-        
+
         private RFC7239()
         {
             super(false);
@@ -503,27 +522,27 @@ private RFC7239()
         @Override
         protected void parsedParam(StringBuffer buffer, int valueLength, int paramName, int paramValue)
         {
-            if (valueLength==0 && paramValue>paramName)
+            if (valueLength == 0 && paramValue > paramName)
             {
-                String name=StringUtil.asciiToLowerCase(buffer.substring(paramName,paramValue-1));
-                String value=buffer.substring(paramValue);
-                switch(name)
+                String name = StringUtil.asciiToLowerCase(buffer.substring(paramName, paramValue - 1));
+                String value = buffer.substring(paramValue);
+                switch (name)
                 {
                     case "by":
-                        if (_by==null && !value.startsWith("_") && !"unknown".equals(value))
-                            _by=new HostPortHttpField(value);
+                        if (_by == null && !value.startsWith("_") && !"unknown".equals(value))
+                            _by = new HostPortHttpField(value);
                         break;
                     case "for":
-                        if (_for==null && !value.startsWith("_") && !"unknown".equals(value))
-                            _for=new HostPortHttpField(value);
+                        if (_for == null && !value.startsWith("_") && !"unknown".equals(value))
+                            _for = new HostPortHttpField(value);
                         break;
                     case "host":
-                        if (_host==null)
-                            _host=new HostPortHttpField(value);
+                        if (_host == null)
+                            _host = new HostPortHttpField(value);
                         break;
                     case "proto":
-                        if (_proto==null)
-                            _proto=value;
+                        if (_proto == null)
+                            _proto = value;
                         break;
                 }
             }
@@ -536,7 +555,7 @@ private void updateHandles()
         MethodHandles.Lookup lookup = MethodHandles.lookup();
         MethodType type = methodType(Void.TYPE, HttpField.class);
 
-        while(true)
+        while (true)
         {
             try
             {
@@ -563,7 +582,7 @@ private void updateHandles()
                     continue;
                 break;
             }
-            catch (NoSuchMethodException|IllegalAccessException e)
+            catch (NoSuchMethodException | IllegalAccessException e)
             {
                 throw new IllegalStateException(e);
             }
@@ -591,7 +610,7 @@ public Forwarded(Request request, HttpConfiguration config)
 
         public void handleCipherSuite(HttpField field)
         {
-            _request.setAttribute("javax.servlet.request.cipher_suite",field.getValue());
+            _request.setAttribute("javax.servlet.request.cipher_suite", field.getValue());
             if (isSslIsSecure())
             {
                 _request.setSecure(true);
@@ -633,6 +652,7 @@ public void handlePort(HttpField field)
         {
             _forwardedPort = field.getIntValue();
         }
+
         public void handleHttps(HttpField field)
         {
             _forwardedHttps = getLeftMost(field.getValue());
@@ -640,11 +660,9 @@ public void handleHttps(HttpField field)
 
         public void handleRFC7239(HttpField field)
         {
-            if (_rfc7239 ==null)
+            if (_rfc7239 == null)
                 _rfc7239 = new RFC7239();
             _rfc7239.addValue(field.getValue());
         }
-
-
     }
 }
