[ 
https://issues.apache.org/jira/browse/CLOUDSTACK-9772?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16304312#comment-16304312
 ] 

ASF GitHub Bot commented on CLOUDSTACK-9772:
--------------------------------------------

rhtyd closed pull request #1934: [CLOUDSTACK-9772] Template: perform a HEAD 
request to check file size from a URL
URL: https://github.com/apache/cloudstack/pull/1934
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/utils/src/main/java/com/cloud/utils/UriUtils.java 
b/utils/src/main/java/com/cloud/utils/UriUtils.java
index 8805891cd2a..4d42e3cadd9 100644
--- a/utils/src/main/java/com/cloud/utils/UriUtils.java
+++ b/utils/src/main/java/com/cloud/utils/UriUtils.java
@@ -35,8 +35,6 @@
 import java.util.ListIterator;
 import java.util.StringTokenizer;
 
-import javax.net.ssl.HttpsURLConnection;
-
 import org.apache.commons.httpclient.Credentials;
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpException;
@@ -202,39 +200,47 @@ public static String getUpdateUri(String url, boolean 
encrypt) {
     }
 
     // Get the size of a file from URL response header.
-    public static Long getRemoteSize(String url) {
-        Long remoteSize = (long)0;
-        HttpURLConnection httpConn = null;
-        HttpsURLConnection httpsConn = null;
-        try {
-            URI uri = new URI(url);
-            if (uri.getScheme().equalsIgnoreCase("http")) {
+    public static long getRemoteSize(String url) {
+        long remoteSize = 0L;
+        final String[] methods = new String[]{"HEAD", "GET"};
+        IllegalArgumentException exception = null;
+        // Attempting first a HEAD request to avoid downloading the whole 
file. If
+        // it fails (for example with S3 presigned URL), fallback on a 
standard GET
+        // request.
+        for (String method : methods) {
+            HttpURLConnection httpConn = null;
+            try {
+                URI uri = new URI(url);
                 httpConn = (HttpURLConnection)uri.toURL().openConnection();
-                if (httpConn != null) {
-                    httpConn.setConnectTimeout(2000);
-                    httpConn.setReadTimeout(5000);
-                    String contentLength = 
httpConn.getHeaderField("content-length");
-                    if (contentLength != null) {
-                        remoteSize = Long.parseLong(contentLength);
+                httpConn.setRequestMethod(method);
+                httpConn.setConnectTimeout(2000);
+                httpConn.setReadTimeout(5000);
+                String contentLength = 
httpConn.getHeaderField("Content-Length");
+                if (contentLength != null) {
+                    remoteSize = Long.parseLong(contentLength);
+                } else if (method.equals("GET") && httpConn.getResponseCode() 
< 300) {
+                    // Calculate the content size based on the input stream 
content
+                    byte[] buf = new byte[1024];
+                    int length;
+                    while ((length = httpConn.getInputStream().read(buf, 0, 
buf.length)) != -1) {
+                        remoteSize += length;
                     }
-                    httpConn.disconnect();
                 }
-            } else if (uri.getScheme().equalsIgnoreCase("https")) {
-                httpsConn = (HttpsURLConnection)uri.toURL().openConnection();
-                if (httpsConn != null) {
-                    String contentLength = 
httpsConn.getHeaderField("content-length");
-                    if (contentLength != null) {
-                        remoteSize = Long.parseLong(contentLength);
-                    }
-                    httpsConn.disconnect();
+                return remoteSize;
+            } catch (URISyntaxException e) {
+                throw new IllegalArgumentException("Invalid URL " + url);
+            } catch (IOException e) {
+                exception = new IllegalArgumentException("Unable to establish 
connection with URL " + url);
+            } finally {
+                if (httpConn != null) {
+                    httpConn.disconnect();
                 }
             }
-        } catch (URISyntaxException e) {
-            throw new IllegalArgumentException("Invalid URL " + url);
-        } catch (IOException e) {
-            throw new IllegalArgumentException("Unable to establish connection 
with URL " + url);
         }
-        return remoteSize;
+        if (exception != null) {
+            throw exception;
+        }
+        return 0L;
     }
 
     public static Pair<String, Integer> validateUrl(String url) throws 
IllegalArgumentException {


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


> Perform HEAD request to retrieve header information
> ---------------------------------------------------
>
>                 Key: CLOUDSTACK-9772
>                 URL: https://issues.apache.org/jira/browse/CLOUDSTACK-9772
>             Project: CloudStack
>          Issue Type: Improvement
>      Security Level: Public(Anyone can view this level - this is the 
> default.) 
>          Components: Template
>    Affects Versions: 4.2.0, 4.2.1, 4.3.0, 4.4.0, 4.5.0, 4.3.1, 4.4.1, 4.4.2, 
> 4.4.3, 4.3.2, 4.5.1, 4.4.4, 4.5.2, 4.6.0, 4.6.1, 4.6.2, 4.7.0, 4.7.1, 4.8.0, 
> 4.9.0, 4.8.1.1, 4.9.0.1, 4.5.2.2
>            Reporter: Marc-Aurèle Brothier
>            Assignee: Marc-Aurèle Brothier
>
> The function in UriUtils which perform a check for the template file size of 
> an arbitrary URL is sending a `GET` request to only retrieve the response 
> header. A `HEAD` is the correct way of retrieving such information from the 
> response header.
> This was affecting the restart of a management server since all templates 
> were retrieved when receiving the startup command from the secondary storage 
> sysvm.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to