# Access logs are enabled by default.
#sonar.web.accessLogs.enable=true
-# TCP port for incoming AJP connections. Disabled when value is -1.
-# sonar.ajp.port=9009
-
-
-
#--------------------------------------------------------------------------------------------------
# UPDATE CENTER
# Access logs are enabled by default.
#sonar.web.accessLogs.enable=true
-# TCP port for incoming AJP connections. Disabled when value is -1.
-# sonar.ajp.port=9009
-
-
-
#--------------------------------------------------------------------------------------------------
# UPDATE CENTER
*/
package org.sonar.server.app;
-import static com.google.common.collect.FluentIterable.from;
-import static java.util.Arrays.asList;
-
-import com.google.common.base.Predicates;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.sonar.process.Props;
+import static java.lang.String.format;
+
/**
* Configuration of Tomcat connectors
*/
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 static final int UNDEFINED_PORT = 0;
+ protected static final String HTTP_PROTOCOL = "HTTP/1.1";
+ protected static final int MAX_HTTP_HEADER_SIZE_BYTES = 48 * 1024;
private static final int MAX_POST_SIZE = -1;
private TomcatConnectors() {
}
static void configure(Tomcat tomcat, Props props) {
- List<Connector> connectors = from(asList(newHttpConnector(props), newAjpConnector(props)))
- .filter(Predicates.notNull())
- .toList();
-
- verify(connectors);
-
- tomcat.setConnector(connectors.get(0));
- for (Connector connector : connectors) {
- tomcat.getService().addConnector(connector);
- }
+ Connector httpConnector = newHttpConnector(props);
+ tomcat.setConnector(httpConnector);
+ tomcat.getService().addConnector(httpConnector);
}
- private static void verify(List<Connector> connectors) {
- if (connectors.isEmpty()) {
- throw new IllegalStateException("HTTP connectors are disabled");
- }
- Set<Integer> ports = new HashSet<>();
- for (Connector connector : connectors) {
- int port = connector.getPort();
- if (ports.contains(port)) {
- throw new IllegalStateException(String.format("HTTP and AJP must not use the same port %d", port));
- }
- ports.add(port);
- }
- }
-
- @CheckForNull
private static Connector newHttpConnector(Props props) {
- Connector connector = null;
// Not named "sonar.web.http.port" to keep backward-compatibility
int port = props.valueAsInt("sonar.web.port", 9000);
- if (port > DISABLED_PORT) {
- connector = newConnector(props, HTTP_PROTOCOL, "http");
- configureMaxHttpHeaderSize(connector);
- connector.setPort(port);
- connector.setMaxPostSize(MAX_POST_SIZE);
+ if (port < UNDEFINED_PORT) {
+ throw new IllegalStateException(format("HTTP port '%s' is invalid", port));
}
- return connector;
- }
- @CheckForNull
- private static Connector newAjpConnector(Props props) {
- int port = props.valueAsInt("sonar.ajp.port", DISABLED_PORT);
- if (port > DISABLED_PORT) {
- Connector connector = newConnector(props, AJP_PROTOCOL, "http");
- connector.setPort(port);
- return connector;
- }
- return null;
+ Connector connector = newConnector(props, HTTP_PROTOCOL, "http");
+ configureMaxHttpHeaderSize(connector);
+ connector.setPort(port);
+ connector.setMaxPostSize(MAX_POST_SIZE);
+ return connector;
}
/**
void log(Tomcat tomcat) {
Connector[] connectors = tomcat.getService().findConnectors();
for (Connector connector : connectors) {
- if (StringUtils.containsIgnoreCase(connector.getProtocol(), "AJP")) {
- logAjp(connector);
- } else if (StringUtils.equalsIgnoreCase(connector.getScheme(), "http")) {
+ if (StringUtils.equalsIgnoreCase(connector.getScheme(), "http")) {
logHttp(connector);
} else {
throw new IllegalArgumentException("Unsupported connector: " + connector);
}
}
- private void logAjp(Connector connector) {
- log.info(String.format("%s connector enabled on port %d", connector.getProtocol(), connector.getPort()));
- }
-
private void logHttp(Connector connector) {
log.info(String.format("HTTP connector enabled on port %d", connector.getPort()));
}
*/
package org.sonar.server.app;
-import java.util.Properties;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import org.sonar.api.utils.log.Logger;
-import org.sonar.process.Props;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class StartupLogsTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
- Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
- Logger logger = mock(Logger.class);
- TomcatStartupLogs underTest = new TomcatStartupLogs(logger);
+ private Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
+ private Logger logger = mock(Logger.class);
+ private TomcatStartupLogs underTest = new TomcatStartupLogs(logger);
@Test
- public void logAjp() {
- Connector connector = newConnector("AJP/1.3", "http");
+ public void fail_with_IAE_on_unsupported_protocol() {
+ Connector connector = newConnector("AJP/1.3", "ajp");
when(tomcat.getService().findConnectors()).thenReturn(new Connector[] {connector});
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Unsupported connector: Connector[AJP/1.3-1234]");
+
underTest.log(tomcat);
-
- verify(logger).info("AJP/1.3 connector enabled on port 1234");
- verifyNoMoreInteractions(logger);
}
@Test
*/
package org.sonar.server.app;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
import com.google.common.collect.ImmutableMap;
import java.net.InetAddress;
import java.util.Map;
import org.mockito.Mockito;
import org.sonar.process.Props;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
public class TomcatConnectorsTest {
Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
}
@Test
- public void fail_if_http_connectors_are_disabled() {
- Properties p = new Properties();
- p.setProperty("sonar.web.port", "-1");
- Props props = new Props(p);
-
- try {
- TomcatConnectors.configure(tomcat, props);
- fail();
- } catch (IllegalStateException e) {
- assertThat(e.getMessage()).isEqualTo("HTTP connectors are disabled");
- }
- }
-
- @Test
- public void all_connectors_are_enabled() {
+ public void http_connector_is_enabled() {
Properties p = new Properties();
p.setProperty("sonar.web.port", "9000");
- p.setProperty("sonar.ajp.port", "9009");
Props props = new Props(p);
TomcatConnectors.configure(tomcat, props);
return c.getScheme().equals("http") && c.getPort() == 9000 && c.getProtocol().equals(TomcatConnectors.HTTP_PROTOCOL);
}
}));
- verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
- @Override
- public boolean matches(Object o) {
- Connector c = (Connector) o;
- return c.getScheme().equals("http") && c.getPort() == 9009 && c.getProtocol().equals(TomcatConnectors.AJP_PROTOCOL);
- }
- }));
}
@Test
- public void http_and_ajp_ports_should_be_different() {
+ public void fail_with_ISE_if_http_port_is_invalid() {
Properties p = new Properties();
- p.setProperty("sonar.web.port", "9000");
- p.setProperty("sonar.ajp.port", "9000");
+ p.setProperty("sonar.web.port", "-1");
try {
TomcatConnectors.configure(tomcat, new Props(p));
fail();
} catch (IllegalStateException e) {
- assertThat(e).hasMessage("HTTP and AJP must not use the same port 9000");
+ assertThat(e).hasMessage("HTTP port '-1' is invalid");
}
}
public void bind_to_all_addresses_by_default() {
Properties p = new Properties();
p.setProperty("sonar.web.port", "9000");
- p.setProperty("sonar.ajp.port", "9009");
TomcatConnectors.configure(tomcat, new Props(p));
return c.getScheme().equals("http") && c.getPort() == 9000 && ((InetAddress) c.getProperty("address")).getHostAddress().equals("0.0.0.0");
}
}));
- verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
- @Override
- public boolean matches(Object o) {
- Connector c = (Connector) o;
- return c.getScheme().equals("http") && c.getPort() == 9009 && ((InetAddress) c.getProperty("address")).getHostAddress().equals("0.0.0.0");
- }
- }));
}
@Test
# The default value is 25.
#sonar.web.http.acceptCount=25
-# TCP port for incoming AJP connections. Disabled if value is -1. Disabled by default.
-#sonar.ajp.port=-1
-
# By default users are logged out and sessions closed when server is restarted.
# If you prefer keeping user sessions open, a secret should be defined. Value is
# HS256 key encoded with base64. It must be unique for each installation of SonarQube.