fix cancelation of http downloads and enable resume

This commit is contained in:
Daniel Gultsch 2015-12-11 20:33:41 +01:00
parent b2c278c91b
commit a1ac4fd665
2 changed files with 44 additions and 9 deletions

View File

@ -16,6 +16,7 @@ import java.net.MalformedURLException;
import java.net.Proxy; import java.net.Proxy;
import java.net.URL; import java.net.URL;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.CancellationException;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLHandshakeException;
@ -43,6 +44,7 @@ public class HttpDownloadConnection implements Transferable {
private boolean acceptedAutomatically = false; private boolean acceptedAutomatically = false;
private int mProgress = 0; private int mProgress = 0;
private boolean mUseTor = false; private boolean mUseTor = false;
private boolean canceled = false;
public HttpDownloadConnection(HttpConnectionManager manager) { public HttpDownloadConnection(HttpConnectionManager manager) {
this.mHttpConnectionManager = manager; this.mHttpConnectionManager = manager;
@ -114,7 +116,9 @@ public class HttpDownloadConnection implements Transferable {
new Thread(new FileSizeChecker(interactive)).start(); new Thread(new FileSizeChecker(interactive)).start();
} }
@Override
public void cancel() { public void cancel() {
this.canceled = true;
mHttpConnectionManager.finishConnection(this); mHttpConnectionManager.finishConnection(this);
if (message.isFileOrImage()) { if (message.isFileOrImage()) {
message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED));
@ -150,7 +154,7 @@ public class HttpDownloadConnection implements Transferable {
mXmppConnectionService.showErrorToastInUi(R.string.download_failed_server_not_found); mXmppConnectionService.showErrorToastInUi(R.string.download_failed_server_not_found);
} else if (e instanceof java.net.ConnectException) { } else if (e instanceof java.net.ConnectException) {
mXmppConnectionService.showErrorToastInUi(R.string.download_failed_could_not_connect); mXmppConnectionService.showErrorToastInUi(R.string.download_failed_could_not_connect);
} else { } else if (!(e instanceof CancellationException)) {
mXmppConnectionService.showErrorToastInUi(R.string.download_failed_file_not_found); mXmppConnectionService.showErrorToastInUi(R.string.download_failed_file_not_found);
} }
} }
@ -244,7 +248,7 @@ public class HttpDownloadConnection implements Transferable {
finish(); finish();
} catch (SSLHandshakeException e) { } catch (SSLHandshakeException e) {
changeStatus(STATUS_OFFER); changeStatus(STATUS_OFFER);
} catch (IOException e) { } catch (Exception e) {
if (interactive) { if (interactive) {
showToastForException(e); showToastForException(e);
} }
@ -252,7 +256,7 @@ public class HttpDownloadConnection implements Transferable {
} }
} }
private void download() throws IOException { private void download() throws Exception {
InputStream is = null; InputStream is = null;
PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_"+message.getUuid()); PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_"+message.getUuid());
try { try {
@ -267,24 +271,47 @@ public class HttpDownloadConnection implements Transferable {
mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive);
} }
connection.setRequestProperty("User-Agent",mXmppConnectionService.getIqGenerator().getIdentityName()); connection.setRequestProperty("User-Agent",mXmppConnectionService.getIqGenerator().getIdentityName());
final boolean tryResume = file.exists() && file.getKey() == null;
if (tryResume) {
Log.d(Config.LOGTAG,"http download trying resume");
long size = file.getSize();
connection.setRequestProperty("Range", "bytes="+size+"-");
}
connection.connect(); connection.connect();
is = new BufferedInputStream(connection.getInputStream()); is = new BufferedInputStream(connection.getInputStream());
file.getParentFile().mkdirs(); boolean serverResumed = "bytes".equals(connection.getHeaderField("Accept-Ranges"));
file.createNewFile();
os = AbstractConnectionManager.createOutputStream(file, true);
long transmitted = 0; long transmitted = 0;
long expected = file.getExpectedSize(); long expected = file.getExpectedSize();
if (tryResume && serverResumed) {
Log.d(Config.LOGTAG,"server resumed");
transmitted = file.getSize();
updateProgress((int) ((((double) transmitted) / expected) * 100));
os = AbstractConnectionManager.createAppendedOutputStream(file);
} else {
file.getParentFile().mkdirs();
file.createNewFile();
os = AbstractConnectionManager.createOutputStream(file, true);
}
int count = -1; int count = -1;
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
while ((count = is.read(buffer)) != -1) { while ((count = is.read(buffer)) != -1) {
transmitted += count; transmitted += count;
os.write(buffer, 0, count); os.write(buffer, 0, count);
updateProgress((int) ((((double) transmitted) / expected) * 100)); updateProgress((int) ((((double) transmitted) / expected) * 100));
if (canceled) {
throw new CancellationException();
}
} }
os.flush(); } catch (CancellationException | IOException e) {
} catch (IOException e) {
throw e; throw e;
} finally { } finally {
if (os != null) {
try {
os.flush();
} catch (final IOException ignored) {
}
}
FileBackend.close(os); FileBackend.close(os);
FileBackend.close(is); FileBackend.close(is);
wakeLock.release(); wakeLock.release();

View File

@ -95,10 +95,18 @@ public class AbstractConnectionManager {
} }
} }
public static OutputStream createAppendedOutputStream(DownloadableFile file) {
return createOutputStream(file, false, true);
}
public static OutputStream createOutputStream(DownloadableFile file, boolean gcm) { public static OutputStream createOutputStream(DownloadableFile file, boolean gcm) {
return createOutputStream(file, gcm, false);
}
private static OutputStream createOutputStream(DownloadableFile file, boolean gcm, boolean append) {
FileOutputStream os; FileOutputStream os;
try { try {
os = new FileOutputStream(file); os = new FileOutputStream(file, append);
if (file.getKey() == null) { if (file.getKey() == null) {
return os; return os;
} }