Check completed download size against Content-Length header.

If the number of bytes received is less than the reported content length (e.g. a network timeout), mark the download with the "error" status instead of "complete".  Content-Length should be reliable if reported at all, so this should be a valid approach.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-08-30 23:18:46 -05:00
parent bd8e35cb81
commit aed5163a83
2 changed files with 13 additions and 6 deletions

View File

@ -245,9 +245,18 @@ public class Download {
fos = fileOutputStream;
status = Status.DOWNLOADING;
updateReadSoFar();
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
long bytesRead = fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
if (status == Status.DOWNLOADING) { // not interrupted
// TODO: if connection is lost before a download finishes, it's still marked as "complete"
// check if the entire file was received
if (bytesRead < contentLength) {
status = Status.ERROR;
Log.warn(String.format("Download '%s' failed: %d bytes expected, %d bytes received.", url.toString(), contentLength, bytesRead));
if (listener != null)
listener.error();
return;
}
// mark download as complete
status = Status.COMPLETE;
rbc.close();
fos.close();
@ -320,7 +329,7 @@ public class Download {
public long readSoFar() {
switch (status) {
case COMPLETE:
return contentLength;
return (rbc != null) ? rbc.getReadSoFar() : contentLength;
case DOWNLOADING:
if (rbc != null)
return rbc.getReadSoFar();

View File

@ -174,9 +174,7 @@ public class MengSkyServer extends DownloadServer {
continue;
}
DownloadNode node = new DownloadNode(id, date, title, titleUnicode, artist, artistUnicode, creator);
System.out.println(node);
nodeList.add(node);
nodeList.add(new DownloadNode(id, date, title, titleUnicode, artist, artistUnicode, creator));
}
nodes = nodeList.toArray(new DownloadNode[nodeList.size()]);