]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6855 Increase Tomcat maxHttpHeaderSize to 48kb
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Sun, 27 Sep 2015 12:46:34 +0000 (14:46 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Sun, 27 Sep 2015 12:46:34 +0000 (14:46 +0200)
server/sonar-server/src/main/java/org/sonar/server/app/TomcatConnectors.java
server/sonar-server/src/test/java/org/sonar/server/app/TomcatConnectorsTest.java

index 9f385a111616aa657f07b8c8dc23b21741b1f7e8..f2b82a9018a894dcc594c1eab2da22799830421b 100644 (file)
  */
 package org.sonar.server.app;
 
-import org.apache.catalina.connector.Connector;
-import org.apache.catalina.startup.Tomcat;
-import org.sonar.process.Props;
-
-import javax.annotation.Nullable;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import javax.annotation.Nullable;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.startup.Tomcat;
+import org.sonar.process.Props;
 
 /**
  * Configuration of Tomcat connectors
@@ -42,6 +40,7 @@ class TomcatConnectors {
   public static final int DISABLED_PORT = -1;
   public static final String HTTP_PROTOCOL = "HTTP/1.1";
   public static final String AJP_PROTOCOL = "AJP/1.3";
+  public static final int MAX_HTTP_HEADER_SIZE_BYTES = 48 * 1024;
 
   private TomcatConnectors() {
     // only static stuff
@@ -81,6 +80,7 @@ class TomcatConnectors {
     int port = props.valueAsInt("sonar.web.port", 9000);
     if (port > DISABLED_PORT) {
       connector = newConnector(props, HTTP_PROTOCOL, "http");
+      configureMaxHttpHeaderSize(connector);
       connector.setPort(port);
     }
     return connector;
@@ -106,6 +106,7 @@ class TomcatConnectors {
       connector.setPort(port);
       connector.setSecure(true);
       connector.setScheme("https");
+      configureMaxHttpHeaderSize(connector);
       setConnectorAttribute(connector, "keyAlias", props.value("sonar.web.https.keyAlias"));
       String keyPassword = props.value("sonar.web.https.keyPass", "changeit");
       setConnectorAttribute(connector, "keyPass", keyPassword);
@@ -128,6 +129,14 @@ class TomcatConnectors {
     return connector;
   }
 
+  /**
+   * HTTP header must be at least 48kb  to accommodate the authentication token used for
+   * negotiate protocol of windows authentication.
+   */
+  private static void configureMaxHttpHeaderSize(Connector connector) {
+    setConnectorAttribute(connector, "maxHttpHeaderSize", MAX_HTTP_HEADER_SIZE_BYTES);
+  }
+
   private static Connector newConnector(Props props, String protocol, String scheme) {
     Connector connector = new Connector(protocol);
     connector.setURIEncoding("UTF-8");
index 1b8452ef58a94f07fd5e5fa8325415b30af48cba..2ace07a0ff16b5d4556e925732bb3c3596be311e 100644 (file)
@@ -21,6 +21,9 @@
 package org.sonar.server.app;
 
 import com.google.common.collect.ImmutableMap;
+import java.net.InetAddress;
+import java.util.Map;
+import java.util.Properties;
 import org.apache.catalina.connector.Connector;
 import org.apache.catalina.startup.Tomcat;
 import org.junit.Test;
@@ -28,10 +31,6 @@ import org.mockito.ArgumentMatcher;
 import org.mockito.Mockito;
 import org.sonar.process.Props;
 
-import java.net.InetAddress;
-import java.util.Map;
-import java.util.Properties;
-
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.argThat;
@@ -55,8 +54,7 @@ public class TomcatConnectorsTest {
     TomcatConnectors.configure(tomcat, props);
 
     verify(tomcat).setConnector(argThat(new PropertiesMatcher(
-      ImmutableMap.<String, Object>of("minSpareThreads", 2, "maxThreads", 30, "acceptCount", 20)
-      )));
+      ImmutableMap.<String, Object>of("minSpareThreads", 2, "maxThreads", 30, "acceptCount", 20))));
   }
 
   @Test
@@ -66,8 +64,7 @@ public class TomcatConnectorsTest {
     TomcatConnectors.configure(tomcat, props);
 
     verify(tomcat).setConnector(argThat(new PropertiesMatcher(
-      ImmutableMap.<String, Object>of("minSpareThreads", 5, "maxThreads", 50, "acceptCount", 25)
-      )));
+      ImmutableMap.<String, Object>of("minSpareThreads", 5, "maxThreads", 50, "acceptCount", 25))));
   }
 
   @Test
@@ -121,14 +118,7 @@ public class TomcatConnectorsTest {
 
     TomcatConnectors.configure(tomcat, props);
 
-    verify(tomcat).setConnector(argThat(new ArgumentMatcher<Connector>() {
-      @Override
-      public boolean matches(Object o) {
-        Connector c = (Connector) o;
-        return c.getScheme().equals("https") && c.getPort() == 9443
-          && c.getProperty("clientAuth").equals("false");
-      }
-    }));
+    verifyConnectorProperty(tomcat, "https", "clientAuth", "false");
   }
 
   @Test
@@ -238,44 +228,49 @@ public class TomcatConnectorsTest {
 
   @Test
   public void enable_client_auth() {
-
     Properties p = new Properties();
-
     p.setProperty("sonar.web.port", "-1");
     p.setProperty("sonar.web.https.port", "9443");
     p.setProperty("sonar.web.https.clientAuth", "want");
-
     Props props = new Props(p);
 
     TomcatConnectors.configure(tomcat, props);
 
-    verify(tomcat).setConnector(argThat(new ArgumentMatcher<Connector>() {
-      @Override
-      public boolean matches(Object o) {
-        Connector c = (Connector) o;
-        return c.getScheme().equals("https") && c.getProperty("clientAuth").equals("want");
-      }
-    }));
+    verifyConnectorProperty(tomcat, "https", "clientAuth", "want");
   }
 
   @Test
   public void require_client_auth() {
-
     Properties p = new Properties();
-
     p.setProperty("sonar.web.port", "-1");
     p.setProperty("sonar.web.https.port", "9443");
     p.setProperty("sonar.web.https.clientAuth", "true");
-
     Props props = new Props(p);
 
     TomcatConnectors.configure(tomcat, props);
 
-    verify(tomcat).setConnector(argThat(new ArgumentMatcher<Connector>() {
+    verifyConnectorProperty(tomcat, "https", "clientAuth", "true");
+  }
+
+  @Test
+  public void test_max_http_header_size_for_http_and_https_connections() {
+    Properties properties = new Properties();
+
+    properties.setProperty("sonar.web.https.port", "9443");
+
+    Props props = new Props(properties);
+    TomcatConnectors.configure(tomcat, props);
+    verifyConnectorProperty(tomcat, "http", "maxHttpHeaderSize", TomcatConnectors.MAX_HTTP_HEADER_SIZE_BYTES);
+    verifyConnectorProperty(tomcat, "https", "maxHttpHeaderSize", TomcatConnectors.MAX_HTTP_HEADER_SIZE_BYTES);
+  }
+
+  private static void verifyConnectorProperty(Tomcat tomcat, final String connectorScheme,
+    final String property, final Object propertyValue) {
+    verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
       @Override
       public boolean matches(Object o) {
         Connector c = (Connector) o;
-        return c.getScheme().equals("https") && c.getProperty("clientAuth").equals("true");
+        return c.getScheme().equals(connectorScheme) && c.getProperty(property).equals(propertyValue);
       }
     }));
   }