mirror of
https://codeberg.org/monocles/monocles_chat.git
synced 2025-01-30 16:51:42 +01:00
Implement download resumption for OMEMO encrypted files
This commit is contained in:
parent
80c0e7d575
commit
15d27e2cbb
2 changed files with 56 additions and 22 deletions
|
@ -1,10 +1,14 @@
|
|||
package de.pixart.messenger.http;
|
||||
|
||||
import android.os.PowerManager;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
@ -93,12 +97,17 @@ public class HttpDownloadConnection implements Transferable {
|
|||
} else {
|
||||
ext = extension.main;
|
||||
}
|
||||
if (message.getStatus() == Message.STATUS_RECEIVED){
|
||||
if (message.getStatus() == Message.STATUS_RECEIVED) {
|
||||
message.setRelativeFilePath(fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + (ext != null ? ("." + ext) : ""));
|
||||
} else {
|
||||
message.setRelativeFilePath("Sent/" + fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + (ext != null ? ("." + ext) : ""));
|
||||
}
|
||||
this.file = mXmppConnectionService.getFileBackend().getFile(message, false);
|
||||
if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) {
|
||||
this.file = new DownloadableFile(mXmppConnectionService.getCacheDir().getAbsolutePath() + "/" + message.getUuid());
|
||||
Log.d(Config.LOGTAG, "create temporary OMEMO encrypted file: " + this.file.getAbsolutePath() + "(" + message.getMimeType() + ")");
|
||||
} else {
|
||||
this.file = mXmppConnectionService.getFileBackend().getFile(message, false);
|
||||
}
|
||||
final String reference = mUrl.getRef();
|
||||
if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) {
|
||||
this.file.setKeyAndIv(CryptoHelper.hexToBytes(reference));
|
||||
|
@ -141,7 +150,41 @@ public class HttpDownloadConnection implements Transferable {
|
|||
mHttpConnectionManager.updateConversationUi(true);
|
||||
}
|
||||
|
||||
private void finish() {
|
||||
private void decryptOmemoFile() throws Exception {
|
||||
final DownloadableFile outputFile = mXmppConnectionService.getFileBackend().getFile(message, true);
|
||||
|
||||
if (outputFile.getParentFile().mkdirs()) {
|
||||
Log.d(Config.LOGTAG, "created parent directories for " + outputFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
try {
|
||||
outputFile.createNewFile();
|
||||
final InputStream is = new FileInputStream(this.file);
|
||||
|
||||
outputFile.setKey(this.file.getKey());
|
||||
outputFile.setIv(this.file.getIv());
|
||||
final OutputStream os = AbstractConnectionManager.createOutputStream(outputFile, false, true);
|
||||
|
||||
ByteStreams.copy(is, os);
|
||||
|
||||
FileBackend.close(is);
|
||||
FileBackend.close(os);
|
||||
|
||||
if (!file.delete()) {
|
||||
Log.w(Config.LOGTAG, "unable to delete temporary OMEMO encrypted file " + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
message.setRelativeFilePath(outputFile.getPath());
|
||||
} catch (IOException e) {
|
||||
message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
|
||||
mXmppConnectionService.updateMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void finish() throws Exception {
|
||||
if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) {
|
||||
decryptOmemoFile();
|
||||
}
|
||||
message.setTransferable(null);
|
||||
mHttpConnectionManager.finishConnection(this);
|
||||
boolean notify = acceptedAutomatically && !message.isRead();
|
||||
|
@ -263,6 +306,10 @@ public class HttpDownloadConnection implements Transferable {
|
|||
retrieveFailed(e);
|
||||
return;
|
||||
}
|
||||
//TODO at this stage we probably also want to persist the file size in the body of the
|
||||
// message via a similar mechansim as updateFileParams() - essentially body needs to read
|
||||
// "url|filesize"
|
||||
// afterwards a file that failed to download mid way will not display 'check file size' anymore
|
||||
file.setExpectedSize(size);
|
||||
message.resetFileParams();
|
||||
if (mHttpConnectionManager.hasStoragePermission()
|
||||
|
@ -349,8 +396,8 @@ public class HttpDownloadConnection implements Transferable {
|
|||
try {
|
||||
changeStatus(STATUS_DOWNLOADING);
|
||||
download();
|
||||
updateImageBounds();
|
||||
finish();
|
||||
updateImageBounds();
|
||||
} catch (SSLHandshakeException e) {
|
||||
changeStatus(STATUS_OFFER);
|
||||
} catch (Exception e) {
|
||||
|
@ -383,11 +430,11 @@ public class HttpDownloadConnection implements Transferable {
|
|||
connection.setRequestProperty("User-Agent", mXmppConnectionService.getIqGenerator().getUserAgent());
|
||||
connection.setRequestProperty("Accept-Encoding", "identity");
|
||||
final long expected = file.getExpectedSize();
|
||||
final boolean tryResume = file.exists() && file.getKey() == null && file.getSize() > 0 && file.getSize() < expected;
|
||||
final boolean tryResume = file.exists() && file.getSize() > 0 && file.getSize() < expected;
|
||||
long resumeSize = 0;
|
||||
if (tryResume) {
|
||||
resumeSize = file.getSize();
|
||||
Log.d(Config.LOGTAG, "http download trying resume after" + resumeSize + " of " + expected);
|
||||
Log.d(Config.LOGTAG, "http download trying resume after " + resumeSize + " of " + expected);
|
||||
connection.setRequestProperty("Range", "bytes=" + resumeSize + "-");
|
||||
}
|
||||
connection.setConnectTimeout(Config.SOCKET_TIMEOUT * 1000);
|
||||
|
@ -401,7 +448,7 @@ public class HttpDownloadConnection implements Transferable {
|
|||
Log.d(Config.LOGTAG, "server resumed");
|
||||
transmitted = file.getSize();
|
||||
updateProgress(Math.round(((double) transmitted / expected) * 100));
|
||||
os = AbstractConnectionManager.createAppendedOutputStream(file);
|
||||
os = AbstractConnectionManager.createOutputStream(file, true, false);
|
||||
if (os == null) {
|
||||
throw new FileWriterException();
|
||||
}
|
||||
|
@ -421,7 +468,7 @@ public class HttpDownloadConnection implements Transferable {
|
|||
if (!file.exists() && !file.createNewFile()) {
|
||||
throw new FileWriterException();
|
||||
}
|
||||
os = AbstractConnectionManager.createOutputStream(file, true);
|
||||
os = AbstractConnectionManager.createOutputStream(file, false, false);
|
||||
}
|
||||
int count;
|
||||
byte[] buffer = new byte[4096];
|
||||
|
|
|
@ -51,19 +51,6 @@ public class AbstractConnectionManager {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static OutputStream createAppendedOutputStream(DownloadableFile file) {
|
||||
return createOutputStream(file, false, true);
|
||||
}
|
||||
|
||||
public static OutputStream createOutputStream(DownloadableFile file) {
|
||||
return createOutputStream(file, false);
|
||||
}
|
||||
|
||||
public static OutputStream createOutputStream(DownloadableFile file, boolean gcm) {
|
||||
return createOutputStream(file, gcm, false);
|
||||
}
|
||||
|
||||
public static OutputStream createOutputStream(DownloadableFile file, boolean append, boolean decrypt) {
|
||||
FileOutputStream os;
|
||||
try {
|
||||
|
|
Loading…
Add table
Reference in a new issue