diff options
author | SimonBrandhof <simon.brandhof@gmail.com> | 2013-04-08 14:57:13 +0200 |
---|---|---|
committer | SimonBrandhof <simon.brandhof@gmail.com> | 2013-04-08 14:57:13 +0200 |
commit | 1ed751ab62fc2cb0cac57a409ebef0e0425b6525 (patch) | |
tree | d418672ac0a1f2815d2a2b962f7f63c00dc5f11f /sonar-runner-impl | |
parent | 3df1496b29c383b09ff4a2882620f6b922a7196c (diff) | |
download | sonar-scanner-cli-1ed751ab62fc2cb0cac57a409ebef0e0425b6525.tar.gz sonar-scanner-cli-1ed751ab62fc2cb0cac57a409ebef0e0425b6525.zip |
SONARPLUGINS-2709 Send HTTP credentials
Diffstat (limited to 'sonar-runner-impl')
4 files changed, 125 insertions, 49 deletions
diff --git a/sonar-runner-impl/pom.xml b/sonar-runner-impl/pom.xml index 688bb81..37ffe8d 100644 --- a/sonar-runner-impl/pom.xml +++ b/sonar-runner-impl/pom.xml @@ -12,6 +12,15 @@ <dependencies> <dependency> + <groupId>com.github.kevinsawicki</groupId> + <artifactId>http-request</artifactId> + </dependency> + <dependency> + <groupId>com.google.code.findbugs</groupId> + <artifactId>jsr305</artifactId> + <scope>provided</scope> + </dependency> + <dependency> <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-home</artifactId> </dependency> @@ -21,11 +30,6 @@ <version>${pom.version}</version> <scope>provided</scope> </dependency> - <dependency> - <groupId>com.google.code.findbugs</groupId> - <artifactId>jsr305</artifactId> - <scope>provided</scope> - </dependency> <!-- unit tests --> <dependency> @@ -93,6 +97,12 @@ <configuration> <createDependencyReducedPom>true</createDependencyReducedPom> <minimizeJar>true</minimizeJar> + <relocations> + <relocation> + <pattern>com.github.kevinsawicki.http</pattern> + <shadedPattern>org.sonar.runner.kevinsawicki</shadedPattern> + </relocation> + </relocations> </configuration> </execution> </executions> diff --git a/sonar-runner-impl/src/main/java/org/sonar/runner/impl/ServerConnection.java b/sonar-runner-impl/src/main/java/org/sonar/runner/impl/ServerConnection.java index 3985bff..3ea0f1b 100644 --- a/sonar-runner-impl/src/main/java/org/sonar/runner/impl/ServerConnection.java +++ b/sonar-runner-impl/src/main/java/org/sonar/runner/impl/ServerConnection.java @@ -19,17 +19,12 @@ */ package org.sonar.runner.impl; +import com.github.kevinsawicki.http.HttpRequest; import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; import java.net.ConnectException; -import java.net.HttpURLConnection; import java.net.URL; import java.net.UnknownHostException; import java.util.Properties; @@ -58,70 +53,58 @@ class ServerConnection { } void download(String path, File toFile) { - InputStream input = null; - FileOutputStream output = null; String fullUrl = serverUrl + path; try { Logs.debug("Download " + fullUrl + " to " + toFile.getAbsolutePath()); - HttpURLConnection connection = newHttpConnection(new URL(fullUrl)); - int statusCode = connection.getResponseCode(); - if (statusCode != HttpURLConnection.HTTP_OK) { - throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode); + HttpRequest httpRequest = newHttpRequest(new URL(fullUrl)); + if (!httpRequest.ok()) { + throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + httpRequest.code()); } - output = new FileOutputStream(toFile, false); - input = connection.getInputStream(); - IOUtils.copyLarge(input, output); + httpRequest.receive(toFile); } catch (Exception e) { - if (e instanceof ConnectException || e instanceof UnknownHostException) { + if (e.getCause() instanceof ConnectException || e.getCause() instanceof UnknownHostException) { Logs.error("Sonar server '" + serverUrl + "' can not be reached"); } - IOUtils.closeQuietly(output); FileUtils.deleteQuietly(toFile); throw new IllegalStateException("Fail to download: " + fullUrl, e); - } finally { - IOUtils.closeQuietly(input); - IOUtils.closeQuietly(output); } } String downloadString(String path) throws IOException { String fullUrl = serverUrl + path; - HttpURLConnection conn = newHttpConnection(new URL(fullUrl)); - String charset = getCharsetFromContentType(conn.getContentType()); - if (charset == null || "".equals(charset)) { - charset = "UTF-8"; - } - Reader reader = null; + HttpRequest httpRequest = newHttpRequest(new URL(fullUrl)); try { - int statusCode = conn.getResponseCode(); - if (statusCode != HttpURLConnection.HTTP_OK) { - throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode); + String charset = getCharsetFromContentType(httpRequest.contentType()); + if (charset == null || "".equals(charset)) { + charset = "UTF-8"; + } + if (!httpRequest.ok()) { + throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + httpRequest.code()); } - reader = new InputStreamReader(conn.getInputStream(), charset); - return IOUtils.toString(reader); - } catch (IOException e) { - if (e instanceof ConnectException || e instanceof UnknownHostException) { + return httpRequest.body(charset); + + } catch (HttpRequest.HttpRequestException e) { + if (e.getCause() instanceof ConnectException || e.getCause() instanceof UnknownHostException) { Logs.error("Sonar server '" + serverUrl + "' can not be reached"); } throw e; } finally { - IOUtils.closeQuietly(reader); - conn.disconnect(); + httpRequest.disconnect(); } } - private HttpURLConnection newHttpConnection(URL url) throws IOException { - //TODO send credentials - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setConnectTimeout(CONNECT_TIMEOUT_MILLISECONDS); - connection.setReadTimeout(READ_TIMEOUT_MILLISECONDS); - connection.setInstanceFollowRedirects(true); - connection.setRequestMethod("GET"); - connection.setRequestProperty("User-Agent", userAgent); - return connection; + private HttpRequest newHttpRequest(URL url) { + HttpRequest request = HttpRequest.get(url); + request.trustAllCerts().trustAllHosts(); + request.acceptGzipEncoding().uncompress(true); + request.connectTimeout(CONNECT_TIMEOUT_MILLISECONDS).readTimeout(READ_TIMEOUT_MILLISECONDS); + request.userAgent(userAgent); + + // TODO send credentials + return request; } /** diff --git a/sonar-runner-impl/src/test/java/org/sonar/runner/impl/NetworkUtil.java b/sonar-runner-impl/src/test/java/org/sonar/runner/impl/NetworkUtil.java new file mode 100644 index 0000000..ccc5a53 --- /dev/null +++ b/sonar-runner-impl/src/test/java/org/sonar/runner/impl/NetworkUtil.java @@ -0,0 +1,52 @@ +/* + * Sonar Runner - Implementation + * Copyright (C) 2011 SonarSource + * dev@sonar.codehaus.org + * + * 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 02 + */ +package org.sonar.runner.impl; + + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.Arrays; +import java.util.List; + +class NetworkUtil { + static int getNextAvailablePort() { + for (int index = 0; index < 5; index++) { + try { + ServerSocket socket = new ServerSocket(0); + int unusedPort = socket.getLocalPort(); + socket.close(); + if (isValidPort(unusedPort)) { + return unusedPort; + } + + } catch (IOException e) { + throw new IllegalStateException("Can not find an open network port", e); + } + } + throw new IllegalStateException("Can not find an open network port"); + } + + // Firefox blocks some reserverd ports : http://www-archive.mozilla.org/projects/netlib/PortBanning.html + private static final List<Integer> BLOCKED_PORTS = Arrays.asList(2049, 4045, 6000); + + static boolean isValidPort(int port) { + return port > 1023 && !BLOCKED_PORTS.contains(port); + } +} diff --git a/sonar-runner-impl/src/test/java/org/sonar/runner/impl/ServerConnectionTest.java b/sonar-runner-impl/src/test/java/org/sonar/runner/impl/ServerConnectionTest.java index ca722e3..378aed5 100644 --- a/sonar-runner-impl/src/test/java/org/sonar/runner/impl/ServerConnectionTest.java +++ b/sonar-runner-impl/src/test/java/org/sonar/runner/impl/ServerConnectionTest.java @@ -28,6 +28,7 @@ import java.io.File; import java.util.Properties; import static org.fest.assertions.Assertions.assertThat; +import static org.fest.assertions.Fail.fail; public class ServerConnectionTest { @@ -61,4 +62,34 @@ public class ServerConnectionTest { assertThat(FileUtils.readFileToString(toFile)).isEqualTo("abcde"); } + + @Test + public void should_not_download_file_when_host_is_down() throws Exception { + Properties props = new Properties(); + props.setProperty("sonar.host.url", "http://localhost:" + NetworkUtil.getNextAvailablePort()); + + ServerConnection connection = ServerConnection.create(props); + File toFile = temp.newFile(); + try { + connection.download("/batch/index.txt", toFile); + fail(); + } catch (Exception e) { + // success + } + } + + @Test + public void should_not_download_string_when_host_is_down() throws Exception { + Properties props = new Properties(); + props.setProperty("sonar.host.url", "http://localhost:" + NetworkUtil.getNextAvailablePort()); + + ServerConnection connection = ServerConnection.create(props); + File toFile = temp.newFile(); + try { + connection.download("/batch/index.txt", toFile); + fail(); + } catch (Exception e) { + // success + } + } } |