From d3fd746ad6b71a85e0bf8af38def6fdac409e55b Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Wed, 26 Oct 2022 22:09:33 -0500 Subject: [PATCH] Remove redundate oobUri, set FileParams from OOB or SIMS The url was being stored as part of oobUri and the FileParams, which is redundant. Just store FileParams now, and construct it directly from the OOB or (newly) SIMS reference if present. This brings rudimentary support for SIMS, which saves us a file size check roundtrip when SIMS is present. --- .../entities/IndividualMessage.java | 2 +- .../siacs/conversations/entities/Message.java | 59 ++++++++++++------- .../http/HttpDownloadConnection.java | 2 - .../conversations/parser/MessageParser.java | 26 ++++---- 4 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/IndividualMessage.java b/src/main/java/eu/siacs/conversations/entities/IndividualMessage.java index b16de580dead57b6f0d821c49e0537a21d2cd573..a9a62237aa21d6e0745d6c41eb157f79b7044998 100644 --- a/src/main/java/eu/siacs/conversations/entities/IndividualMessage.java +++ b/src/main/java/eu/siacs/conversations/entities/IndividualMessage.java @@ -44,7 +44,7 @@ public class IndividualMessage extends Message { } private IndividualMessage(Conversational conversation, String uuid, String conversationUUid, Jid counterpart, Jid trueCounterpart, String body, long timeSent, int encryption, int status, int type, boolean carbon, String remoteMsgId, String relativeFilePath, String serverMsgId, String fingerprint, boolean read, String edited, boolean oob, String errorMessage, Set readByMarkers, boolean markable, boolean deleted, String bodyLanguage) { - super(conversation, uuid, conversationUUid, counterpart, trueCounterpart, body, timeSent, encryption, status, type, carbon, remoteMsgId, relativeFilePath, serverMsgId, fingerprint, read, edited, oob, errorMessage, readByMarkers, markable, deleted, bodyLanguage, null, null, null, null); + super(conversation, uuid, conversationUUid, counterpart, trueCounterpart, body, timeSent, encryption, status, type, carbon, remoteMsgId, relativeFilePath, serverMsgId, fingerprint, read, edited, oob, errorMessage, readByMarkers, markable, deleted, bodyLanguage, null, null, null); } @Override diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 5d84e743416e1a55d49c98081d1bce3880a1776d..2f4a3d58dcf147549ea14f0d98fe0f1c07c3d3b0 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -46,6 +46,7 @@ import eu.siacs.conversations.utils.MimeUtils; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xml.Element; +import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xml.Tag; import eu.siacs.conversations.xml.XmlReader; @@ -119,7 +120,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable protected boolean deleted = false; protected boolean carbon = false; private boolean oob = false; - protected URI oobUri = null; protected List payloads = new ArrayList<>(); protected List edits = new ArrayList<>(); protected String relativeFilePath; @@ -175,7 +175,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable null, null, null, - null, null); } @@ -204,7 +203,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable null, null, null, - null, null); } @@ -214,7 +212,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable final String remoteMsgId, final String relativeFilePath, final String serverMsgId, final String fingerprint, final boolean read, final String edited, final boolean oob, final String errorMessage, final Set readByMarkers, - final boolean markable, final boolean deleted, final String bodyLanguage, final String subject, final String oobUri, final String fileParams, final List payloads) { + final boolean markable, final boolean deleted, final String bodyLanguage, final String subject, final String fileParams, final List payloads) { this.conversation = conversation; this.uuid = uuid; this.conversationUuid = conversationUUid; @@ -232,7 +230,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable this.axolotlFingerprint = fingerprint; this.read = read; this.edits = Edit.fromJson(edited); - setOob(oobUri); this.oob = oob; this.errorMessage = errorMessage; this.readByMarkers = readByMarkers == null ? new CopyOnWriteArraySet<>() : readByMarkers; @@ -280,7 +277,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable cursor.getInt(cursor.getColumnIndex(DELETED)) > 0, cursor.getString(cursor.getColumnIndex(BODY_LANGUAGE)), cursor.getString(cursor.getColumnIndex("subject")), - cursor.getString(cursor.getColumnIndex("oobUri")), cursor.getString(cursor.getColumnIndex("fileParams")), payloads ); @@ -316,7 +312,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable ContentValues values = new ContentValues(); values.put(UUID, uuid); values.put("subject", subject); - values.put("oobUri", oobUri == null ? null : oobUri.toString()); values.put("fileParams", fileParams == null ? null : fileParams.toString()); values.put("payloads", payloads.size() < 1 ? null : payloads.stream().map(Object::toString).collect(Collectors.joining())); return values; @@ -392,8 +387,8 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } public String getBody() { - if (oobUri != null) { - return body.replace(oobUri.toString(), ""); + if (getOob() != null) { + return body.replace(getOob().toString(), ""); } else { return body; } @@ -763,7 +758,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } public boolean isOOb() { - return oob || oobUri != null; + return oob || getFileParams().url != null; } public static class MergeSeparator { @@ -893,16 +888,12 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } public URI getOob() { - return oobUri; - } - - public void setOob(String oobUri) { + final String url = getFileParams().url; try { - this.oobUri = oobUri == null ? null : new URI(oobUri); + return url == null ? null : new URI(url); } catch (final URISyntaxException e) { - this.oobUri = null; + return null; } - this.oob = this.oobUri != null; } public void addPayload(Element el) { @@ -938,7 +929,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable if (relativeFilePath != null) { extension = MimeUtils.extractRelevantExtension(relativeFilePath); } else { - final String url = URL.tryParse(oobUri == null ? body.split("\n")[0] : oobUri.toString()); + final String url = URL.tryParse(getOob() == null ? body.split("\n")[0] : getOob().toString()); if (url == null) { return null; } @@ -982,10 +973,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable if (this.transferable != null) { fileParams.size = this.transferable.getFileSize(); } - - if (oobUri != null && ("http".equalsIgnoreCase(oobUri.getScheme()) || "https".equalsIgnoreCase(oobUri.getScheme()) || "cid".equalsIgnoreCase(oobUri.getScheme()))) { - fileParams.url = oobUri.toString(); - } } return fileParams; } @@ -1033,6 +1020,34 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable public FileParams() { } + public FileParams(Element el) { + if (el.getName().equals("x") && el.getNamespace().equals(Namespace.OOB)) { + this.url = el.findChildContent("url", Namespace.OOB); + } + if (el.getName().equals("reference") && el.getNamespace().equals("urn:xmpp:reference:0")) { + final String refUri = el.getAttribute("uri"); + if (refUri != null) url = refUri; + final Element mediaSharing = el.findChild("media-sharing", "urn:xmpp:sims:1"); + if (mediaSharing != null) { + Element file = mediaSharing.findChild("file", "urn:xmpp:jingle:apps:file-transfer:5"); + if (file == null) file = mediaSharing.findChild("file", "urn:xmpp:jingle:apps:file-transfer:4"); + if (file == null) file = mediaSharing.findChild("file", "urn:xmpp:jingle:apps:file-transfer:3"); + if (file != null) { + String sizeS = file.findChildContent("size", "urn:xmpp:jingle:apps:file-transfer:5"); + if (sizeS == null) sizeS = file.findChildContent("size", "urn:xmpp:jingle:apps:file-transfer:4"); + if (sizeS == null) sizeS = file.findChildContent("size", "urn:xmpp:jingle:apps:file-transfer:3"); + if (sizeS != null) size = new Long(sizeS); + } + + final Element sources = mediaSharing.findChild("sources", "urn:xmpp:sims:1"); + if (sources != null) { + final Element ref = sources.findChild("reference", "urn:xmpp:reference:0"); + if (ref != null) url = ref.getAttribute("uri"); + } + } + } + } + public FileParams(String ser) { final String[] parts = ser == null ? new String[0] : ser.split("\\|"); switch (parts.length) { diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index e7a0a35373372c57f6e800778f846bf3b45afb3d..e701d556d2bc66aa0b3af40579ff7668839522a1 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -75,7 +75,6 @@ public class HttpDownloadConnection implements Transferable { } else if (message.isFileOrImage()) { message.setType(Message.TYPE_TEXT); } - message.setOob(fileParams.url); message.setDeleted(false); mXmppConnectionService.updateMessage(message); } @@ -305,7 +304,6 @@ public class HttpDownloadConnection implements Transferable { } final Message.FileParams fileParams = message.getFileParams(); FileBackend.updateFileParams(message, fileParams.url, size); - message.setOob(fileParams.url); mXmppConnectionService.databaseBackend.updateMessage(message, true); file.setExpectedSize(size); message.resetFileParams(); diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d6bd5ef3e91ae550218fa0e32d192fb10241bcb4..d36eb772375cae6d45944b528c9a3dc1521e6d9a 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -408,8 +408,14 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece final Element mucUserElement = packet.findChild("x", Namespace.MUC_USER); final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted"); final Element replaceElement = packet.findChild("replace", "urn:xmpp:message-correct:0"); - final Element oob = packet.findChild("x", Namespace.OOB); - final String oobUrl = oob != null ? oob.findChildContent("url") : null; + Element oob = packet.findChild("x", Namespace.OOB); + if (oob != null && oob.findChildContent("url") == null) { + oob = null; + } + final Element reference = packet.findChild("reference", "urn:xmpp:reference:0"); + if (reference != null && reference.findChild("media-sharing", "urn:xmpp:sims:1") != null) { + oob = reference; + } String replacementId = replaceElement == null ? null : replaceElement.getAttribute("id"); if (replacementId == null) { Element fasten = packet.findChild("apply-to", "urn:xmpp:fasten:0"); @@ -477,7 +483,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece } } - if ((body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || oobUrl != null || html != null) && !isMucStatusMessage) { + if ((body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || oob != null || html != null) && !isMucStatusMessage) { final boolean conversationIsProbablyMuc = isTypeGroupChat || mucUserElement != null || account.getXmppConnection().getMucServersWithholdAccount().contains(counterpart.getDomain().toEscapedString()); final Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), conversationIsProbablyMuc, false, query, false); final boolean conversationMultiMode = conversation.getMode() == Conversation.MODE_MULTI; @@ -575,12 +581,8 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece if (conversationMultiMode) { message.setTrueCounterpart(origin); } - } else if (body == null && oobUrl != null) { - message = new Message(conversation, oobUrl, Message.ENCRYPTION_NONE, status); - message.setOob(oobUrl); - if (CryptoHelper.isPgpEncryptedUrl(oobUrl)) { - message.setEncryption(Message.ENCRYPTION_DECRYPTED); - } + } else if (body == null && oob != null) { + message = new Message(conversation, "", Message.ENCRYPTION_NONE, status); } else { message = new Message(conversation, body == null ? "HTML-only message" : body.content, Message.ENCRYPTION_NONE, status); if (body != null && body.count > 1) { @@ -595,9 +597,9 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece message.setServerMsgId(serverMsgId); message.setCarbon(isCarbon); message.setTime(timestamp); - if (oobUrl != null) { - message.setOob(oobUrl); - if (CryptoHelper.isPgpEncryptedUrl(oobUrl)) { + if (oob != null) { + message.setFileParams(new Message.FileParams(oob)); + if (CryptoHelper.isPgpEncryptedUrl(message.getFileParams().url)) { message.setEncryption(Message.ENCRYPTION_DECRYPTED); } }