if file extension doesn’t exist. try to guess from content type. fixes #3939

This commit is contained in:
Daniel Gultsch 2020-12-06 19:22:36 +01:00
parent 99cb23fe14
commit 303e205276
2 changed files with 41 additions and 19 deletions

View File

@ -4,6 +4,7 @@ import android.os.PowerManager;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
import com.google.common.base.Strings;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
@ -30,16 +31,16 @@ import eu.siacs.conversations.services.AbstractConnectionManager;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.FileWriterException; import eu.siacs.conversations.utils.FileWriterException;
import eu.siacs.conversations.utils.MimeUtils;
import eu.siacs.conversations.utils.WakeLockHelper; import eu.siacs.conversations.utils.WakeLockHelper;
import eu.siacs.conversations.xmpp.stanzas.IqPacket; import eu.siacs.conversations.xmpp.stanzas.IqPacket;
import eu.siacs.conversations.xmpp.Jid;
public class HttpDownloadConnection implements Transferable { public class HttpDownloadConnection implements Transferable {
private final Message message; private final Message message;
private final boolean mUseTor; private final boolean mUseTor;
private HttpConnectionManager mHttpConnectionManager; private final HttpConnectionManager mHttpConnectionManager;
private XmppConnectionService mXmppConnectionService; private final XmppConnectionService mXmppConnectionService;
private URL mUrl; private URL mUrl;
private DownloadableFile file; private DownloadableFile file;
private int mStatus = Transferable.STATUS_UNKNOWN; private int mStatus = Transferable.STATUS_UNKNOWN;
@ -97,23 +98,13 @@ public class HttpDownloadConnection implements Transferable {
&& message.getEncryption() != Message.ENCRYPTION_AXOLOTL) { && message.getEncryption() != Message.ENCRYPTION_AXOLOTL) {
this.message.setEncryption(Message.ENCRYPTION_NONE); this.message.setEncryption(Message.ENCRYPTION_NONE);
} }
final String ext; final String ext = extension.getExtension();
if (VALID_CRYPTO_EXTENSIONS.contains(extension.main)) { if (ext != null) {
ext = extension.secondary; message.setRelativeFilePath(String.format("%s.%s", message.getUuid(), ext));
} else { } else if (Strings.isNullOrEmpty(message.getRelativeFilePath())) {
ext = extension.main; message.setRelativeFilePath(message.getUuid());
} }
message.setRelativeFilePath(message.getUuid() + (ext != null ? ("." + ext) : "")); 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);
}
if (this.message.getEncryption() == Message.ENCRYPTION_AXOLOTL && this.file.getKey() == null) { if (this.message.getEncryption() == Message.ENCRYPTION_AXOLOTL && this.file.getKey() == null) {
this.message.setEncryption(Message.ENCRYPTION_NONE); 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) { private void download(boolean interactive) {
new Thread(new FileDownloader(interactive)).start(); new Thread(new FileDownloader(interactive)).start();
} }
@ -363,6 +365,16 @@ public class HttpDownloadConnection implements Transferable {
} else { } else {
contentLength = connection.getHeaderField("Content-Length"); 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(); connection.disconnect();
if (contentLength == null) { if (contentLength == null) {
throw new IOException("no content-length found in HEAD response"); throw new IOException("no content-length found in HEAD response");

View File

@ -30,6 +30,8 @@ import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.utils.Compatibility; import eu.siacs.conversations.utils.Compatibility;
import static eu.siacs.conversations.entities.Transferable.VALID_CRYPTO_EXTENSIONS;
public class AbstractConnectionManager { public class AbstractConnectionManager {
private static final int UI_REFRESH_THRESHOLD = 250; private static final int UI_REFRESH_THRESHOLD = 250;
@ -106,6 +108,14 @@ public class AbstractConnectionManager {
this.secondary = secondary; this.secondary = secondary;
} }
public String getExtension() {
if (VALID_CRYPTO_EXTENSIONS.contains(main)) {
return secondary;
} else {
return main;
}
}
public static Extension of(String path) { public static Extension of(String path) {
final int pos = path.lastIndexOf('/'); final int pos = path.lastIndexOf('/');
final String filename = path.substring(pos + 1).toLowerCase(); final String filename = path.substring(pos + 1).toLowerCase();