*/
package org.sonar.core.util;
-
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
-import java.util.Map;
import java.util.zip.GZIPInputStream;
import javax.annotation.Nullable;
import org.apache.commons.codec.binary.Base64;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.log.Loggers;
+import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.sonar.core.util.FileUtils.deleteQuietly;
/**
* @since 2.2
*/
public class DefaultHttpDownloader extends HttpDownloader {
+
private final BaseHttpDownloader downloader;
private final Integer readTimeout;
private final Integer connectTimeout;
public DefaultHttpDownloader(Server server, Settings settings, @Nullable Integer connectTimeout, @Nullable Integer readTimeout) {
this.readTimeout = readTimeout;
this.connectTimeout = connectTimeout;
- downloader = new BaseHttpDownloader(settings.getProperties(), server.getVersion());
+ downloader = new BaseHttpDownloader(new ProxySystem(), settings, server.getVersion());
}
public DefaultHttpDownloader(Settings settings) {
public DefaultHttpDownloader(Settings settings, @Nullable Integer connectTimeout, @Nullable Integer readTimeout) {
this.readTimeout = readTimeout;
this.connectTimeout = connectTimeout;
- downloader = new BaseHttpDownloader(settings.getProperties(), null);
+ downloader = new BaseHttpDownloader(new ProxySystem(), settings, null);
}
@Override
throw new SonarException(String.format("Fail to download: %s (%s)", uri, getProxySynthesis(uri)), e);
}
- public static class BaseHttpDownloader {
+ static class ProxySystem {
+ public void setProperty(String key, String value) {
+ System.setProperty(key, value);
+ }
+
+ public void setDefaultAuthenticator(Authenticator authenticator) {
+ Authenticator.setDefault(authenticator);
+ }
+ }
+
+ static class BaseHttpDownloader {
private static final String GET = "GET";
private static final String HTTP_PROXY_USER = "http.proxyUser";
private String userAgent;
- public BaseHttpDownloader(Map<String, String> settings, @Nullable String userAgent) {
- initProxy(settings);
+ BaseHttpDownloader(ProxySystem system, Settings settings, @Nullable String userAgent) {
+ initProxy(system, settings);
initUserAgent(userAgent);
}
- private void initProxy(Map<String, String> settings) {
- propagateProxySystemProperties(settings);
- if (requiresProxyAuthentication(settings)) {
- registerProxyCredentials(settings);
+ private void initProxy(ProxySystem system, Settings settings) {
+ // propagate system properties
+ for (String key : PROXY_SETTINGS) {
+ if (settings.hasKey(key)) {
+ system.setProperty(key, settings.getString(key));
+ }
+ }
+ // register credentials
+ String login = settings.getString(HTTP_PROXY_USER);
+ if (isNotEmpty(login)) {
+ system.setDefaultAuthenticator(new ProxyAuthenticator(login, settings.getString(HTTP_PROXY_PASSWORD)));
}
}
return Joiner.on(", ").join(descriptions);
}
- private static 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 newInputSupplier(uri, GET, null, null, null, null);
}
return resultingInputStream;
}
}
+ }
- private static class ProxyAuthenticator extends Authenticator {
- private final PasswordAuthentication auth;
+ 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());
- }
+ ProxyAuthenticator(String user, @Nullable String password) {
+ auth = new PasswordAuthentication(user, password == null ? new char[0] : password.toCharArray());
+ }
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- return auth;
- }
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return auth;
}
}
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.net.Authenticator;
import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.util.Arrays;
import java.util.Properties;
import java.util.zip.GZIPOutputStream;
-
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.sonar.api.config.Settings;
import org.sonar.api.platform.Server;
import org.sonar.api.utils.SonarException;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class DefaultHttpDownloaderTest {
String description = new DefaultHttpDownloader(new Settings()).description(new URI("http://sonarsource.org"));
assertThat(description).matches("http://sonarsource.org \\(.*\\)");
}
+
+ @Test
+ public void configure_http_proxy() {
+ DefaultHttpDownloader.ProxySystem system = mock(DefaultHttpDownloader.ProxySystem.class);
+ Settings settings = new Settings();
+ settings.setProperty("http.proxyHost", "1.2.3.4");
+ settings.setProperty("http.proxyPort", "80");
+
+ new DefaultHttpDownloader.BaseHttpDownloader(system, settings, null);
+
+ verify(system).setProperty("http.proxyHost", "1.2.3.4");
+ verify(system).setProperty("http.proxyPort", "80");
+ verify(system, never()).setDefaultAuthenticator(any(Authenticator.class));
+ }
+
+ @Test
+ public void configure_http_proxy_credentials() {
+ DefaultHttpDownloader.ProxySystem system = mock(DefaultHttpDownloader.ProxySystem.class);
+ Settings settings = new Settings();
+ settings.setProperty("https.proxyHost", "1.2.3.4");
+ settings.setProperty("http.proxyUser", "the_login");
+ settings.setProperty("http.proxyPassword", "the_passwd");
+
+ new DefaultHttpDownloader.BaseHttpDownloader(system, settings, null);
+
+ verify(system).setDefaultAuthenticator(argThat(new TypeSafeMatcher<Authenticator>() {
+ @Override
+ protected boolean matchesSafely(Authenticator authenticator) {
+ DefaultHttpDownloader.ProxyAuthenticator a = (DefaultHttpDownloader.ProxyAuthenticator) authenticator;
+ PasswordAuthentication authentication = a.getPasswordAuthentication();
+ return authentication.getUserName().equals("the_login") &&
+ new String(authentication.getPassword()).equals("the_passwd");
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ }
+ }));
+ }
+
}
class FakeProxy extends Proxy {