import org.sonar.api.rules.XMLRuleParser;
import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
import org.sonar.api.utils.Durations;
-import org.sonar.api.utils.HttpDownloader;
+import org.sonar.core.util.DefaultHttpDownloader;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.UriReader;
import org.sonar.api.utils.internal.TempFolderCleaner;
ThreadLocalDatabaseSessionFactory.class,
new DatabaseSessionProvider(),
ServerMetadataPersister.class,
- HttpDownloader.class,
+ DefaultHttpDownloader.class,
UriReader.class,
ServerIdGenerator.class
);
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.picocontainer.Startable;
-import org.sonar.api.utils.HttpDownloader;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
+import org.sonar.api.utils.HttpDownloader;
import org.sonar.server.platform.DefaultServerFileSystem;
import org.sonar.updatecenter.common.Release;
import org.sonar.updatecenter.common.Version;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.platform.PluginMetadata;
import org.sonar.api.utils.Durations;
-import org.sonar.api.utils.HttpDownloader;
+import org.sonar.core.util.DefaultHttpDownloader;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.UriReader;
import org.sonar.api.utils.internal.TempFolderCleaner;
DefaultServer.class,
new TempFolderProvider(),
TempFolderCleaner.class,
- HttpDownloader.class,
+ DefaultHttpDownloader.class,
UriReader.class,
new FileCacheProvider(),
System2.INSTANCE,
import org.apache.commons.lang.StringUtils;
import org.sonar.api.BatchComponent;
import org.sonar.api.CoreProperties;
-import org.sonar.api.utils.HttpDownloader;
+import org.sonar.core.util.DefaultHttpDownloader;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
+import org.sonar.api.utils.HttpDownloader;
import javax.annotation.Nullable;
private static final String GET = "GET";
private BootstrapProperties props;
- private HttpDownloader.BaseHttpDownloader downloader;
+ private DefaultHttpDownloader.BaseHttpDownloader downloader;
public ServerClient(BootstrapProperties settings, EnvironmentInformation env) {
this.props = settings;
- this.downloader = new HttpDownloader.BaseHttpDownloader(settings.properties(), env.toString());
+ this.downloader = new DefaultHttpDownloader.BaseHttpDownloader(settings.properties(), env.toString());
}
public String getURL() {
import org.slf4j.LoggerFactory;
import org.sonar.api.config.Settings;
import org.sonar.api.measures.MetricFinder;
-import org.sonar.api.utils.HttpDownloader;
import org.sonar.api.utils.MessageException;
import org.sonar.batch.bootstrap.ServerClient;
+import org.sonar.api.utils.HttpDownloader;
import java.net.HttpURLConnection;
import com.google.common.base.Function;
import com.google.common.io.InputSupplier;
-import org.sonar.api.utils.HttpDownloader;
import org.sonar.batch.bootstrap.ServerClient;
import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
+import org.sonar.api.utils.HttpDownloader;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.sonar.api.utils.HttpDownloader;
import org.sonar.batch.bootstrap.ServerClient;
+import org.sonar.api.utils.HttpDownloader;
import java.net.URI;
import java.net.URISyntaxException;
import org.slf4j.Logger;
import org.sonar.api.config.Settings;
import org.sonar.api.measures.MetricFinder;
-import org.sonar.api.utils.HttpDownloader;
import org.sonar.api.utils.MessageException;
import org.sonar.batch.bootstrap.ServerClient;
+import org.sonar.api.utils.HttpDownloader;
import java.net.HttpURLConnection;
import java.net.URI;
<artifactId>bean-matchers</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.simpleframework</groupId>
+ <artifactId>simple</artifactId>
+ <version>4.1.21</version>
+ <scope>test</scope>
+ </dependency>
+
<!--
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.core.util;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.io.ByteStreams;
+import com.google.common.io.CharStreams;
+import com.google.common.io.Files;
+import com.google.common.io.InputSupplier;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.Charsets;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.sonar.api.config.Settings;
+import org.sonar.api.platform.Server;
+import org.sonar.api.utils.HttpDownloader;
+import org.sonar.api.utils.SonarException;
+import org.sonar.api.utils.log.Loggers;
+
+import javax.annotation.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Authenticator;
+import java.net.HttpURLConnection;
+import java.net.PasswordAuthentication;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.URI;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * This component downloads HTTP files
+ *
+ * @since 2.2
+ */
+public class DefaultHttpDownloader extends HttpDownloader {
+ public static final int TIMEOUT_MILLISECONDS = 20 * 1000;
+
+ private final BaseHttpDownloader downloader;
+ private final Integer readTimeout;
+
+ public DefaultHttpDownloader(Server server, Settings settings) {
+ this(server, settings, null);
+ }
+
+ public DefaultHttpDownloader(Server server, Settings settings, @Nullable Integer readTimeout) {
+ this.readTimeout = readTimeout;
+ downloader = new BaseHttpDownloader(settings.getProperties(), server.getVersion());
+ }
+
+ public DefaultHttpDownloader(Settings settings) {
+ this(settings, null);
+ }
+
+ public DefaultHttpDownloader(Settings settings, @Nullable Integer readTimeout) {
+ this.readTimeout = readTimeout;
+ downloader = new BaseHttpDownloader(settings.getProperties(), null);
+ }
+
+ @Override
+ protected String description(URI uri) {
+ return String.format("%s (%s)", uri.toString(), getProxySynthesis(uri));
+ }
+
+ @Override
+ protected String[] getSupportedSchemes() {
+ return new String[] {"http", "https"};
+ }
+
+ @Override
+ protected byte[] readBytes(URI uri) {
+ return download(uri);
+ }
+
+ @Override
+ protected String readString(URI uri, Charset charset) {
+ try {
+ return CharStreams.toString(CharStreams.newReaderSupplier(downloader.newInputSupplier(uri, this.readTimeout), charset));
+ } catch (IOException e) {
+ throw failToDownload(uri, e);
+ }
+ }
+
+ @Override
+ public String downloadPlainText(URI uri, String encoding) {
+ return readString(uri, Charset.forName(encoding));
+ }
+
+ @Override
+ public byte[] download(URI uri) {
+ try {
+ return ByteStreams.toByteArray(downloader.newInputSupplier(uri, this.readTimeout));
+ } catch (IOException e) {
+ throw failToDownload(uri, e);
+ }
+ }
+
+ public String getProxySynthesis(URI uri) {
+ return downloader.getProxySynthesis(uri);
+ }
+
+ @Override
+ public InputStream openStream(URI uri) {
+ try {
+ return downloader.newInputSupplier(uri, this.readTimeout).getInput();
+ } catch (IOException e) {
+ throw failToDownload(uri, e);
+ }
+ }
+
+ @Override
+ public void download(URI uri, File toFile) {
+ try {
+ Files.copy(downloader.newInputSupplier(uri, this.readTimeout), toFile);
+ } catch (IOException e) {
+ FileUtils.deleteQuietly(toFile);
+ throw failToDownload(uri, e);
+ }
+ }
+
+ private SonarException failToDownload(URI uri, IOException e) {
+ throw new SonarException(String.format("Fail to download: %s (%s)", uri, getProxySynthesis(uri)), e);
+ }
+
+ public static class BaseHttpDownloader {
+
+ private static final String GET = "GET";
+ private static final String HTTP_PROXY_USER = "http.proxyUser";
+ private static final String HTTP_PROXY_PASSWORD = "http.proxyPassword";
+
+ private static final List<String> PROXY_SETTINGS = ImmutableList.of(
+ "http.proxyHost", "http.proxyPort", "http.nonProxyHosts",
+ "http.auth.ntlm.domain", "socksProxyHost", "socksProxyPort");
+
+ private String userAgent;
+
+ public BaseHttpDownloader(Map<String, String> settings, @Nullable String userAgent) {
+ initProxy(settings);
+ initUserAgent(userAgent);
+ }
+
+ private void initProxy(Map<String, String> settings) {
+ propagateProxySystemProperties(settings);
+ if (requiresProxyAuthentication(settings)) {
+ registerProxyCredentials(settings);
+ }
+ }
+
+ private void initUserAgent(@Nullable String sonarVersion) {
+ userAgent = (sonarVersion == null ? "SonarQube" : String.format("SonarQube %s", sonarVersion));
+ System.setProperty("http.agent", userAgent);
+ }
+
+ private String getProxySynthesis(URI uri) {
+ return getProxySynthesis(uri, ProxySelector.getDefault());
+ }
+
+ @VisibleForTesting
+ static String getProxySynthesis(URI uri, ProxySelector proxySelector) {
+ List<Proxy> proxies = proxySelector.select(uri);
+ if (proxies.size() == 1 && proxies.get(0).type().equals(Proxy.Type.DIRECT)) {
+ return "no proxy";
+ }
+
+ List<String> descriptions = Lists.newArrayList();
+ for (Proxy proxy : proxies) {
+ if (proxy.type() != Proxy.Type.DIRECT) {
+ descriptions.add(proxy.type() + " proxy: " + proxy.address());
+ }
+ }
+
+ return Joiner.on(", ").join(descriptions);
+ }
+
+ private void registerProxyCredentials(Map<String, String> settings) {
+ Authenticator.setDefault(new ProxyAuthenticator(
+ settings.get(HTTP_PROXY_USER),
+ settings.get(HTTP_PROXY_PASSWORD)));
+ }
+
+ private boolean requiresProxyAuthentication(Map<String, String> settings) {
+ return settings.containsKey(HTTP_PROXY_USER);
+ }
+
+ private void propagateProxySystemProperties(Map<String, String> settings) {
+ for (String key : PROXY_SETTINGS) {
+ if (settings.containsKey(key)) {
+ System.setProperty(key, settings.get(key));
+ }
+ }
+ }
+
+ public InputSupplier<InputStream> newInputSupplier(URI uri) {
+ return new HttpInputSupplier(uri, GET, userAgent, null, null, TIMEOUT_MILLISECONDS);
+ }
+
+ public InputSupplier<InputStream> newInputSupplier(URI uri, @Nullable Integer readTimeoutMillis) {
+ return newInputSupplier(uri, GET, readTimeoutMillis);
+ }
+
+ public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, @Nullable Integer readTimeoutMillis) {
+ if (readTimeoutMillis != null) {
+ return new HttpInputSupplier(uri, requestMethod, userAgent, null, null, readTimeoutMillis);
+ }
+ return new HttpInputSupplier(uri, requestMethod, userAgent, null, null, TIMEOUT_MILLISECONDS);
+ }
+
+ public InputSupplier<InputStream> newInputSupplier(URI uri, String login, String password) {
+ return newInputSupplier(uri, GET, login, password);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, String login, String password) {
+ return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, TIMEOUT_MILLISECONDS);
+ }
+
+ public InputSupplier<InputStream> newInputSupplier(URI uri, String login, String password, @Nullable Integer readTimeoutMillis) {
+ return newInputSupplier(uri, GET, login, password, readTimeoutMillis);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, String login, String password, @Nullable Integer readTimeoutMillis) {
+ if (readTimeoutMillis != null) {
+ return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, readTimeoutMillis);
+ }
+ return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, TIMEOUT_MILLISECONDS);
+ }
+
+ private static class HttpInputSupplier implements InputSupplier<InputStream> {
+ private final String login;
+ private final String password;
+ private final URI uri;
+ private final String userAgent;
+ private final int readTimeoutMillis;
+ private final String requestMethod;
+
+ HttpInputSupplier(URI uri, String requestMethod, String userAgent, String login, String password, int readTimeoutMillis) {
+ this.uri = uri;
+ this.requestMethod = requestMethod;
+ this.userAgent = userAgent;
+ this.login = login;
+ this.password = password;
+ this.readTimeoutMillis = readTimeoutMillis;
+ }
+
+ @Override
+ public InputStream getInput() throws IOException {
+ Loggers.get(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri, ProxySelector.getDefault()) + ")");
+
+ HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
+ connection.setRequestMethod(requestMethod);
+ HttpsTrust.INSTANCE.trust(connection);
+
+ // allow both GZip and Deflate (ZLib) encodings
+ connection.setRequestProperty("Accept-Encoding", "gzip");
+ if (!Strings.isNullOrEmpty(login)) {
+ String encoded = Base64.encodeBase64String((login + ":" + password).getBytes(Charsets.UTF_8));
+ connection.setRequestProperty("Authorization", "Basic " + encoded);
+ }
+ connection.setConnectTimeout(TIMEOUT_MILLISECONDS);
+ connection.setReadTimeout(readTimeoutMillis);
+ connection.setUseCaches(true);
+ connection.setInstanceFollowRedirects(true);
+ connection.setRequestProperty("User-Agent", userAgent);
+
+ // establish connection, get response headers
+ connection.connect();
+
+ // obtain the encoding returned by the server
+ String encoding = connection.getContentEncoding();
+
+ int responseCode = connection.getResponseCode();
+ if (responseCode >= 400) {
+ InputStream errorResponse = null;
+ try {
+ errorResponse = connection.getErrorStream();
+ if (errorResponse != null) {
+ String errorResponseContent = IOUtils.toString(errorResponse);
+ throw new HttpException(uri, responseCode, errorResponseContent);
+ }
+ throw new HttpException(uri, responseCode);
+
+ } finally {
+ IOUtils.closeQuietly(errorResponse);
+ }
+ }
+
+ InputStream resultingInputStream;
+ // create the appropriate stream wrapper based on the encoding type
+ if (encoding != null && "gzip".equalsIgnoreCase(encoding)) {
+ resultingInputStream = new GZIPInputStream(connection.getInputStream());
+ } else {
+ resultingInputStream = connection.getInputStream();
+ }
+ return resultingInputStream;
+ }
+ }
+
+ private static class ProxyAuthenticator extends Authenticator {
+ private final PasswordAuthentication auth;
+
+ ProxyAuthenticator(String user, String password) {
+ auth = new PasswordAuthentication(user, password == null ? new char[0] : password.toCharArray());
+ }
+
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return auth;
+ }
+ }
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.core.util;
+
+import javax.net.ssl.*;
+import java.net.HttpURLConnection;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+
+/**
+ * @since 4.0
+ */
+class HttpsTrust {
+
+ static HttpsTrust INSTANCE = new HttpsTrust(new Ssl());
+
+ static class Ssl {
+ SSLSocketFactory newFactory(TrustManager... managers) throws NoSuchAlgorithmException, KeyManagementException {
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, managers, new SecureRandom());
+ return context.getSocketFactory();
+ }
+ }
+
+ private final SSLSocketFactory socketFactory;
+ private final HostnameVerifier hostnameVerifier;
+
+ HttpsTrust(Ssl context) {
+ this.socketFactory = createSocketFactory(context);
+ this.hostnameVerifier = createHostnameVerifier();
+ }
+
+ void trust(HttpURLConnection connection) {
+ if (connection instanceof HttpsURLConnection) {
+ HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
+ httpsConnection.setSSLSocketFactory(socketFactory);
+ httpsConnection.setHostnameVerifier(hostnameVerifier);
+ }
+ }
+
+ /**
+ * Trust all certificates
+ */
+ private SSLSocketFactory createSocketFactory(Ssl context) {
+ try {
+ return context.newFactory(new AlwaysTrustManager());
+ } catch (Exception e) {
+ throw new IllegalStateException("Fail to build SSL factory", e);
+ }
+ }
+
+ /**
+ * Trust all hosts
+ */
+ private HostnameVerifier createHostnameVerifier() {
+ return new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ };
+ }
+
+ static class AlwaysTrustManager implements X509TrustManager {
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType) {
+ // Do not check
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType) {
+ // Do not check
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.core.util;
+
+import com.google.common.base.Charsets;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.DisableOnDebug;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestRule;
+import org.junit.rules.Timeout;
+import org.simpleframework.http.Request;
+import org.simpleframework.http.Response;
+import org.simpleframework.http.core.Container;
+import org.simpleframework.transport.connect.SocketConnection;
+import org.sonar.api.config.Settings;
+import org.sonar.api.platform.Server;
+import org.sonar.api.utils.SonarException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.zip.GZIPOutputStream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DefaultHttpDownloaderTest {
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Rule
+ public TestRule timeout = new DisableOnDebug(Timeout.seconds(5));
+
+ private static SocketConnection socketConnection;
+ private static String baseUrl;
+
+ @BeforeClass
+ public static void startServer() throws IOException {
+ socketConnection = new SocketConnection(new Container() {
+ public void handle(Request req, Response resp) {
+ try {
+ if (req.getPath().getPath().contains("/redirect/")) {
+ resp.setCode(303);
+ resp.add("Location", "/");
+ }
+ else {
+ if (req.getPath().getPath().contains("/timeout/")) {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ if (req.getPath().getPath().contains("/gzip/")) {
+ if (!"gzip".equals(req.getValue("Accept-Encoding"))) {
+ throw new IllegalStateException("Should accept gzip");
+ }
+ resp.set("Content-Encoding", "gzip");
+ GZIPOutputStream gzipOutputStream = new GZIPOutputStream(resp.getOutputStream());
+ gzipOutputStream.write("GZIP response".getBytes());
+ gzipOutputStream.close();
+ }
+ else {
+ resp.getPrintStream().append("agent=" + req.getValues("User-Agent").get(0));
+ }
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ } finally {
+ try {
+ resp.close();
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ });
+ SocketAddress address = socketConnection.connect(new InetSocketAddress(0));
+
+ baseUrl = "http://0.0.0.0:" + ((InetSocketAddress) address).getPort();
+ }
+
+ @AfterClass
+ public static void stopServer() throws IOException {
+ if (null != socketConnection) {
+ socketConnection.close();
+ }
+ }
+
+ @Test
+ public void downloadBytes() throws URISyntaxException {
+ byte[] bytes = new DefaultHttpDownloader(new Settings()).readBytes(new URI(baseUrl));
+ assertThat(bytes.length).isGreaterThan(10);
+ }
+
+ @Test
+ public void readString() throws URISyntaxException {
+ String text = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl), Charsets.UTF_8);
+ assertThat(text.length()).isGreaterThan(10);
+ }
+
+ @Test
+ public void readGzipString() throws URISyntaxException {
+ String text = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl + "/gzip/"), Charsets.UTF_8);
+ assertThat(text).isEqualTo("GZIP response");
+ }
+
+ @Test
+ public void readStringWithDefaultTimeout() throws URISyntaxException {
+ String text = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl + "/timeout/"), Charsets.UTF_8);
+ assertThat(text.length()).isGreaterThan(10);
+ }
+
+ @Test
+ public void readStringWithTimeout() throws URISyntaxException {
+ thrown.expect(new BaseMatcher<Exception>() {
+ @Override
+ public boolean matches(Object ex) {
+ return ex instanceof SonarException && ((SonarException) ex).getCause() instanceof SocketTimeoutException;
+ }
+
+ @Override
+ public void describeTo(Description arg0) {
+ }
+ });
+ new DefaultHttpDownloader(new Settings(), 50).readString(new URI(baseUrl + "/timeout/"), Charsets.UTF_8);
+ }
+
+ @Test
+ public void downloadToFile() throws URISyntaxException, IOException {
+ File toDir = temporaryFolder.newFolder();
+ File toFile = new File(toDir, "downloadToFile.txt");
+
+ new DefaultHttpDownloader(new Settings()).download(new URI(baseUrl), toFile);
+ assertThat(toFile).exists();
+ assertThat(toFile.length()).isGreaterThan(10l);
+ }
+
+ @Test
+ public void shouldNotCreateFileIfFailToDownload() throws Exception {
+ File toDir = temporaryFolder.newFolder();
+ File toFile = new File(toDir, "downloadToFile.txt");
+
+ try {
+ int port = new InetSocketAddress(0).getPort();
+ new DefaultHttpDownloader(new Settings()).download(new URI("http://localhost:" + port), toFile);
+ } catch (SonarException e) {
+ assertThat(toFile).doesNotExist();
+ }
+ }
+
+ @Test
+ public void userAgentIsSonarVersion() throws URISyntaxException, IOException {
+ Server server = mock(Server.class);
+ when(server.getVersion()).thenReturn("2.2");
+
+ InputStream stream = new DefaultHttpDownloader(server, new Settings()).openStream(new URI(baseUrl));
+ Properties props = new Properties();
+ props.load(stream);
+ stream.close();
+
+ assertThat(props.getProperty("agent")).isEqualTo("SonarQube 2.2");
+ }
+
+ @Test
+ public void followRedirect() throws URISyntaxException {
+ String content = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl + "/redirect/"), Charsets.UTF_8);
+ assertThat(content).contains("agent");
+ }
+
+ @Test
+ public void shouldGetDirectProxySynthesis() throws URISyntaxException {
+ ProxySelector proxySelector = mock(ProxySelector.class);
+ when(proxySelector.select(any(URI.class))).thenReturn(Arrays.asList(Proxy.NO_PROXY));
+ assertThat(DefaultHttpDownloader.BaseHttpDownloader.getProxySynthesis(new URI("http://an_url"), proxySelector)).isEqualTo("no proxy");
+ }
+
+ @Test
+ public void shouldGetProxySynthesis() throws URISyntaxException {
+ ProxySelector proxySelector = mock(ProxySelector.class);
+ when(proxySelector.select(any(URI.class))).thenReturn(Arrays.<Proxy>asList(new FakeProxy()));
+ assertThat(DefaultHttpDownloader.BaseHttpDownloader.getProxySynthesis(new URI("http://an_url"), proxySelector)).isEqualTo("HTTP proxy: /123.45.67.89:4040");
+ }
+
+ @Test
+ public void supported_schemes() {
+ assertThat(new DefaultHttpDownloader(new Settings()).getSupportedSchemes()).contains("http");
+ }
+
+ @Test
+ public void uri_description() throws URISyntaxException {
+ String description = new DefaultHttpDownloader(new Settings()).description(new URI("http://sonarsource.org"));
+ assertThat(description).matches("http://sonarsource.org \\(.*\\)");
+ }
+}
+
+class FakeProxy extends Proxy {
+ public FakeProxy() {
+ super(Type.HTTP, new InetSocketAddress("123.45.67.89", 4040));
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.core.util;
+
+import org.junit.Test;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.TrustManager;
+import java.io.IOException;
+import java.net.URL;
+import java.security.KeyManagementException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class HttpsTrustTest {
+ @Test
+ public void trustAllHosts() throws Exception {
+ HttpsURLConnection connection = newHttpsConnection();
+ HttpsTrust.INSTANCE.trust(connection);
+
+ assertThat(connection.getHostnameVerifier()).isNotNull();
+ assertThat(connection.getHostnameVerifier().verify("foo", null)).isTrue();
+ }
+
+ @Test
+ public void singleHostnameVerifier() throws Exception {
+ HttpsURLConnection connection1 = newHttpsConnection();
+ HttpsTrust.INSTANCE.trust(connection1);
+ HttpsURLConnection connection2 = newHttpsConnection();
+ HttpsTrust.INSTANCE.trust(connection2);
+
+ assertThat(connection1.getHostnameVerifier()).isSameAs(connection2.getHostnameVerifier());
+ }
+
+ @Test
+ public void trustAllCerts() throws Exception {
+ HttpsURLConnection connection1 = newHttpsConnection();
+ HttpsTrust.INSTANCE.trust(connection1);
+
+ assertThat(connection1.getSSLSocketFactory()).isNotNull();
+ assertThat(connection1.getSSLSocketFactory().getDefaultCipherSuites()).isNotEmpty();
+ }
+
+ @Test
+ public void singleSslFactory() throws Exception {
+ HttpsURLConnection connection1 = newHttpsConnection();
+ HttpsTrust.INSTANCE.trust(connection1);
+ HttpsURLConnection connection2 = newHttpsConnection();
+ HttpsTrust.INSTANCE.trust(connection2);
+
+ assertThat(connection1.getSSLSocketFactory()).isSameAs(connection2.getSSLSocketFactory());
+ }
+
+ @Test
+ public void testAlwaysTrustManager() throws Exception {
+ HttpsTrust.AlwaysTrustManager manager = new HttpsTrust.AlwaysTrustManager();
+ assertThat(manager.getAcceptedIssuers()).isEmpty();
+ // does nothing
+ manager.checkClientTrusted(null, null);
+ manager.checkServerTrusted(null, null);
+ }
+
+ @Test
+ public void failOnError() throws Exception {
+ HttpsTrust.Ssl context = mock(HttpsTrust.Ssl.class);
+ KeyManagementException cause = new KeyManagementException("foo");
+ when(context.newFactory(any(TrustManager.class))).thenThrow(cause);
+
+ try {
+ new HttpsTrust(context);
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage()).isEqualTo("Fail to build SSL factory");
+ assertThat(e.getCause()).isSameAs(cause);
+ }
+ }
+
+ private HttpsURLConnection newHttpsConnection() throws IOException {
+ return (HttpsURLConnection) new URL("https://localhost").openConnection();
+ }
+}
<artifactId>dbunit</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.simpleframework</groupId>
- <artifactId>simple</artifactId>
- <version>4.1.21</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
*/
package org.sonar.api.batch;
-import com.google.common.collect.Lists;
import org.sonar.api.measures.FormulaData;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.Metric;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Override
public Collection<FormulaData> getChildren() {
- List<FormulaData> result = Lists.newArrayList();
+ List<FormulaData> result = new ArrayList<>();
for (DecoratorContext childContext : decoratorContext.getChildren()) {
result.add(new DefaultFormulaData(childContext));
}
*/
package org.sonar.api.batch;
-import com.google.common.collect.Lists;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.project.MavenProject;
import org.sonar.api.BatchComponent;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
+import java.util.ArrayList;
import java.util.List;
/**
protected URLClassLoader createClassLoader() {
try {
- List<URL> urls = Lists.newArrayList();
+ List<URL> urls = new ArrayList<>();
for (File file : getElements()) {
urls.add(file.toURI().toURL());
}
protected List<File> createElements() {
try {
- List<File> files = Lists.newArrayList();
+ List<File> files = new ArrayList<>();
if (pom.getCompileClasspathElements() != null) {
for (String classPathString : pom.getCompileClasspathElements()) {
files.add(new File(classPathString));
*/
package org.sonar.api.batch;
-import com.google.common.collect.Lists;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.Resource;
import java.util.Arrays;
import java.util.Date;
+import java.util.LinkedList;
import java.util.List;
/**
*/
public TimeMachineQuery setMetrics(List<Metric> metrics) {
this.metrics = metrics;
- this.metricKeys = Lists.newLinkedList();
+ this.metricKeys = new LinkedList<>();
for (Metric metric : this.metrics) {
this.metricKeys.add(metric.getKey());
}
*/
public TimeMachineQuery setMetrics(Metric... metrics) {
this.metrics = Arrays.asList(metrics);
- this.metricKeys = Lists.newLinkedList();
+ this.metricKeys = new LinkedList<>();
for (Metric metric : this.metrics) {
this.metricKeys.add(metric.getKey());
}
@Override
public String toString() {
return new ToStringBuilder(this)
- .append("resource", resource)
- .append("metrics", metrics)
- .append("from", from)
- .append("to", to)
- .toString();
+ .append("resource", resource)
+ .append("metrics", metrics)
+ .append("from", from)
+ .append("to", to)
+ .toString();
}
}
*/
package org.sonar.api.batch.bootstrap;
-import com.google.common.collect.Lists;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
private File baseDir, workDir, buildDir;
private Map<String, String> properties = new HashMap<String, String>();
private ProjectDefinition parent = null;
- private List<ProjectDefinition> subProjects = Lists.newArrayList();
- private List<Object> containerExtensions = Lists.newArrayList();
+ private List<ProjectDefinition> subProjects = new ArrayList<>();
+ private List<Object> containerExtensions = new ArrayList<>();
private ProjectDefinition(Properties p) {
for (Entry<Object, Object> entry : p.entrySet()) {
}
private static List<String> trim(String[] strings) {
- List<String> result = Lists.newArrayList();
+ List<String> result = new ArrayList<>();
for (String s : strings) {
result.add(StringUtils.trim(s));
}
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
public class Checks<C> {
private final ActiveRules activeRules;
private final String repository;
- private final Map<RuleKey, C> checkByRule = Maps.newHashMap();
- private final Map<C, RuleKey> ruleByCheck = Maps.newIdentityHashMap();
+ private final Map<RuleKey, C> checkByRule = new HashMap<>();
+ private final Map<C, RuleKey> ruleByCheck = new IdentityHashMap<>();
Checks(ActiveRules activeRules, String repository) {
this.activeRules = activeRules;
*/
package org.sonar.api.batch.rule.internal;
-import com.google.common.collect.Maps;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.rule.RuleKey;
+import java.util.LinkedHashMap;
import java.util.Map;
/**
*/
public class ActiveRulesBuilder {
- private final Map<RuleKey, NewActiveRule> map = Maps.newLinkedHashMap();
+ private final Map<RuleKey, NewActiveRule> map = new LinkedHashMap<>();
public NewActiveRule create(RuleKey ruleKey) {
return new NewActiveRule(this, ruleKey);
import java.io.StringReader;
import java.util.Calendar;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
private Map<String, String> additionalProperties;
private License(Map<String, String> properties) {
- this.additionalProperties = Maps.newHashMap(properties);
+ this.additionalProperties = new HashMap<>(properties);
product = StringUtils.defaultString(get("Product", properties), get("Plugin", properties));
organization = StringUtils.defaultString(get("Organisation", properties), get("Name", properties));
expirationDate = StringUtils.defaultString(get("Expiration", properties), get("Expires", properties));
import javax.annotation.Nullable;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import static com.google.common.collect.Lists.newArrayList;
-
/**
* Declare a plugin property. Values are available at runtime through the component {@link Settings}.
* <p/>
.propertySetKey(annotation.propertySetKey())
.fields(PropertyFieldDefinition.create(annotation.fields()))
.deprecatedKey(annotation.deprecatedKey());
- List<String> qualifiers = newArrayList();
+ List<String> qualifiers = new ArrayList<>();
if (annotation.project()) {
qualifiers.add(Qualifiers.PROJECT);
}
* @see PropertyDefinition.Builder#subCategory(String)
*/
private String subCategory = "";
- private List<String> onQualifiers = newArrayList();
- private List<String> onlyOnQualifiers = newArrayList();
+ private List<String> onQualifiers = new ArrayList<>();
+ private List<String> onlyOnQualifiers = new ArrayList<>();
private boolean global = true;
private PropertyType type = PropertyType.STRING;
- private List<String> options = newArrayList();
+ private List<String> options = new ArrayList<>();
private boolean multiValues = false;
private String propertySetKey = "";
- private List<PropertyFieldDefinition> fields = newArrayList();
+ private List<PropertyFieldDefinition> fields = new ArrayList<>();
private String deprecatedKey = "";
private boolean hidden = false;
private int index = 999;
package org.sonar.api.config;
import com.google.common.base.Strings;
-import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.BatchComponent;
import org.sonar.api.CoreProperties;
*/
public final class PropertyDefinitions implements BatchComponent, ServerComponent {
- private final Map<String, PropertyDefinition> definitions = Maps.newHashMap();
- private final Map<String, Category> categories = Maps.newHashMap();
- private final Map<String, SubCategory> subcategories = Maps.newHashMap();
+ private final Map<String, PropertyDefinition> definitions = new HashMap<>();
+ private final Map<String, Category> categories = new HashMap<>();
+ private final Map<String, SubCategory> subcategories = new HashMap<>();
// deprecated key -> new key
- private final Map<String, String> deprecatedKeys = Maps.newHashMap();
+ private final Map<String, String> deprecatedKeys = new HashMap<>();
public PropertyDefinitions(Object... components) {
if (components != null) {
import javax.annotation.Nullable;
+import java.util.ArrayList;
import java.util.List;
-import static com.google.common.collect.Lists.newArrayList;
-
/**
* @since 3.3
*/
}
static List<PropertyFieldDefinition> create(PropertyField[] fields) {
- List<PropertyFieldDefinition> definitions = newArrayList();
+ List<PropertyFieldDefinition> definitions = new ArrayList<>();
for (PropertyField field : fields) {
definitions.add(PropertyFieldDefinition.build(field.key())
- .name(field.name())
- .description(field.description())
- .indicativeSize(field.indicativeSize())
- .type(field.type())
- .options(field.options())
- .build()
- );
+ .name(field.name())
+ .description(field.description())
+ .indicativeSize(field.indicativeSize())
+ .type(field.type())
+ .options(field.options())
+ .build()
+ );
}
return definitions;
}
this.description = "";
this.indicativeSize = 20;
this.type = PropertyType.STRING;
- this.options = newArrayList();
+ this.options = new ArrayList<>();
}
public Builder name(String name) {
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Nullable;
+import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
return ArrayUtils.EMPTY_STRING_ARRAY;
}
- List<String> values = Lists.newArrayList();
+ List<String> values = new ArrayList<>();
for (String v : Splitter.on(",").trimResults().split(value)) {
values.add(v.replace("%2C", ","));
}
}
public List<String> getKeysStartingWith(String prefix) {
- List<String> result = Lists.newArrayList();
+ List<String> result = new ArrayList<>();
for (String key : properties.keySet()) {
if (StringUtils.startsWith(key, prefix)) {
result.add(key);
String text = null;
if (values != null) {
- List<String> escaped = Lists.newArrayList();
+ List<String> escaped = new ArrayList<>();
for (String value : values) {
if (null != value) {
escaped.add(value.replace(",", "%2C"));
import com.google.common.annotations.Beta;
import org.sonar.api.ServerExtension;
+import java.util.ArrayList;
import java.util.List;
-import static com.google.common.collect.Lists.newArrayList;
-
/**
* @since 3.6
*/
@Beta
public class Actions implements ServerExtension {
- private final List<Action> actions;
-
- public Actions() {
- actions = newArrayList();
- }
+ private final List<Action> actions = new ArrayList<>();
public Action add(String actionKey) {
Action action = new Action(actionKey);
import java.io.Serializable;
import java.util.*;
-import static com.google.common.collect.Lists.newArrayList;
-
/**
* PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
*
public DefaultIssue addChange(FieldDiffs change) {
if (changes == null) {
- changes = newArrayList();
+ changes = new ArrayList<>();
}
changes.add(change);
return this;
public DefaultIssue addComment(DefaultIssueComment comment) {
if (comments == null) {
- comments = newArrayList();
+ comments = new ArrayList<>();
}
comments.add(comment);
return this;
import com.google.common.annotations.Beta;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
import org.sonar.api.resources.Scopes;
import org.sonar.api.test.MutableTestPlan;
import org.sonar.api.utils.SonarException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.util.LinkedList;
import java.util.List;
/**
private static final List<Metric> METRICS;
static {
- METRICS = Lists.newLinkedList();
+ METRICS = new LinkedList<>();
for (Field field : CoreMetrics.class.getFields()) {
if (!Modifier.isTransient(field.getModifiers()) && Metric.class.isAssignableFrom(field.getType())) {
try {
*/
package org.sonar.api.measures;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.sonar.api.utils.KeyValueFormat;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
}
public Collection<Measure> createMeasures() {
- Collection<Measure> measures = Lists.newArrayList();
+ Collection<Measure> measures = new ArrayList<>();
if (getLinesToCover() > 0) {
measures.add(new Measure(CoreMetrics.LINES_TO_COVER, (double) getLinesToCover()));
measures.add(new Measure(CoreMetrics.UNCOVERED_LINES, (double) (getLinesToCover() - getCoveredLines())));
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.lang.StringUtils;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-
import java.util.ArrayList;
import java.util.List;
private Boolean defaultProfile = Boolean.FALSE;
private String language;
private String parentName;
- private List<ActiveRule> activeRules = Lists.newArrayList();
+ private List<ActiveRule> activeRules = new ArrayList<>();
/**
* @deprecated use the factory method create()
public RulesProfile(String name, String language) {
this.name = name;
this.language = language;
- this.activeRules = Lists.newArrayList();
+ this.activeRules = new ArrayList<>();
}
/**
if (acceptDisabledRules) {
return activeRules;
}
- List<ActiveRule> result = Lists.newArrayList();
+ List<ActiveRule> result = new ArrayList<>();
for (ActiveRule activeRule : activeRules) {
if (activeRule.isEnabled()) {
result.add(activeRule);
* @return the list of active rules for a given severity
*/
public List<ActiveRule> getActiveRules(RulePriority severity) {
- List<ActiveRule> result = Lists.newArrayList();
+ List<ActiveRule> result = new ArrayList<>();
for (ActiveRule activeRule : activeRules) {
if (activeRule.getSeverity().equals(severity) && activeRule.isEnabled()) {
result.add(activeRule);
* Only enabled rules are selected. Disabled rules are excluded.
*/
public List<ActiveRule> getActiveRulesByRepository(String repositoryKey) {
- List<ActiveRule> result = Lists.newArrayList();
+ List<ActiveRule> result = new ArrayList<>();
for (ActiveRule activeRule : activeRules) {
if (repositoryKey.equals(activeRule.getRepositoryKey()) && activeRule.isEnabled()) {
result.add(activeRule);
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
* @return not null list
*/
public static List<java.io.File> toFiles(Collection<InputFile> inputFiles) {
- List<java.io.File> files = Lists.newArrayList();
+ List<java.io.File> files = new ArrayList<>();
for (InputFile inputFile : inputFiles) {
files.add(inputFile.getFile());
}
* For internal and for testing purposes. Please use the FileSystem component to access files.
*/
public static List<InputFile> create(java.io.File basedir, Collection<java.io.File> files) {
- List<InputFile> inputFiles = Lists.newArrayList();
+ List<InputFile> inputFiles = new ArrayList<>();
for (File file : files) {
InputFile inputFile = create(basedir, file);
if (inputFile != null) {
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Lists;
import org.sonar.api.ServerExtension;
import org.sonar.api.task.TaskExtension;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
}
public static final class Builder {
- private List<ResourceType> types = Lists.newArrayList();
+ private List<ResourceType> types = new ArrayList<>();
private ListMultimap<String, String> relations = ArrayListMultimap.create();
private ResourceType root;
*/
package org.sonar.api.scan.filesystem;
-import com.google.common.collect.Lists;
import com.google.common.collect.ObjectArrays;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.BatchComponent;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
+import java.util.ArrayList;
import java.util.List;
/**
private String[] inclusions(String propertyKey) {
String[] patterns = sanitize(settings.getStringArray(propertyKey));
- List<String> list = Lists.newArrayList();
+ List<String> list = new ArrayList<>();
for (String pattern : patterns) {
if (!"**/*".equals(pattern) && !"file:**/*".equals(pattern)) {
list.add(pattern);
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
import org.sonar.api.BatchComponent;
import org.sonar.api.utils.PathUtils;
import javax.annotation.CheckForNull;
import java.io.File;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
}
public List<File> relativeFiles(File dir, List<String> paths) {
- List<File> result = Lists.newArrayList();
+ List<File> result = new ArrayList<>();
for (String path : paths) {
result.add(relativeFile(dir, path));
}
@CheckForNull
public RelativePath relativePath(Collection<File> dirs, File file) {
- List<String> stack = Lists.newArrayList();
+ List<String> stack = new ArrayList<>();
File cursor = file;
while (cursor != null) {
File parentDir = parentDir(dirs, cursor);
@CheckForNull
public String relativePath(File dir, File file) {
- List<String> stack = Lists.newArrayList();
+ List<String> stack = new ArrayList<>();
String dirPath = PathUtils.canonicalPath(dir);
File cursor = file;
while (cursor != null) {
import javax.annotation.CheckForNull;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Date;
import java.util.List;
return null;
}
Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value);
- List<E> result = Lists.newArrayList();
+ List<E> result = new ArrayList<>();
for (String s : values) {
result.add(Enum.valueOf(enumClass, s));
}
import javax.annotation.Nullable;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.List;
import java.util.Set;
return null;
}
Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value);
- List<E> result = Lists.newArrayList();
+ List<E> result = new ArrayList<>();
for (String s : values) {
validate(s, definition);
result.add(Enum.valueOf(enumClass, s));
*/
package org.sonar.api.utils;
-import com.google.common.collect.Lists;
import org.apache.commons.lang.ClassUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
* <code>False</code> only matches public fields.
*/
public static List<Field> getFields(Class clazz, boolean forceAccess) {
- List<Field> result = Lists.newArrayList();
+ List<Field> result = new ArrayList<>();
Class c = clazz;
while (c != null) {
for (Field declaredField : c.getDeclaredFields()) {
if (!Modifier.isPublic(declaredField.getModifiers())) {
if (forceAccess) {
- declaredField.setAccessible(true);//NOSONAR only works from sufficiently privileged code
+ declaredField.setAccessible(true);// NOSONAR only works from sufficiently privileged code
} else {
continue;
}
*/
package org.sonar.api.utils;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.io.ByteStreams;
-import com.google.common.io.CharStreams;
-import com.google.common.io.Files;
-import com.google.common.io.InputSupplier;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.io.Charsets;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
-import org.sonar.api.config.Settings;
-import org.sonar.api.platform.Server;
-import org.sonar.api.utils.log.Loggers;
-
-import javax.annotation.Nullable;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
-import java.net.Authenticator;
-import java.net.HttpURLConnection;
-import java.net.PasswordAuthentication;
-import java.net.Proxy;
-import java.net.ProxySelector;
import java.net.URI;
-import java.nio.charset.Charset;
-import java.util.List;
-import java.util.Map;
-import java.util.zip.GZIPInputStream;
/**
- * This component downloads HTTP files
- *
- * @since 2.2
+ * This component is available in IoC container, so it should be injected through
+ * a constructor parameter. It is available in both batch and server.
*/
-public class HttpDownloader extends UriReader.SchemeProcessor implements BatchComponent, ServerComponent {
- public static final int TIMEOUT_MILLISECONDS = 20 * 1000;
-
- private final BaseHttpDownloader downloader;
- private final Integer readTimeout;
-
- public HttpDownloader(Server server, Settings settings) {
- this(server, settings, null);
- }
-
- public HttpDownloader(Server server, Settings settings, @Nullable Integer readTimeout) {
- this.readTimeout = readTimeout;
- downloader = new BaseHttpDownloader(settings.getProperties(), server.getVersion());
- }
-
- public HttpDownloader(Settings settings) {
- this(settings, null);
- }
-
- public HttpDownloader(Settings settings, @Nullable Integer readTimeout) {
- this.readTimeout = readTimeout;
- downloader = new BaseHttpDownloader(settings.getProperties(), null);
- }
-
- @Override
- String description(URI uri) {
- return String.format("%s (%s)", uri.toString(), getProxySynthesis(uri));
- }
-
- @Override
- String[] getSupportedSchemes() {
- return new String[] {"http", "https"};
- }
-
- @Override
- byte[] readBytes(URI uri) {
- return download(uri);
- }
-
- @Override
- String readString(URI uri, Charset charset) {
- try {
- return CharStreams.toString(CharStreams.newReaderSupplier(downloader.newInputSupplier(uri, this.readTimeout), charset));
- } catch (IOException e) {
- throw failToDownload(uri, e);
- }
- }
-
- public String downloadPlainText(URI uri, String encoding) {
- return readString(uri, Charset.forName(encoding));
- }
-
- public byte[] download(URI uri) {
- try {
- return ByteStreams.toByteArray(downloader.newInputSupplier(uri, this.readTimeout));
- } catch (IOException e) {
- throw failToDownload(uri, e);
- }
- }
-
- public String getProxySynthesis(URI uri) {
- return downloader.getProxySynthesis(uri);
- }
-
- public InputStream openStream(URI uri) {
- try {
- return downloader.newInputSupplier(uri, this.readTimeout).getInput();
- } catch (IOException e) {
- throw failToDownload(uri, e);
- }
- }
-
- public void download(URI uri, File toFile) {
- try {
- Files.copy(downloader.newInputSupplier(uri, this.readTimeout), toFile);
- } catch (IOException e) {
- FileUtils.deleteQuietly(toFile);
- throw failToDownload(uri, e);
- }
- }
-
- private SonarException failToDownload(URI uri, IOException e) {
- throw new SonarException(String.format("Fail to download: %s (%s)", uri, getProxySynthesis(uri)), e);
- }
-
- public static class BaseHttpDownloader {
-
- private static final String GET = "GET";
- private static final String HTTP_PROXY_USER = "http.proxyUser";
- private static final String HTTP_PROXY_PASSWORD = "http.proxyPassword";
-
- private static final List<String> PROXY_SETTINGS = ImmutableList.of(
- "http.proxyHost", "http.proxyPort", "http.nonProxyHosts",
- "http.auth.ntlm.domain", "socksProxyHost", "socksProxyPort");
-
- private String userAgent;
-
- public BaseHttpDownloader(Map<String, String> settings, @Nullable String userAgent) {
- initProxy(settings);
- initUserAgent(userAgent);
- }
-
- private void initProxy(Map<String, String> settings) {
- propagateProxySystemProperties(settings);
- if (requiresProxyAuthentication(settings)) {
- registerProxyCredentials(settings);
- }
- }
-
- private void initUserAgent(@Nullable String sonarVersion) {
- userAgent = (sonarVersion == null ? "SonarQube" : String.format("SonarQube %s", sonarVersion));
- System.setProperty("http.agent", userAgent);
- }
-
- private String getProxySynthesis(URI uri) {
- return getProxySynthesis(uri, ProxySelector.getDefault());
- }
-
- @VisibleForTesting
- static String getProxySynthesis(URI uri, ProxySelector proxySelector) {
- List<Proxy> proxies = proxySelector.select(uri);
- if (proxies.size() == 1 && proxies.get(0).type().equals(Proxy.Type.DIRECT)) {
- return "no proxy";
- }
-
- List<String> descriptions = Lists.newArrayList();
- for (Proxy proxy : proxies) {
- if (proxy.type() != Proxy.Type.DIRECT) {
- descriptions.add(proxy.type() + " proxy: " + proxy.address());
- }
- }
-
- return Joiner.on(", ").join(descriptions);
- }
-
- private void registerProxyCredentials(Map<String, String> settings) {
- Authenticator.setDefault(new ProxyAuthenticator(
- settings.get(HTTP_PROXY_USER),
- settings.get(HTTP_PROXY_PASSWORD)));
- }
-
- private boolean requiresProxyAuthentication(Map<String, String> settings) {
- return settings.containsKey(HTTP_PROXY_USER);
- }
-
- private void propagateProxySystemProperties(Map<String, String> settings) {
- for (String key : PROXY_SETTINGS) {
- if (settings.containsKey(key)) {
- System.setProperty(key, settings.get(key));
- }
- }
- }
-
- public InputSupplier<InputStream> newInputSupplier(URI uri) {
- return new HttpInputSupplier(uri, GET, userAgent, null, null, TIMEOUT_MILLISECONDS);
- }
-
- public InputSupplier<InputStream> newInputSupplier(URI uri, @Nullable Integer readTimeoutMillis) {
- return newInputSupplier(uri, GET, readTimeoutMillis);
- }
-
- public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, @Nullable Integer readTimeoutMillis) {
- if (readTimeoutMillis != null) {
- return new HttpInputSupplier(uri, requestMethod, userAgent, null, null, readTimeoutMillis);
- }
- return new HttpInputSupplier(uri, requestMethod, userAgent, null, null, TIMEOUT_MILLISECONDS);
- }
+public abstract class HttpDownloader extends UriReader.SchemeProcessor implements BatchComponent, ServerComponent {
+ public abstract String downloadPlainText(URI uri, String encoding);
- public InputSupplier<InputStream> newInputSupplier(URI uri, String login, String password) {
- return newInputSupplier(uri, GET, login, password);
- }
-
- /**
- * @since 5.0
- */
- public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, String login, String password) {
- return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, TIMEOUT_MILLISECONDS);
- }
-
- public InputSupplier<InputStream> newInputSupplier(URI uri, String login, String password, @Nullable Integer readTimeoutMillis) {
- return newInputSupplier(uri, GET, login, password, readTimeoutMillis);
- }
-
- /**
- * @since 5.0
- */
- public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, String login, String password, @Nullable Integer readTimeoutMillis) {
- if (readTimeoutMillis != null) {
- return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, readTimeoutMillis);
- }
- return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, TIMEOUT_MILLISECONDS);
- }
-
- private static class HttpInputSupplier implements InputSupplier<InputStream> {
- private final String login;
- private final String password;
- private final URI uri;
- private final String userAgent;
- private final int readTimeoutMillis;
- private final String requestMethod;
-
- HttpInputSupplier(URI uri, String requestMethod, String userAgent, String login, String password, int readTimeoutMillis) {
- this.uri = uri;
- this.requestMethod = requestMethod;
- this.userAgent = userAgent;
- this.login = login;
- this.password = password;
- this.readTimeoutMillis = readTimeoutMillis;
- }
-
- @Override
- public InputStream getInput() throws IOException {
- Loggers.get(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri, ProxySelector.getDefault()) + ")");
-
- HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
- connection.setRequestMethod(requestMethod);
- HttpsTrust.INSTANCE.trust(connection);
+ public abstract byte[] download(URI uri);
- // allow both GZip and Deflate (ZLib) encodings
- connection.setRequestProperty("Accept-Encoding", "gzip");
- if (!Strings.isNullOrEmpty(login)) {
- String encoded = Base64.encodeBase64String((login + ":" + password).getBytes(Charsets.UTF_8));
- connection.setRequestProperty("Authorization", "Basic " + encoded);
- }
- connection.setConnectTimeout(TIMEOUT_MILLISECONDS);
- connection.setReadTimeout(readTimeoutMillis);
- connection.setUseCaches(true);
- connection.setInstanceFollowRedirects(true);
- connection.setRequestProperty("User-Agent", userAgent);
+ public abstract InputStream openStream(URI uri);
- // establish connection, get response headers
- connection.connect();
-
- // obtain the encoding returned by the server
- String encoding = connection.getContentEncoding();
-
- int responseCode = connection.getResponseCode();
- if (responseCode >= 400) {
- InputStream errorResponse = null;
- try {
- errorResponse = connection.getErrorStream();
- if (errorResponse != null) {
- String errorResponseContent = IOUtils.toString(errorResponse);
- throw new HttpException(uri, responseCode, errorResponseContent);
- }
- throw new HttpException(uri, responseCode);
-
- } finally {
- IOUtils.closeQuietly(errorResponse);
- }
- }
-
- InputStream resultingInputStream;
- // create the appropriate stream wrapper based on the encoding type
- if (encoding != null && "gzip".equalsIgnoreCase(encoding)) {
- resultingInputStream = new GZIPInputStream(connection.getInputStream());
- } else {
- resultingInputStream = connection.getInputStream();
- }
- return resultingInputStream;
- }
- }
-
- private static class ProxyAuthenticator extends Authenticator {
- private final PasswordAuthentication auth;
-
- ProxyAuthenticator(String user, String password) {
- auth = new PasswordAuthentication(user, password == null ? new char[0] : password.toCharArray());
- }
-
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- return auth;
- }
- }
- }
+ public abstract void download(URI uri, File toFile);
public static class HttpException extends RuntimeException {
private final URI uri;
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.utils;
-
-import javax.net.ssl.*;
-import java.net.HttpURLConnection;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.cert.X509Certificate;
-
-/**
- * @since 4.0
- */
-class HttpsTrust {
-
- static HttpsTrust INSTANCE = new HttpsTrust(new Ssl());
-
- static class Ssl {
- SSLSocketFactory newFactory(TrustManager... managers) throws NoSuchAlgorithmException, KeyManagementException {
- SSLContext context = SSLContext.getInstance("TLS");
- context.init(null, managers, new SecureRandom());
- return context.getSocketFactory();
- }
- }
-
- private final SSLSocketFactory socketFactory;
- private final HostnameVerifier hostnameVerifier;
-
- HttpsTrust(Ssl context) {
- this.socketFactory = createSocketFactory(context);
- this.hostnameVerifier = createHostnameVerifier();
- }
-
- void trust(HttpURLConnection connection) {
- if (connection instanceof HttpsURLConnection) {
- HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
- httpsConnection.setSSLSocketFactory(socketFactory);
- httpsConnection.setHostnameVerifier(hostnameVerifier);
- }
- }
-
- /**
- * Trust all certificates
- */
- private SSLSocketFactory createSocketFactory(Ssl context) {
- try {
- return context.newFactory(new AlwaysTrustManager());
- } catch (Exception e) {
- throw new IllegalStateException("Fail to build SSL factory", e);
- }
- }
-
- /**
- * Trust all hosts
- */
- private HostnameVerifier createHostnameVerifier() {
- return new HostnameVerifier() {
- @Override
- public boolean verify(String hostname, SSLSession session) {
- return true;
- }
- };
- }
-
- static class AlwaysTrustManager implements X509TrustManager {
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return new X509Certificate[0];
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) {
- // Do not check
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType) {
- // Do not check
- }
- }
-}
return processor;
}
- abstract static class SchemeProcessor {
- abstract String[] getSupportedSchemes();
+ public abstract static class SchemeProcessor {
+ protected abstract String[] getSupportedSchemes();
- abstract byte[] readBytes(URI uri);
+ protected abstract byte[] readBytes(URI uri);
- abstract String readString(URI uri, Charset charset);
+ protected abstract String readString(URI uri, Charset charset);
- abstract String description(URI uri);
+ protected abstract String description(URI uri);
}
}
@Override
- byte[] readBytes(URI uri) {
+ protected byte[] readBytes(URI uri) {
try {
return Files.toByteArray(new File(uri));
} catch (IOException e) {
}
@Override
- String readString(URI uri, Charset charset) {
+ protected String readString(URI uri, Charset charset) {
try {
return Files.toString(new File(uri), charset);
} catch (IOException e) {
}
@Override
- String description(URI uri) {
+ protected String description(URI uri) {
return new File(uri).getAbsolutePath();
}
}
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.System2;
import java.io.File;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
*/
public class Command {
private final String executable;
- private final List<String> arguments = Lists.newArrayList();
- private final List<String> argumentsForLogs = Lists.newArrayList();
+ private final List<String> arguments = new ArrayList<>();
+ private final List<String> argumentsForLogs = new ArrayList<>();
private final Map<String, String> env;
private File directory;
private boolean newShell = false;
public List sort() {
sortNodes();
- List<Object> result = Lists.newArrayList();
+ List<Object> result = new ArrayList<>();
for (Node node : nodes) {
result.add(node.getObject());
}
*/
package org.sonar.api.web;
-import com.google.common.collect.Lists;
+import com.google.common.base.Preconditions;
+import java.util.ArrayList;
import java.util.List;
-import com.google.common.base.Preconditions;
-
/**
* Definition of a filter.
*
private Filter() {
displayAs = LIST;
- criteria = Lists.newArrayList();
- columns = Lists.newArrayList();
+ criteria = new ArrayList<>();
+ columns = new ArrayList<>();
}
/**
*/
package org.sonar.api.utils;
-import com.google.common.collect.Lists;
import org.assertj.core.api.Assertions;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public void shouldBeThreadSafe() throws Exception {
final DateUtils.ThreadSafeDateFormat format = new DateUtils.ThreadSafeDateFormat("yyyy-MM-dd'T'HH:mm:ss,S z");
final Date now = new Date();
- final List<Throwable> throwables = Lists.newArrayList();
+ final List<Throwable> throwables = new ArrayList<>();
final ThreadGroup tg = new ThreadGroup("shouldBeThreadSafe") {
@Override
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.utils;
-
-import com.google.common.base.Charsets;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.DisableOnDebug;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.TestRule;
-import org.junit.rules.Timeout;
-import org.simpleframework.http.Request;
-import org.simpleframework.http.Response;
-import org.simpleframework.http.core.Container;
-import org.simpleframework.transport.connect.SocketConnection;
-import org.sonar.api.config.Settings;
-import org.sonar.api.platform.Server;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.ProxySelector;
-import java.net.SocketAddress;
-import java.net.SocketTimeoutException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Arrays;
-import java.util.Properties;
-import java.util.zip.GZIPOutputStream;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class HttpDownloaderTest {
-
- @Rule
- public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Rule
- public TestRule timeout = new DisableOnDebug(Timeout.seconds(5));
-
- private static SocketConnection socketConnection;
- private static String baseUrl;
-
- @BeforeClass
- public static void startServer() throws IOException {
- socketConnection = new SocketConnection(new Container() {
- public void handle(Request req, Response resp) {
- try {
- if (req.getPath().getPath().contains("/redirect/")) {
- resp.setCode(303);
- resp.add("Location", "/");
- }
- else {
- if (req.getPath().getPath().contains("/timeout/")) {
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- throw new IllegalStateException(e);
- }
- }
- if (req.getPath().getPath().contains("/gzip/")) {
- if (!"gzip".equals(req.getValue("Accept-Encoding"))) {
- throw new IllegalStateException("Should accept gzip");
- }
- resp.set("Content-Encoding", "gzip");
- GZIPOutputStream gzipOutputStream = new GZIPOutputStream(resp.getOutputStream());
- gzipOutputStream.write("GZIP response".getBytes());
- gzipOutputStream.close();
- }
- else {
- resp.getPrintStream().append("agent=" + req.getValues("User-Agent").get(0));
- }
- }
- } catch (IOException e) {
- throw new IllegalStateException(e);
- } finally {
- try {
- resp.close();
- } catch (IOException ignored) {
- }
- }
- }
- });
- SocketAddress address = socketConnection.connect(new InetSocketAddress(0));
-
- baseUrl = "http://0.0.0.0:" + ((InetSocketAddress) address).getPort();
- }
-
- @AfterClass
- public static void stopServer() throws IOException {
- if (null != socketConnection) {
- socketConnection.close();
- }
- }
-
- @Test
- public void downloadBytes() throws URISyntaxException {
- byte[] bytes = new HttpDownloader(new Settings()).readBytes(new URI(baseUrl));
- assertThat(bytes.length).isGreaterThan(10);
- }
-
- @Test
- public void readString() throws URISyntaxException {
- String text = new HttpDownloader(new Settings()).readString(new URI(baseUrl), Charsets.UTF_8);
- assertThat(text.length()).isGreaterThan(10);
- }
-
- @Test
- public void readGzipString() throws URISyntaxException {
- String text = new HttpDownloader(new Settings()).readString(new URI(baseUrl + "/gzip/"), Charsets.UTF_8);
- assertThat(text).isEqualTo("GZIP response");
- }
-
- @Test
- public void readStringWithDefaultTimeout() throws URISyntaxException {
- String text = new HttpDownloader(new Settings()).readString(new URI(baseUrl + "/timeout/"), Charsets.UTF_8);
- assertThat(text.length()).isGreaterThan(10);
- }
-
- @Test
- public void readStringWithTimeout() throws URISyntaxException {
- thrown.expect(new BaseMatcher<Exception>() {
- @Override
- public boolean matches(Object ex) {
- return ex instanceof SonarException && ((SonarException) ex).getCause() instanceof SocketTimeoutException;
- }
-
- @Override
- public void describeTo(Description arg0) {
- }
- });
- new HttpDownloader(new Settings(), 50).readString(new URI(baseUrl + "/timeout/"), Charsets.UTF_8);
- }
-
- @Test
- public void downloadToFile() throws URISyntaxException, IOException {
- File toDir = temporaryFolder.newFolder();
- File toFile = new File(toDir, "downloadToFile.txt");
-
- new HttpDownloader(new Settings()).download(new URI(baseUrl), toFile);
- assertThat(toFile).exists();
- assertThat(toFile.length()).isGreaterThan(10l);
- }
-
- @Test
- public void shouldNotCreateFileIfFailToDownload() throws Exception {
- File toDir = temporaryFolder.newFolder();
- File toFile = new File(toDir, "downloadToFile.txt");
-
- try {
- int port = new InetSocketAddress(0).getPort();
- new HttpDownloader(new Settings()).download(new URI("http://localhost:" + port), toFile);
- } catch (SonarException e) {
- assertThat(toFile).doesNotExist();
- }
- }
-
- @Test
- public void userAgentIsSonarVersion() throws URISyntaxException, IOException {
- Server server = mock(Server.class);
- when(server.getVersion()).thenReturn("2.2");
-
- InputStream stream = new HttpDownloader(server, new Settings()).openStream(new URI(baseUrl));
- Properties props = new Properties();
- props.load(stream);
- stream.close();
-
- assertThat(props.getProperty("agent")).isEqualTo("SonarQube 2.2");
- }
-
- @Test
- public void followRedirect() throws URISyntaxException {
- String content = new HttpDownloader(new Settings()).readString(new URI(baseUrl + "/redirect/"), Charsets.UTF_8);
- assertThat(content).contains("agent");
- }
-
- @Test
- public void shouldGetDirectProxySynthesis() throws URISyntaxException {
- ProxySelector proxySelector = mock(ProxySelector.class);
- when(proxySelector.select(any(URI.class))).thenReturn(Arrays.asList(Proxy.NO_PROXY));
- assertThat(HttpDownloader.BaseHttpDownloader.getProxySynthesis(new URI("http://an_url"), proxySelector)).isEqualTo("no proxy");
- }
-
- @Test
- public void shouldGetProxySynthesis() throws URISyntaxException {
- ProxySelector proxySelector = mock(ProxySelector.class);
- when(proxySelector.select(any(URI.class))).thenReturn(Arrays.<Proxy>asList(new FakeProxy()));
- assertThat(HttpDownloader.BaseHttpDownloader.getProxySynthesis(new URI("http://an_url"), proxySelector)).isEqualTo("HTTP proxy: /123.45.67.89:4040");
- }
-
- @Test
- public void supported_schemes() {
- assertThat(new HttpDownloader(new Settings()).getSupportedSchemes()).contains("http");
- }
-
- @Test
- public void uri_description() throws URISyntaxException {
- String description = new HttpDownloader(new Settings()).description(new URI("http://sonarsource.org"));
- assertThat(description).matches("http://sonarsource.org \\(.*\\)");
- }
-}
-
-class FakeProxy extends Proxy {
- public FakeProxy() {
- super(Type.HTTP, new InetSocketAddress("123.45.67.89", 4040));
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.utils;
-
-import org.junit.Test;
-
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.TrustManager;
-import java.io.IOException;
-import java.net.URL;
-import java.security.KeyManagementException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class HttpsTrustTest {
- @Test
- public void trustAllHosts() throws Exception {
- HttpsURLConnection connection = newHttpsConnection();
- HttpsTrust.INSTANCE.trust(connection);
-
- assertThat(connection.getHostnameVerifier()).isNotNull();
- assertThat(connection.getHostnameVerifier().verify("foo", null)).isTrue();
- }
-
- @Test
- public void singleHostnameVerifier() throws Exception {
- HttpsURLConnection connection1 = newHttpsConnection();
- HttpsTrust.INSTANCE.trust(connection1);
- HttpsURLConnection connection2 = newHttpsConnection();
- HttpsTrust.INSTANCE.trust(connection2);
-
- assertThat(connection1.getHostnameVerifier()).isSameAs(connection2.getHostnameVerifier());
- }
-
- @Test
- public void trustAllCerts() throws Exception {
- HttpsURLConnection connection1 = newHttpsConnection();
- HttpsTrust.INSTANCE.trust(connection1);
-
- assertThat(connection1.getSSLSocketFactory()).isNotNull();
- assertThat(connection1.getSSLSocketFactory().getDefaultCipherSuites()).isNotEmpty();
- }
-
- @Test
- public void singleSslFactory() throws Exception {
- HttpsURLConnection connection1 = newHttpsConnection();
- HttpsTrust.INSTANCE.trust(connection1);
- HttpsURLConnection connection2 = newHttpsConnection();
- HttpsTrust.INSTANCE.trust(connection2);
-
- assertThat(connection1.getSSLSocketFactory()).isSameAs(connection2.getSSLSocketFactory());
- }
-
- @Test
- public void testAlwaysTrustManager() throws Exception {
- HttpsTrust.AlwaysTrustManager manager = new HttpsTrust.AlwaysTrustManager();
- assertThat(manager.getAcceptedIssuers()).isEmpty();
- // does nothing
- manager.checkClientTrusted(null, null);
- manager.checkServerTrusted(null, null);
- }
-
- @Test
- public void failOnError() throws Exception {
- HttpsTrust.Ssl context = mock(HttpsTrust.Ssl.class);
- KeyManagementException cause = new KeyManagementException("foo");
- when(context.newFactory(any(TrustManager.class))).thenThrow(cause);
-
- try {
- new HttpsTrust(context);
- fail();
- } catch (IllegalStateException e) {
- assertThat(e.getMessage()).isEqualTo("Fail to build SSL factory");
- assertThat(e.getCause()).isSameAs(cause);
- }
- }
-
- private HttpsURLConnection newHttpsConnection() throws IOException {
- return (HttpsURLConnection) new URL("https://localhost").openConnection();
- }
-}