Skip to content

Commit 33ce66c

Browse files
committed
Template: perform a HEAD request to check file size from a URL
Signed-off-by: Marc-Aurèle Brothier <m@brothier.org>
1 parent bd56044 commit 33ce66c

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

utils/src/main/java/com/cloud/utils/UriUtils.java

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
import java.util.ListIterator;
3636
import java.util.StringTokenizer;
3737

38-
import javax.net.ssl.HttpsURLConnection;
39-
4038
import org.apache.commons.httpclient.Credentials;
4139
import org.apache.commons.httpclient.HttpClient;
4240
import org.apache.commons.httpclient.HttpException;
@@ -202,39 +200,47 @@ private static List<NameValuePair> getUserDetails(String query) {
202200
}
203201

204202
// Get the size of a file from URL response header.
205-
public static Long getRemoteSize(String url) {
206-
Long remoteSize = (long)0;
207-
HttpURLConnection httpConn = null;
208-
HttpsURLConnection httpsConn = null;
209-
try {
210-
URI uri = new URI(url);
211-
if (uri.getScheme().equalsIgnoreCase("http")) {
203+
public static long getRemoteSize(String url) {
204+
long remoteSize = 0L;
205+
final String[] methods = new String[]{"HEAD", "GET"};
206+
IllegalArgumentException exception = null;
207+
// Attempting first a HEAD request to avoid downloading the whole file. If
208+
// it fails (for example with S3 presigned URL), fallback on a standard GET
209+
// request.
210+
for (String method : methods) {
211+
HttpURLConnection httpConn = null;
212+
try {
213+
URI uri = new URI(url);
212214
httpConn = (HttpURLConnection)uri.toURL().openConnection();
213-
if (httpConn != null) {
214-
httpConn.setConnectTimeout(2000);
215-
httpConn.setReadTimeout(5000);
216-
String contentLength = httpConn.getHeaderField("content-length");
217-
if (contentLength != null) {
218-
remoteSize = Long.parseLong(contentLength);
215+
httpConn.setRequestMethod(method);
216+
httpConn.setConnectTimeout(2000);
217+
httpConn.setReadTimeout(5000);
218+
String contentLength = httpConn.getHeaderField("Content-Length");
219+
if (contentLength != null) {
220+
remoteSize = Long.parseLong(contentLength);
221+
} else if (method.equals("GET") && httpConn.getResponseCode() < 300) {
222+
// Calculate the content size based on the input stream content
223+
byte[] buf = new byte[1024];
224+
int length;
225+
while ((length = httpConn.getInputStream().read(buf, 0, buf.length)) != -1) {
226+
remoteSize += length;
219227
}
220-
httpConn.disconnect();
221228
}
222-
} else if (uri.getScheme().equalsIgnoreCase("https")) {
223-
httpsConn = (HttpsURLConnection)uri.toURL().openConnection();
224-
if (httpsConn != null) {
225-
String contentLength = httpsConn.getHeaderField("content-length");
226-
if (contentLength != null) {
227-
remoteSize = Long.parseLong(contentLength);
228-
}
229-
httpsConn.disconnect();
229+
return remoteSize;
230+
} catch (URISyntaxException e) {
231+
throw new IllegalArgumentException("Invalid URL " + url);
232+
} catch (IOException e) {
233+
exception = new IllegalArgumentException("Unable to establish connection with URL " + url);
234+
} finally {
235+
if (httpConn != null) {
236+
httpConn.disconnect();
230237
}
231238
}
232-
} catch (URISyntaxException e) {
233-
throw new IllegalArgumentException("Invalid URL " + url);
234-
} catch (IOException e) {
235-
throw new IllegalArgumentException("Unable to establish connection with URL " + url);
236239
}
237-
return remoteSize;
240+
if (exception != null) {
241+
throw exception;
242+
}
243+
return 0L;
238244
}
239245

240246
public static Pair<String, Integer> validateUrl(String url) throws IllegalArgumentException {

0 commit comments

Comments
 (0)