Skip to content

Commit

Permalink
Merge pull request #968 from rantianhua/master
Browse files Browse the repository at this point in the history
fix: cannot get content length during download connections
  • Loading branch information
Jacksgong authored Mar 11, 2018
2 parents 0795595 + 1442f8c commit 37d54d3
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ private void handleTrialConnectResult(Map<String, List<String>> requestHeader,

redirectedUrl = connectTask.getFinalRedirectedUrl();
if (acceptPartial || onlyFromBeginning) {
final long totalLength = FileDownloadUtils.findInstanceLengthForTrial(id, connection);
final long totalLength = FileDownloadUtils.findInstanceLengthForTrial(connection);

// update model
String fileName = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ public void run() throws IOException, IllegalAccessException, IllegalArgumentExc

if (paused) return;

final long contentLength = FileDownloadUtils.findContentLength(connectionIndex, connection);
long contentLength = FileDownloadUtils.findContentLength(connectionIndex, connection);
if (contentLength == TOTAL_VALUE_IN_CHUNKED_RESOURCE) {
contentLength = FileDownloadUtils.findContentLengthFromContentRange(connection);
}
if (contentLength == 0) {
throw new FileDownloadGiveUpRetryException(FileDownloadUtils.
formatString(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,10 +555,13 @@ public static boolean isAcceptRange(int responseCode, FileDownloadConnection con
// because of we using one of two HEAD method to request or using range:0-0 to trial connection
// only if connection api not support, so we test content-range first and then test
// content-length.
public static long findInstanceLengthForTrial(int id, FileDownloadConnection connection) {
public static long findInstanceLengthForTrial(FileDownloadConnection connection) {
long length = findInstanceLengthFromContentRange(connection);
if (length < 0) length = findContentLength(id, connection);
if (length < 0) length = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
if (length < 0) {
length = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
FileDownloadLog.w(FileDownloadUtils.class, "don't get instance length from"
+ "Content-Range header");
}
// the response of HEAD method is not very canonical sometimes(it depends on server
// implementation)
// so that it's uncertain the content-length is the same as the response of GET method if
Expand All @@ -571,13 +574,16 @@ public static long findInstanceLengthForTrial(int id, FileDownloadConnection con
}

public static long findInstanceLengthFromContentRange(FileDownloadConnection connection) {
return parseContentRangeFoInstanceLength(
connection.getResponseHeaderField("Content-Range"));
return parseContentRangeFoInstanceLength(getContentRangeHeader(connection));
}

private static String getContentRangeHeader(FileDownloadConnection connection) {
return connection.getResponseHeaderField("Content-Range");
}

public static long findContentLength(final int id, FileDownloadConnection connection) {
long contentLength = FileDownloadUtils
.convertContentLengthString(connection.getResponseHeaderField("Content-Length"));
long contentLength = convertContentLengthString(
connection.getResponseHeaderField("Content-Length"));
final String transferEncoding = connection.getResponseHeaderField("Transfer-Encoding");

if (contentLength < 0) {
Expand Down Expand Up @@ -609,6 +615,31 @@ public static long findContentLength(final int id, FileDownloadConnection connec
return contentLength;
}

public static long findContentLengthFromContentRange(FileDownloadConnection connection) {
final String contentRange = getContentRangeHeader(connection);
long contentLength = parseContentLengthFromContentRange(contentRange);
if (contentLength < 0) contentLength = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
return contentLength;
}

public static long parseContentLengthFromContentRange(String contentRange) {
if (contentRange == null || contentRange.length() == 0) return -1;
final String pattern = "bytes (\\d+)-(\\d+)/\\d+";
try {
final Pattern r = Pattern.compile(pattern);
final Matcher m = r.matcher(contentRange);
if (m.find()) {
final long rangeStart = Long.parseLong(m.group(1));
final long rangeEnd = Long.parseLong(m.group(2));
return rangeEnd - rangeStart + 1;
}
} catch (Exception e) {
FileDownloadLog.e(FileDownloadUtils.class, e, "parse content length"
+ " from content range error");
}
return -1;
}

public static String findFilename(FileDownloadConnection connection, String url) {
String filename = FileDownloadUtils.parseContentDisposition(connection.
getResponseHeaderField("Content-Disposition"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,29 @@ public void parseContentDisposition() {
assertThat(filename).isEqualTo("genome.jpeg");
}

@Test
public void parseContentLengthFromContentRange_withNullContentRange() {
long length = FileDownloadUtils.parseContentLengthFromContentRange(null);
assertThat(length).isEqualTo(-1);
}

@Test
public void parseContentLengthFromContentRange_withEmptyContentRange() {
long length = FileDownloadUtils.parseContentLengthFromContentRange("");
assertThat(length).isEqualTo(-1);
}

@Test
public void parseContentLengthFromContentRange_withStartToEndRange() {
long length = FileDownloadUtils
.parseContentLengthFromContentRange("bytes 25086300-37629450/37629451");
assertThat(length).isEqualTo(12543151);
}

@Test
public void parseContentLengthFromContentRange_withUnavailableContentRange() {
long length = FileDownloadUtils.parseContentLengthFromContentRange("bytes 0-/37629451");
assertThat(length).isEqualTo(-1);
}

}

0 comments on commit 37d54d3

Please sign in to comment.