diff options
author | Wojtek Wajerowicz <115081248+wojciech-wajerowicz-sonarsource@users.noreply.github.com> | 2023-11-07 14:16:43 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-11-08 20:02:51 +0000 |
commit | 3c40fffa36a740785892e8963916b07b4a5faed5 (patch) | |
tree | 714de58d7cd7e06ee6847dfde646932b7e7b58c9 /sonar-core/src | |
parent | 6c525fc50c21c84015497eb31ab8ef47aece1e2e (diff) | |
download | sonarqube-3c40fffa36a740785892e8963916b07b4a5faed5.tar.gz sonarqube-3c40fffa36a740785892e8963916b07b4a5faed5.zip |
SONAR-20540 Use proxy settings in DefaultHttpDownloader
Diffstat (limited to 'sonar-core/src')
3 files changed, 67 insertions, 44 deletions
diff --git a/sonar-core/src/it/java/org/sonar/core/util/DefaultHttpDownloaderIT.java b/sonar-core/src/it/java/org/sonar/core/util/DefaultHttpDownloaderIT.java index 63e0afc5520..8c773608d8f 100644 --- a/sonar-core/src/it/java/org/sonar/core/util/DefaultHttpDownloaderIT.java +++ b/sonar-core/src/it/java/org/sonar/core/util/DefaultHttpDownloaderIT.java @@ -55,6 +55,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.sonar.api.utils.HttpDownloader.HttpException; public class DefaultHttpDownloaderIT { @@ -75,13 +76,6 @@ public class DefaultHttpDownloaderIT { if (req.getPath().getPath().contains("/redirect/")) { resp.setCode(303); resp.setValue("Location", "/redirected"); - } else if (req.getPath().getPath().contains("/timeout/")) { - try { - Thread.sleep(500); - writeDefaultResponse(req, resp); - } catch (InterruptedException e) { - throw new IllegalStateException(e); - } } else if (req.getPath().getPath().contains("/gzip/")) { if (!"gzip".equals(req.getValue("Accept-Encoding"))) { throw new IllegalStateException("Should accept gzip"); @@ -92,6 +86,8 @@ public class DefaultHttpDownloaderIT { gzipOutputStream.close(); } else if (req.getPath().getPath().contains("/redirected")) { resp.getPrintStream().append("redirected"); + } else if (req.getPath().getPath().contains("/error")) { + writeErrorResponse(req, resp); } else { writeDefaultResponse(req, resp); } @@ -115,6 +111,11 @@ public class DefaultHttpDownloaderIT { return resp.getPrintStream().append("agent=" + req.getValues("User-Agent").get(0)); } + private static void writeErrorResponse(Request req, Response resp) throws IOException { + resp.setCode(500); + resp.getPrintStream().append("agent=" + req.getValues("User-Agent").get(0)); + } + @AfterClass public static void stopServer() throws IOException { if (null != socketConnection) { @@ -124,11 +125,11 @@ public class DefaultHttpDownloaderIT { @Test(timeout = 10000) public void openStream_network_errors() throws IOException, URISyntaxException { - // non routable address - String url = "http://10.255.255.1"; + // host not accepting connections + String url = "http://127.0.0.1:1"; assertThatThrownBy(() -> { - DefaultHttpDownloader downloader = new DefaultHttpDownloader(mock(Server.class), new MapSettings().asConfig(), 10, 10); + DefaultHttpDownloader downloader = new DefaultHttpDownloader(mock(Server.class), new MapSettings().asConfig()); downloader.openStream(new URI(url)); }) .isInstanceOf(SonarException.class) @@ -147,7 +148,7 @@ public class DefaultHttpDownloaderIT { @Test public void downloadBytes() throws URISyntaxException { byte[] bytes = new DefaultHttpDownloader(mock(Server.class), new MapSettings().asConfig()).readBytes(new URI(baseUrl)); - assertThat(bytes.length).isGreaterThan(10); + assertThat(bytes).hasSizeGreaterThan(10); } @Test @@ -169,22 +170,6 @@ public class DefaultHttpDownloaderIT { } @Test - public void readStringWithTimeout() throws URISyntaxException { - assertThatThrownBy( - () -> new DefaultHttpDownloader(mock(Server.class), new MapSettings().asConfig(), null, 50).readString(new URI(baseUrl + "/timeout/"), StandardCharsets.UTF_8)) - .isEqualToComparingFieldByField(new BaseMatcher<Exception>() { - @Override - public boolean matches(Object ex) { - return ex instanceof SonarException && ((SonarException) ex).getCause() instanceof SocketTimeoutException; - } - - @Override - public void describeTo(Description arg0) { - } - }); - } - - @Test public void downloadToFile() throws URISyntaxException, IOException { File toDir = temporaryFolder.newFolder(); File toFile = new File(toDir, "downloadToFile.txt"); @@ -251,4 +236,11 @@ public class DefaultHttpDownloaderIT { assertThat(description).isEqualTo("http://sonarsource.org"); } + @Test + public void readBytes_whenServerReturnsError_shouldThrow() throws URISyntaxException { + DefaultHttpDownloader downloader = new DefaultHttpDownloader(mock(Server.class), new MapSettings().asConfig()); + URI errorUri = new URI(baseUrl + "/error"); + assertThatThrownBy(() -> downloader.readBytes(errorUri)).isInstanceOf(HttpException.class).hasMessage("Fail to download [" + errorUri + "]. Response code: 500"); + } + } diff --git a/sonar-core/src/main/java/org/sonar/core/config/ProxyProperties.java b/sonar-core/src/main/java/org/sonar/core/config/ProxyProperties.java new file mode 100644 index 00000000000..0dfd0f5c2ad --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/config/ProxyProperties.java @@ -0,0 +1,29 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.config; + +public class ProxyProperties { + + public static final String HTTP_PROXY_USER = "http.proxyUser"; + public static final String HTTP_PROXY_PASSWORD = "http.proxyPassword"; + + private ProxyProperties() { + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/util/DefaultHttpDownloader.java b/sonar-core/src/main/java/org/sonar/core/util/DefaultHttpDownloader.java index 8db9479e61d..fd64bdb5281 100644 --- a/sonar-core/src/main/java/org/sonar/core/util/DefaultHttpDownloader.java +++ b/sonar-core/src/main/java/org/sonar/core/util/DefaultHttpDownloader.java @@ -26,11 +26,11 @@ import java.io.InputStream; import java.net.URI; import java.nio.charset.Charset; import java.util.Optional; -import javax.annotation.Nullable; import javax.inject.Inject; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; +import okhttp3.ResponseBody; import org.apache.commons.io.IOUtils; import org.sonar.api.CoreProperties; import org.sonar.api.config.Configuration; @@ -40,6 +40,8 @@ import org.sonar.api.utils.SonarException; import org.sonarqube.ws.client.OkHttpClientBuilder; import static org.apache.commons.io.FileUtils.copyInputStreamToFile; +import static org.sonar.core.config.ProxyProperties.HTTP_PROXY_PASSWORD; +import static org.sonar.core.config.ProxyProperties.HTTP_PROXY_USER; import static org.sonar.core.util.FileUtils.deleteQuietly; /** @@ -51,28 +53,18 @@ public class DefaultHttpDownloader extends HttpDownloader { private final OkHttpClient client; + @Inject public DefaultHttpDownloader(Server server, Configuration config) { - this(server, config, null, null); - } - - public DefaultHttpDownloader(Server server, Configuration config, @Nullable Integer connectTimeout, @Nullable Integer readTimeout) { - client = buildHttpClient(server, config, connectTimeout, readTimeout); + client = buildHttpClient(server, config); } - private static OkHttpClient buildHttpClient(Server server, Configuration config, @Nullable Integer connectTimeout, - @Nullable Integer readTimeout) { + private static OkHttpClient buildHttpClient(Server server, Configuration config) { OkHttpClientBuilder clientBuilder = new OkHttpClientBuilder() .setFollowRedirects(true) .setUserAgent(getUserAgent(server, config)); - if (connectTimeout != null) { - clientBuilder - .setConnectTimeoutMs(connectTimeout); - } - if (readTimeout != null) { - clientBuilder - .setReadTimeoutMs(readTimeout); - } + clientBuilder.setProxyLogin(config.get(HTTP_PROXY_USER).orElse(null)); + clientBuilder.setProxyPassword(config.get(HTTP_PROXY_PASSWORD).orElse(null)); return clientBuilder.build(); } @@ -144,7 +136,17 @@ public class DefaultHttpDownloader extends HttpDownloader { private Response executeCall(URI uri) throws IOException { Request request = new Request.Builder().url(uri.toURL()).get().build(); - return client.newCall(request).execute(); + Response response = client.newCall(request).execute(); + throwExceptionIfResponseIsNotSuccesful(uri, response); + return response; + } + + private static void throwExceptionIfResponseIsNotSuccesful(URI uri, Response response) throws IOException { + if (!response.isSuccessful()) { + try (ResponseBody responseBody = response.body()) { + throw new HttpException(uri, response.code(), responseBody.string()); + } + } } private static SonarException failToDownload(URI uri, IOException e) { |