diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java')
-rw-r--r-- | src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java | 199 |
1 files changed, 60 insertions, 139 deletions
diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index 455a0b14..516d3141 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -2,33 +2,29 @@ package eu.siacs.conversations.http; import android.content.Intent; import android.net.Uri; -import android.os.PowerManager; -import android.util.Log; +import android.os.SystemClock; import java.io.BufferedInputStream; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.MalformedURLException; -import java.net.Proxy; import java.net.URL; import java.util.Arrays; -import java.util.concurrent.CancellationException; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLHandshakeException; +import de.thedevstack.android.logcat.Logging; +import de.thedevstack.conversationsplus.ConversationsPlusPreferences; +import de.thedevstack.conversationsplus.utils.MessageUtil; + import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.entities.Transferable; -import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.persistance.FileBackend; -import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; @@ -43,13 +39,11 @@ public class HttpDownloadConnection implements Transferable { private int mStatus = Transferable.STATUS_UNKNOWN; private boolean acceptedAutomatically = false; private int mProgress = 0; - private boolean mUseTor = false; - private boolean canceled = false; + private long mLastGuiRefresh = 0; public HttpDownloadConnection(HttpConnectionManager manager) { this.mHttpConnectionManager = manager; this.mXmppConnectionService = manager.getXmppConnectionService(); - this.mUseTor = mXmppConnectionService.useTorToConnect(); } @Override @@ -74,18 +68,13 @@ public class HttpDownloadConnection implements Transferable { this.message = message; this.message.setTransferable(this); try { - if (message.hasFileOnRemoteHost()) { - mUrl = message.getFileParams().url; - } else { - mUrl = new URL(message.getBody()); - } + mUrl = new URL(message.getBody()); String[] parts = mUrl.getPath().toLowerCase().split("\\."); String lastPart = parts.length >= 1 ? parts[parts.length - 1] : null; String secondToLast = parts.length >= 2 ? parts[parts.length -2] : null; if ("pgp".equals(lastPart) || "gpg".equals(lastPart)) { this.message.setEncryption(Message.ENCRYPTION_PGP); - } else if (message.getEncryption() != Message.ENCRYPTION_OTR - && message.getEncryption() != Message.ENCRYPTION_AXOLOTL) { + } else if (message.getEncryption() != Message.ENCRYPTION_OTR) { this.message.setEncryption(Message.ENCRYPTION_NONE); } String extension; @@ -95,14 +84,13 @@ public class HttpDownloadConnection implements Transferable { extension = lastPart; } message.setRelativeFilePath(message.getUuid()+"."+extension); - this.file = mXmppConnectionService.getFileBackend().getFile(message, false); + this.file = FileBackend.getFile(message, false); String reference = mUrl.getRef(); if (reference != null && reference.length() == 96) { - this.file.setKeyAndIv(CryptoHelper.hexToBytes(reference)); + this.file.setKey(CryptoHelper.hexToBytes(reference)); } - if ((this.message.getEncryption() == Message.ENCRYPTION_OTR - || this.message.getEncryption() == Message.ENCRYPTION_AXOLOTL) + if (this.message.getEncryption() == Message.ENCRYPTION_OTR && this.file.getKey() == null) { this.message.setEncryption(Message.ENCRYPTION_NONE); } @@ -116,15 +104,9 @@ public class HttpDownloadConnection implements Transferable { new Thread(new FileSizeChecker(interactive)).start(); } - @Override public void cancel() { - this.canceled = true; mHttpConnectionManager.finishConnection(this); - if (message.isFileOrImage()) { - message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); - } else { - message.setTransferable(null); - } + message.setTransferable(null); mXmppConnectionService.updateConversationUi(); } @@ -134,9 +116,6 @@ public class HttpDownloadConnection implements Transferable { mXmppConnectionService.sendBroadcast(intent); message.setTransferable(null); mHttpConnectionManager.finishConnection(this); - if (message.getEncryption() == Message.ENCRYPTION_PGP) { - message.getConversation().getAccount().getPgpDecryptionService().add(message); - } mXmppConnectionService.updateConversationUi(); if (acceptedAutomatically) { mXmppConnectionService.getNotificationService().push(message); @@ -148,17 +127,6 @@ public class HttpDownloadConnection implements Transferable { mXmppConnectionService.updateConversationUi(); } - private void showToastForException(Exception e) { - e.printStackTrace(); - if (e instanceof java.net.UnknownHostException) { - mXmppConnectionService.showErrorToastInUi(R.string.download_failed_server_not_found); - } else if (e instanceof java.net.ConnectException) { - mXmppConnectionService.showErrorToastInUi(R.string.download_failed_could_not_connect); - } else if (!(e instanceof CancellationException)) { - mXmppConnectionService.showErrorToastInUi(R.string.download_failed_file_not_found); - } - } - private class FileSizeChecker implements Runnable { private boolean interactive = false; @@ -178,15 +146,15 @@ public class HttpDownloadConnection implements Transferable { HttpDownloadConnection.this.mXmppConnectionService.getNotificationService().push(message); return; } catch (IOException e) { - Log.d(Config.LOGTAG, "io exception in http file size checker: " + e.getMessage()); + Logging.d(Config.LOGTAG, "io exception in http file size checker: " + e.getMessage()); if (interactive) { - showToastForException(e); + mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); } cancel(); return; } file.setExpectedSize(size); - if (mHttpConnectionManager.hasStoragePermission() && size <= mHttpConnectionManager.getAutoAcceptFileSize()) { + if (size != -1 && size <= ConversationsPlusPreferences.autoAcceptFileSize()) { HttpDownloadConnection.this.acceptedAutomatically = true; new Thread(new FileDownloader(interactive)).start(); } else { @@ -197,33 +165,22 @@ public class HttpDownloadConnection implements Transferable { } private long retrieveFileSize() throws IOException { + Logging.d(Config.LOGTAG,"retrieve file size. interactive:"+String.valueOf(interactive)); + changeStatus(STATUS_CHECKING); + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + connection.setRequestMethod("HEAD"); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); + } + connection.connect(); + String contentLength = connection.getHeaderField("Content-Length"); + if (contentLength == null) { + return -1; + } try { - Log.d(Config.LOGTAG, "retrieve file size. interactive:" + String.valueOf(interactive)); - changeStatus(STATUS_CHECKING); - HttpURLConnection connection; - if (mUseTor) { - connection = (HttpURLConnection) mUrl.openConnection(mHttpConnectionManager.getProxy()); - } else { - connection = (HttpURLConnection) mUrl.openConnection(); - } - connection.setRequestMethod("HEAD"); - Log.d(Config.LOGTAG,"url: "+connection.getURL().toString()); - Log.d(Config.LOGTAG,"connection: "+connection.toString()); - connection.setRequestProperty("User-Agent", mXmppConnectionService.getIqGenerator().getIdentityName()); - if (connection instanceof HttpsURLConnection) { - mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - String contentLength = connection.getHeaderField("Content-Length"); - connection.disconnect(); - if (contentLength == null) { - throw new IOException(); - } return Long.parseLong(contentLength, 10); - } catch (IOException e) { - throw e; } catch (NumberFormatException e) { - throw new IOException(); + return -1; } } @@ -233,8 +190,6 @@ public class HttpDownloadConnection implements Transferable { private boolean interactive = false; - private OutputStream os; - public FileDownloader(boolean interactive) { this.interactive = interactive; } @@ -248,79 +203,42 @@ public class HttpDownloadConnection implements Transferable { finish(); } catch (SSLHandshakeException e) { changeStatus(STATUS_OFFER); - } catch (Exception e) { - if (interactive) { - showToastForException(e); - } + } catch (IOException e) { + mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); cancel(); } } - private void download() throws Exception { - InputStream is = null; - PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_"+message.getUuid()); - try { - wakeLock.acquire(); - HttpURLConnection connection; - if (mUseTor) { - connection = (HttpURLConnection) mUrl.openConnection(mHttpConnectionManager.getProxy()); - } else { - connection = (HttpURLConnection) mUrl.openConnection(); - } - if (connection instanceof HttpsURLConnection) { - mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); - } - 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(); - is = new BufferedInputStream(connection.getInputStream()); - boolean serverResumed = "bytes".equals(connection.getHeaderField("Accept-Ranges")); - long transmitted = 0; - 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; - byte[] buffer = new byte[1024]; - while ((count = is.read(buffer)) != -1) { - transmitted += count; - os.write(buffer, 0, count); - updateProgress((int) ((((double) transmitted) / expected) * 100)); - if (canceled) { - throw new CancellationException(); - } - } - } catch (CancellationException | IOException e) { - throw e; - } finally { - if (os != null) { - try { - os.flush(); - } catch (final IOException ignored) { - - } - } - FileBackend.close(os); - FileBackend.close(is); - wakeLock.release(); + private void download() throws SSLHandshakeException, IOException { + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); } + connection.connect(); + BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); + file.getParentFile().mkdirs(); + file.createNewFile(); + OutputStream os = file.createOutputStream(); + if (os == null) { + throw new IOException(); + } + long transmitted = 0; + long expected = file.getExpectedSize(); + int count = -1; + byte[] buffer = new byte[1024]; + while ((count = is.read(buffer)) != -1) { + transmitted += count; + os.write(buffer, 0, count); + updateProgress((int) ((((double) transmitted) / expected) * 100)); + } + os.flush(); + os.close(); + is.close(); } private void updateImageBounds() { message.setType(Message.TYPE_FILE); - mXmppConnectionService.getFileBackend().updateFileParams(message, mUrl); + MessageUtil.updateFileParams(message, mUrl); mXmppConnectionService.updateMessage(message); } @@ -328,7 +246,10 @@ public class HttpDownloadConnection implements Transferable { public void updateProgress(int i) { this.mProgress = i; - mXmppConnectionService.updateConversationUi(); + if (SystemClock.elapsedRealtime() - this.mLastGuiRefresh > Config.PROGRESS_UI_UPDATE_INTERVAL) { + this.mLastGuiRefresh = SystemClock.elapsedRealtime(); + mXmppConnectionService.updateConversationUi(); + } } @Override |