From 303e205276abfc08cd7a6f50a21326fb3295be30 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 6 Dec 2020 19:22:36 +0100 Subject: [PATCH] =?UTF-8?q?if=20file=20extension=20doesn=E2=80=99t=20exist?= =?UTF-8?q?.=20try=20to=20guess=20from=20content=20type.=20fixes=20#3939?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/HttpDownloadConnection.java | 50 ++++++++++++------- .../services/AbstractConnectionManager.java | 10 ++++ 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index e01eb2578..476ea2d20 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -4,6 +4,7 @@ import android.os.PowerManager; import android.support.annotation.Nullable; import android.util.Log; +import com.google.common.base.Strings; import com.google.common.io.ByteStreams; import java.io.BufferedInputStream; @@ -30,16 +31,16 @@ import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.FileWriterException; +import eu.siacs.conversations.utils.MimeUtils; import eu.siacs.conversations.utils.WakeLockHelper; import eu.siacs.conversations.xmpp.stanzas.IqPacket; -import eu.siacs.conversations.xmpp.Jid; public class HttpDownloadConnection implements Transferable { private final Message message; private final boolean mUseTor; - private HttpConnectionManager mHttpConnectionManager; - private XmppConnectionService mXmppConnectionService; + private final HttpConnectionManager mHttpConnectionManager; + private final XmppConnectionService mXmppConnectionService; private URL mUrl; private DownloadableFile file; private int mStatus = Transferable.STATUS_UNKNOWN; @@ -97,23 +98,13 @@ public class HttpDownloadConnection implements Transferable { && message.getEncryption() != Message.ENCRYPTION_AXOLOTL) { this.message.setEncryption(Message.ENCRYPTION_NONE); } - final String ext; - if (VALID_CRYPTO_EXTENSIONS.contains(extension.main)) { - ext = extension.secondary; - } else { - ext = extension.main; + final String ext = extension.getExtension(); + if (ext != null) { + message.setRelativeFilePath(String.format("%s.%s", message.getUuid(), ext)); + } else if (Strings.isNullOrEmpty(message.getRelativeFilePath())) { + message.setRelativeFilePath(message.getUuid()); } - message.setRelativeFilePath(message.getUuid() + (ext != null ? ("." + ext) : "")); - final String reference = mUrl.getRef(); - if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) { - this.file = new DownloadableFile(mXmppConnectionService.getCacheDir().getAbsolutePath() + "/" + message.getUuid()); - this.file.setKeyAndIv(CryptoHelper.hexToBytes(reference)); - Log.d(Config.LOGTAG, "create temporary OMEMO encrypted file: " + this.file.getAbsolutePath() + "(" + message.getMimeType() + ")"); - } else { - this.file = mXmppConnectionService.getFileBackend().getFile(message, false); - } - - + setupFile(); if (this.message.getEncryption() == Message.ENCRYPTION_AXOLOTL && this.file.getKey() == null) { this.message.setEncryption(Message.ENCRYPTION_NONE); } @@ -130,6 +121,17 @@ public class HttpDownloadConnection implements Transferable { } } + private void setupFile() { + final String reference = mUrl.getRef(); + if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) { + this.file = new DownloadableFile(mXmppConnectionService.getCacheDir().getAbsolutePath() + "/" + message.getUuid()); + this.file.setKeyAndIv(CryptoHelper.hexToBytes(reference)); + Log.d(Config.LOGTAG, "create temporary OMEMO encrypted file: " + this.file.getAbsolutePath() + "(" + message.getMimeType() + ")"); + } else { + this.file = mXmppConnectionService.getFileBackend().getFile(message, false); + } + } + private void download(boolean interactive) { new Thread(new FileDownloader(interactive)).start(); } @@ -363,6 +365,16 @@ public class HttpDownloadConnection implements Transferable { } else { contentLength = connection.getHeaderField("Content-Length"); } + final String contentType = connection.getContentType(); + final AbstractConnectionManager.Extension extension = AbstractConnectionManager.Extension.of(mUrl.getPath()); + if (Strings.isNullOrEmpty(extension.getExtension()) && contentType != null) { + final String fileExtension = MimeUtils.guessExtensionFromMimeType(contentType); + if (fileExtension != null) { + message.setRelativeFilePath(String.format("%s.%s", message.getUuid(), fileExtension)); + Log.d(Config.LOGTAG, "rewriting name after not finding extension in url but in content type"); + setupFile(); + } + } connection.disconnect(); if (contentLength == null) { throw new IOException("no content-length found in HEAD response"); diff --git a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java index 98721aaf4..87dffab29 100644 --- a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java @@ -30,6 +30,8 @@ import eu.siacs.conversations.R; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.utils.Compatibility; +import static eu.siacs.conversations.entities.Transferable.VALID_CRYPTO_EXTENSIONS; + public class AbstractConnectionManager { private static final int UI_REFRESH_THRESHOLD = 250; @@ -106,6 +108,14 @@ public class AbstractConnectionManager { this.secondary = secondary; } + public String getExtension() { + if (VALID_CRYPTO_EXTENSIONS.contains(main)) { + return secondary; + } else { + return main; + } + } + public static Extension of(String path) { final int pos = path.lastIndexOf('/'); final String filename = path.substring(pos + 1).toLowerCase();