You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TomcatConnectors.java 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.app;
  21. import javax.annotation.Nullable;
  22. import org.apache.catalina.connector.Connector;
  23. import org.apache.catalina.startup.Tomcat;
  24. import org.sonar.process.Props;
  25. import static java.lang.String.format;
  26. import static org.sonar.process.ProcessProperties.Property.WEB_HOST;
  27. import static org.sonar.process.ProcessProperties.Property.WEB_HTTP_ACCEPT_COUNT;
  28. import static org.sonar.process.ProcessProperties.Property.WEB_HTTP_MAX_THREADS;
  29. import static org.sonar.process.ProcessProperties.Property.WEB_HTTP_MIN_THREADS;
  30. import static org.sonar.process.ProcessProperties.Property.WEB_HTTP_KEEP_ALIVE_TIMEOUT;
  31. /**
  32. * Configuration of Tomcat connectors
  33. */
  34. class TomcatConnectors {
  35. static final String HTTP_PROTOCOL = "HTTP/1.1";
  36. static final int MAX_HTTP_HEADER_SIZE_BYTES = 48 * 1024;
  37. private static final int MAX_POST_SIZE = -1;
  38. private TomcatConnectors() {
  39. // only static stuff
  40. }
  41. static void configure(Tomcat tomcat, Props props) {
  42. Connector httpConnector = newHttpConnector(props);
  43. tomcat.getService().addConnector(httpConnector);
  44. }
  45. private static Connector newHttpConnector(Props props) {
  46. // Not named "sonar.web.http.port" to keep backward-compatibility
  47. int port = props.valueAsInt("sonar.web.port", 9000);
  48. if (port < 0) {
  49. throw new IllegalStateException(format("HTTP port '%s' is invalid", port));
  50. }
  51. Connector connector = new Connector(HTTP_PROTOCOL);
  52. connector.setURIEncoding("UTF-8");
  53. connector.setProperty("address", props.value(WEB_HOST.getKey(), "0.0.0.0"));
  54. connector.setProperty("socket.soReuseAddress", "true");
  55. // see https://tomcat.apache.org/tomcat-8.5-doc/config/http.html
  56. connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
  57. configurePool(props, connector);
  58. configureCompression(connector);
  59. configureMaxHttpHeaderSize(connector);
  60. connector.setPort(port);
  61. connector.setMaxPostSize(MAX_POST_SIZE);
  62. return connector;
  63. }
  64. /**
  65. * HTTP header must be at least 48kb to accommodate the authentication token used for
  66. * negotiate protocol of windows authentication.
  67. */
  68. private static void configureMaxHttpHeaderSize(Connector connector) {
  69. setConnectorAttribute(connector, "maxHttpHeaderSize", MAX_HTTP_HEADER_SIZE_BYTES);
  70. }
  71. private static void configurePool(Props props, Connector connector) {
  72. connector.setProperty("acceptorThreadCount", String.valueOf(2));
  73. connector.setProperty("minSpareThreads", String.valueOf(props.valueAsInt(WEB_HTTP_MIN_THREADS.getKey(), 5)));
  74. connector.setProperty("maxThreads", String.valueOf(props.valueAsInt(WEB_HTTP_MAX_THREADS.getKey(), 50)));
  75. connector.setProperty("acceptCount", String.valueOf(props.valueAsInt(WEB_HTTP_ACCEPT_COUNT.getKey(), 25)));
  76. connector.setProperty("keepAliveTimeout", String.valueOf(props.valueAsInt(WEB_HTTP_KEEP_ALIVE_TIMEOUT.getKey(), 60000)));
  77. }
  78. private static void configureCompression(Connector connector) {
  79. connector.setProperty("compression", "on");
  80. connector.setProperty("compressionMinSize", "1024");
  81. connector.setProperty("compressibleMimeType", "text/html,text/xml,text/plain,text/css,application/json,application/javascript,text/javascript");
  82. }
  83. private static void setConnectorAttribute(Connector c, String key, @Nullable Object value) {
  84. if (value != null) {
  85. c.setAttribute(key, value);
  86. }
  87. }
  88. }