show p1s3 attchments with download button
This commit is contained in:
parent
70d95c7903
commit
4626bdf8d8
|
@ -123,9 +123,16 @@ public class MessageGenerator extends AbstractGenerator {
|
||||||
public MessagePacket generatePgpChat(Message message) {
|
public MessagePacket generatePgpChat(Message message) {
|
||||||
MessagePacket packet = preparePacket(message);
|
MessagePacket packet = preparePacket(message);
|
||||||
if (message.hasFileOnRemoteHost()) {
|
if (message.hasFileOnRemoteHost()) {
|
||||||
final String url = message.getFileParams().url.toString();
|
Message.FileParams fileParams = message.getFileParams();
|
||||||
packet.setBody(url);
|
final URL url = fileParams.url;
|
||||||
packet.addChild("x", Namespace.OOB).addChild("url").setContent(url);
|
if (P1S3UrlStreamHandler.PROTOCOL_NAME.equals(url.getProtocol())) {
|
||||||
|
Element x = packet.addChild("x", Namespace.P1_S3_FILE_TRANSFER);
|
||||||
|
x.setAttribute("name", url.getFile());
|
||||||
|
x.setAttribute("fileid", url.getHost());
|
||||||
|
} else {
|
||||||
|
packet.setBody(url.toString());
|
||||||
|
packet.addChild("x", Namespace.OOB).addChild("url").setContent(url.toString());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Config.supportUnencrypted()) {
|
if (Config.supportUnencrypted()) {
|
||||||
packet.setBody(PGP_FALLBACK_MESSAGE);
|
packet.setBody(PGP_FALLBACK_MESSAGE);
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
package eu.siacs.conversations.http;
|
package eu.siacs.conversations.http;
|
||||||
|
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.renderscript.ScriptGroup;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import org.bouncycastle.jce.exception.ExtIOException;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -26,17 +22,12 @@ import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.DownloadableFile;
|
import eu.siacs.conversations.entities.DownloadableFile;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.entities.Transferable;
|
import eu.siacs.conversations.entities.Transferable;
|
||||||
import eu.siacs.conversations.parser.IqParser;
|
|
||||||
import eu.siacs.conversations.persistance.FileBackend;
|
import eu.siacs.conversations.persistance.FileBackend;
|
||||||
import eu.siacs.conversations.services.AbstractConnectionManager;
|
import eu.siacs.conversations.services.AbstractConnectionManager;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.utils.Checksum;
|
import eu.siacs.conversations.utils.Checksum;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
import eu.siacs.conversations.utils.WakeLockHelper;
|
import eu.siacs.conversations.utils.WakeLockHelper;
|
||||||
import eu.siacs.conversations.xml.Namespace;
|
|
||||||
import eu.siacs.conversations.xml.Element;
|
|
||||||
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
|
||||||
import rocks.xmpp.addr.Jid;
|
|
||||||
|
|
||||||
public class HttpUploadConnection implements Transferable {
|
public class HttpUploadConnection implements Transferable {
|
||||||
|
|
||||||
|
@ -50,15 +41,13 @@ public class HttpUploadConnection implements Transferable {
|
||||||
private final XmppConnectionService mXmppConnectionService;
|
private final XmppConnectionService mXmppConnectionService;
|
||||||
private final SlotRequester mSlotRequester;
|
private final SlotRequester mSlotRequester;
|
||||||
private final Method method;
|
private final Method method;
|
||||||
|
private final boolean mUseTor;
|
||||||
private boolean canceled = false;
|
private boolean canceled = false;
|
||||||
private boolean delayed = false;
|
private boolean delayed = false;
|
||||||
private DownloadableFile file;
|
private DownloadableFile file;
|
||||||
private Message message;
|
private Message message;
|
||||||
private String mime;
|
private String mime;
|
||||||
private SlotRequester.Slot slot;
|
private SlotRequester.Slot slot;
|
||||||
private final boolean mUseTor;
|
|
||||||
|
|
||||||
private byte[] key = null;
|
private byte[] key = null;
|
||||||
|
|
||||||
private long transmitted = 0;
|
private long transmitted = 0;
|
||||||
|
@ -156,7 +145,6 @@ public class HttpUploadConnection implements Transferable {
|
||||||
public void success(SlotRequester.Slot slot) {
|
public void success(SlotRequester.Slot slot) {
|
||||||
if (!canceled) {
|
if (!canceled) {
|
||||||
HttpUploadConnection.this.slot = slot;
|
HttpUploadConnection.this.slot = slot;
|
||||||
Log.d(Config.LOGTAG,"not starting upload to "+slot.getPutUrl());
|
|
||||||
new Thread(HttpUploadConnection.this::upload).start();
|
new Thread(HttpUploadConnection.this::upload).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +213,11 @@ public class HttpUploadConnection implements Transferable {
|
||||||
Log.d(Config.LOGTAG, "finished uploading file");
|
Log.d(Config.LOGTAG, "finished uploading file");
|
||||||
final URL get;
|
final URL get;
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
get = CryptoHelper.toAesGcmUrl(new URL(slot.getGetUrl().toString() + "#" + CryptoHelper.bytesToHex(key)));
|
if (method == Method.P1_S3) {
|
||||||
|
get = new URL(slot.getGetUrl().toString()+"#"+CryptoHelper.bytesToHex(key));
|
||||||
|
} else {
|
||||||
|
get = CryptoHelper.toAesGcmUrl(new URL(slot.getGetUrl().toString() + "#" + CryptoHelper.bytesToHex(key)));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
get = slot.getGetUrl();
|
get = slot.getGetUrl();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,13 @@
|
||||||
|
|
||||||
package eu.siacs.conversations.http;
|
package eu.siacs.conversations.http;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.net.URLStreamHandler;
|
import java.net.URLStreamHandler;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.xml.Element;
|
||||||
|
|
||||||
public class P1S3UrlStreamHandler extends URLStreamHandler {
|
public class P1S3UrlStreamHandler extends URLStreamHandler {
|
||||||
|
|
||||||
public static final String PROTOCOL_NAME = "p1s3";
|
public static final String PROTOCOL_NAME = "p1s3";
|
||||||
|
@ -45,6 +46,17 @@ public class P1S3UrlStreamHandler extends URLStreamHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static URL of(String fileId, String filename) throws MalformedURLException {
|
public static URL of(String fileId, String filename) throws MalformedURLException {
|
||||||
|
if (fileId == null || filename == null) {
|
||||||
|
throw new MalformedURLException("Paramaters must not be null");
|
||||||
|
}
|
||||||
return new URL(PROTOCOL_NAME+"://" + fileId + "/" + filename);
|
return new URL(PROTOCOL_NAME+"://" + fileId + "/" + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static URL of(Element x) {
|
||||||
|
try {
|
||||||
|
return of(x.getAttribute("fileid"),x.getAttribute("name"));
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package eu.siacs.conversations.parser;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -27,6 +28,7 @@ import eu.siacs.conversations.entities.MucOptions;
|
||||||
import eu.siacs.conversations.entities.ReadByMarker;
|
import eu.siacs.conversations.entities.ReadByMarker;
|
||||||
import eu.siacs.conversations.entities.ReceiptRequest;
|
import eu.siacs.conversations.entities.ReceiptRequest;
|
||||||
import eu.siacs.conversations.http.HttpConnectionManager;
|
import eu.siacs.conversations.http.HttpConnectionManager;
|
||||||
|
import eu.siacs.conversations.http.P1S3UrlStreamHandler;
|
||||||
import eu.siacs.conversations.services.MessageArchiveService;
|
import eu.siacs.conversations.services.MessageArchiveService;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
|
@ -277,6 +279,8 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted");
|
final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted");
|
||||||
final Element replaceElement = packet.findChild("replace", "urn:xmpp:message-correct:0");
|
final Element replaceElement = packet.findChild("replace", "urn:xmpp:message-correct:0");
|
||||||
final Element oob = packet.findChild("x", Namespace.OOB);
|
final Element oob = packet.findChild("x", Namespace.OOB);
|
||||||
|
final Element xP1S3 = packet.findChild("x", Namespace.P1_S3_FILE_TRANSFER);
|
||||||
|
final URL xP1S3url = xP1S3 == null ? null : P1S3UrlStreamHandler.of(xP1S3);
|
||||||
final String oobUrl = oob != null ? oob.findChildContent("url") : null;
|
final String oobUrl = oob != null ? oob.findChildContent("url") : null;
|
||||||
final String replacementId = replaceElement == null ? null : replaceElement.getAttribute("id");
|
final String replacementId = replaceElement == null ? null : replaceElement.getAttribute("id");
|
||||||
final Element axolotlEncrypted = packet.findChild(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
|
final Element axolotlEncrypted = packet.findChild(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
|
||||||
|
@ -324,7 +328,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || oobUrl != null) && !isMucStatusMessage) {
|
if ((body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || oobUrl != null || xP1S3 != null) && !isMucStatusMessage) {
|
||||||
final boolean conversationIsProbablyMuc = isTypeGroupChat || mucUserElement != null || account.getXmppConnection().getMucServersWithholdAccount().contains(counterpart.getDomain());
|
final boolean conversationIsProbablyMuc = isTypeGroupChat || mucUserElement != null || account.getXmppConnection().getMucServersWithholdAccount().contains(counterpart.getDomain());
|
||||||
final Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), conversationIsProbablyMuc, false, query, false);
|
final Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), conversationIsProbablyMuc, false, query, false);
|
||||||
final boolean conversationMultiMode = conversation.getMode() == Conversation.MODE_MULTI;
|
final boolean conversationMultiMode = conversation.getMode() == Conversation.MODE_MULTI;
|
||||||
|
@ -362,7 +366,13 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Message message;
|
final Message message;
|
||||||
if (pgpEncrypted != null && Config.supportOpenPgp()) {
|
if (xP1S3url != null) {
|
||||||
|
message = new Message(conversation, xP1S3url.toString(), Message.ENCRYPTION_NONE, status);
|
||||||
|
message.setOob(true);
|
||||||
|
if (CryptoHelper.isPgpEncryptedUrl(xP1S3url.toString())) {
|
||||||
|
message.setEncryption(Message.ENCRYPTION_DECRYPTED);
|
||||||
|
}
|
||||||
|
} else if (pgpEncrypted != null && Config.supportOpenPgp()) {
|
||||||
message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status);
|
message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status);
|
||||||
} else if (axolotlEncrypted != null && Config.supportOmemo()) {
|
} else if (axolotlEncrypted != null && Config.supportOmemo()) {
|
||||||
Jid origin;
|
Jid origin;
|
||||||
|
|
|
@ -276,6 +276,6 @@ public final class CryptoHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final String u = url.toLowerCase();
|
final String u = url.toLowerCase();
|
||||||
return !u.contains(" ") && (u.startsWith("https://") || u.startsWith("http://")) && u.endsWith(".pgp");
|
return !u.contains(" ") && (u.startsWith("https://") || u.startsWith("http://") || u.startsWith("p1s3://")) && u.endsWith(".pgp");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import java.util.regex.Pattern;
|
||||||
|
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.http.AesGcmURLStreamHandler;
|
import eu.siacs.conversations.http.AesGcmURLStreamHandler;
|
||||||
|
import eu.siacs.conversations.http.P1S3UrlStreamHandler;
|
||||||
|
|
||||||
public class MessageUtils {
|
public class MessageUtils {
|
||||||
|
|
||||||
|
@ -79,7 +80,8 @@ public class MessageUtils {
|
||||||
final boolean encrypted = ref != null && AesGcmURLStreamHandler.IV_KEY.matcher(ref).matches();
|
final boolean encrypted = ref != null && AesGcmURLStreamHandler.IV_KEY.matcher(ref).matches();
|
||||||
final boolean followedByDataUri = lines.length == 2 && lines[1].startsWith("data:");
|
final boolean followedByDataUri = lines.length == 2 && lines[1].startsWith("data:");
|
||||||
final boolean validAesGcm = AesGcmURLStreamHandler.PROTOCOL_NAME.equalsIgnoreCase(protocol) && encrypted && (lines.length == 1 || followedByDataUri);
|
final boolean validAesGcm = AesGcmURLStreamHandler.PROTOCOL_NAME.equalsIgnoreCase(protocol) && encrypted && (lines.length == 1 || followedByDataUri);
|
||||||
final boolean validOob = ("http".equalsIgnoreCase(protocol) || "https".equalsIgnoreCase(protocol)) && (oob || encrypted) && lines.length == 1;
|
final boolean validProtocol = "http".equalsIgnoreCase(protocol) || "https".equalsIgnoreCase(protocol) || P1S3UrlStreamHandler.PROTOCOL_NAME.equalsIgnoreCase(protocol);
|
||||||
|
final boolean validOob = validProtocol && (oob || encrypted) && lines.length == 1;
|
||||||
return validAesGcm || validOob;
|
return validAesGcm || validOob;
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue