[ 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)