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 e4323e1d3950e781ddffef82f0ef7dbbc28a531c..f605fb5491490e6a1f8874358be87f266166bc42 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -47,6 +47,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; @@ -120,7 +121,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; @@ -176,7 +176,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable null, null, null, - null, null); } @@ -205,7 +204,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable null, null, null, - null, null); } @@ -215,7 +213,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; @@ -233,7 +231,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; @@ -281,7 +278,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 ); @@ -317,7 +313,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; @@ -393,8 +388,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; } @@ -764,7 +759,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 { @@ -894,16 +889,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) { @@ -939,7 +930,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; } @@ -983,10 +974,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; } @@ -1034,6 +1021,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); } }