]> source.dussan.org Git - sonarqube.git/commitdiff
Fix leaked connection
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Wed, 13 Jul 2016 09:32:23 +0000 (11:32 +0200)
committerDuarte Meneses <duarte.meneses@sonarsource.com>
Wed, 13 Jul 2016 12:12:14 +0000 (14:12 +0200)
sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/BatchWsClient.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultGlobalRepositoriesLoader.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoader.java
sonar-ws/src/main/java/org/sonarqube/ws/client/BaseResponse.java
sonar-ws/src/main/java/org/sonarqube/ws/client/OkHttpResponse.java
sonar-ws/src/main/java/org/sonarqube/ws/client/WsResponse.java

index a90664999677f7ea737e5646bedc0a492425bba9..ea47cececbd372aaecfc24ad538a3224fdf88d4f 100644 (file)
@@ -56,6 +56,8 @@ public class BatchWsClient {
   }
 
   /**
+   * If an exception is not thrown, the response needs to be closed by either calling close() directly, or closing the 
+   * body content's stream/reader.
    * @throws IllegalStateException if the request could not be executed due to
    *     a connectivity problem or timeout. Because networks can
    *     fail during an exchange, it is possible that the remote server
@@ -82,6 +84,7 @@ public class BatchWsClient {
   private void failIfUnauthorized(WsResponse response) {
     int code = response.code();
     if (code == HTTP_UNAUTHORIZED) {
+      response.close();
       if (hasCredentials) {
         // credentials are not valid
         throw MessageException.of(format("Not authorized. Please check the properties %s and %s.",
@@ -94,6 +97,7 @@ public class BatchWsClient {
     }
     if (code == HTTP_FORBIDDEN || code == HTTP_BAD_REQUEST) {
       // SONAR-4397 Details are in response content
+      response.close();
       throw MessageException.of(tryParseAsJsonError(response.content()));
     }
     response.failIfNotSuccessful();
index d7140372d453839c221292ddf90477cf364b6674..84a44c49d121124179e500d537f10908077fa9be 100644 (file)
@@ -39,9 +39,8 @@ public class DefaultGlobalRepositoriesLoader implements GlobalRepositoriesLoader
   @Override
   public GlobalRepositories load() {
     GetRequest getRequest = new GetRequest(BATCH_GLOBAL_URL);
-    Reader reader = wsClient.call(getRequest).contentReader();
     String str;
-    try {
+    try (Reader reader = wsClient.call(getRequest).contentReader()) {
       str = IOUtils.toString(reader);
     } catch (IOException e) {
       throw new IllegalStateException(e);
index 5a9283dbac1b576502eded9b18eb2553e50a91bc..cea4a21ba17ae3e47b586179df69c1e424417348 100644 (file)
@@ -41,6 +41,7 @@ import org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath;
 import org.sonarqube.ws.WsBatch.WsProjectResponse.Settings;
 import org.sonarqube.ws.client.GetRequest;
 import org.sonarqube.ws.client.HttpException;
+import org.sonarqube.ws.client.WsResponse;
 
 public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoader {
   private static final Logger LOG = LoggerFactory.getLogger(DefaultProjectRepositoriesLoader.class);
@@ -53,9 +54,9 @@ public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoad
 
   @Override
   public ProjectRepositories load(String projectKey, boolean issuesMode) {
-    try {
-      GetRequest request = new GetRequest(getUrl(projectKey, issuesMode));
-      InputStream is = wsClient.call(request).contentStream();
+    GetRequest request = new GetRequest(getUrl(projectKey, issuesMode));
+    try (WsResponse response = wsClient.call(request)) {
+      InputStream is = response.contentStream();
       return processStream(is, projectKey);
     } catch (RuntimeException e) {
       if (shouldThrow(e)) {
index 2cfcd7448a5e4c679fe1cc61c1e263c477b6bec5..f97a919ec9155a0aff56b4734b683f160fc810f6 100644 (file)
@@ -31,6 +31,7 @@ abstract class BaseResponse implements WsResponse {
   @Override
   public WsResponse failIfNotSuccessful() {
     if (!isSuccessful()) {
+      close();
       throw new HttpException(requestUrl(), code());
     }
     return this;
@@ -40,4 +41,9 @@ abstract class BaseResponse implements WsResponse {
   public boolean hasContent() {
     return code() != HTTP_NO_CONTENT;
   }
+  
+  @Override
+  public void close() {
+    // override if needed
+  }
 }
index c2a6babc7149792b83016cdf47f8ff286a6d43f7..ce412f69de82b50d287798d4a980640e75ea962a 100644 (file)
@@ -77,4 +77,12 @@ class OkHttpResponse extends BaseResponse {
   private RuntimeException fail(Exception e) {
     throw new IllegalStateException("Fail to read response of " + requestUrl(), e);
   }
+
+  /**
+   * Equivalent to closing contentReader or contentStream.
+   */
+  @Override
+  public void close() {
+    okResponse.close();
+  }
 }
index 89c8977a46dff138ee2b7b15f048317d390bf6c6..fc3d83ff1773b0186ee57977ad92645fca402f7b 100644 (file)
  */
 package org.sonarqube.ws.client;
 
+import java.io.Closeable;
 import java.io.InputStream;
 import java.io.Reader;
 
 /**
  * @since 5.3
  */
-public interface WsResponse {
+public interface WsResponse extends Closeable {
 
   /**
    * The absolute requested URL
@@ -57,5 +58,8 @@ public interface WsResponse {
   Reader contentReader();
 
   String content();
+  
+  @Override
+  void close();
 
 }