Send SIMS with hashes and filename

Stephen Paul Weber created

Change summary

src/main/java/eu/siacs/conversations/entities/Message.java        | 35 +
src/main/java/eu/siacs/conversations/persistance/FileBackend.java | 10 
2 files changed, 41 insertions(+), 4 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Message.java 🔗

@@ -1100,6 +1100,9 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
             fileParams.sims = this.fileParams.sims;
         }
         this.fileParams = fileParams;
+        if (fileParams != null && getSims().isEmpty()) {
+            addPayload(fileParams.toSims());
+        }
     }
 
     public synchronized FileParams getFileParams() {
@@ -1229,6 +1232,21 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
             return file.findChildContent("name", file.getNamespace());
         }
 
+        public void setName(final String name) {
+            if (sims == null) toSims();
+            Element file = getFileElement();
+
+            for (Element child : file.getChildren()) {
+                if (child.getName().equals("name") && child.getNamespace().equals(file.getNamespace())) {
+                    file.removeChild(child);
+                }
+            }
+
+            if (name != null) {
+                file.addChild("name", file.getNamespace()).setContent(name);
+            }
+        }
+
         public Element toSims() {
             if (sims == null) sims = new Element("reference", "urn:xmpp:reference:0");
             sims.setAttribute("type", "data");
@@ -1277,6 +1295,23 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
             return file;
         }
 
+        public void setCids(Iterable<Cid> cids) throws NoSuchAlgorithmException {
+            if (sims == null) toSims();
+            Element file = getFileElement();
+
+            for (Element child : file.getChildren()) {
+                if (child.getName().equals("hash") && child.getNamespace().equals("urn:xmpp:hashes:2")) {
+                    file.removeChild(child);
+                }
+            }
+
+            for (Cid cid : cids) {
+                file.addChild("hash", "urn:xmpp:hashes:2")
+                    .setAttribute("algo", CryptoHelper.multihashAlgo(cid.getType()))
+                    .setContent(Base64.encodeToString(cid.getHash(), Base64.NO_WRAP));
+            }
+        }
+
         public List<Cid> getCids() {
             List<Cid> cids = new ArrayList<>();
             Element file = getFileElement();

src/main/java/eu/siacs/conversations/persistance/FileBackend.java 🔗

@@ -1739,10 +1739,6 @@ public class FileBackend {
                 message.getEncryption() == Message.ENCRYPTION_PGP
                         || message.getEncryption() == Message.ENCRYPTION_DECRYPTED;
         final DownloadableFile file = getFile(message);
-        Cid[] cids = new Cid[0];
-        try {
-            cids = calculateCids(new FileInputStream(file));
-        } catch (final IOException e) { }
         final String mime = file.getMimeType();
         final boolean privateMessage = message.isPrivateMessage();
         final boolean image =
@@ -1750,6 +1746,11 @@ public class FileBackend {
                         || (mime != null && mime.startsWith("image/"));
         Message.FileParams fileParams = message.getFileParams();
         if (fileParams == null) fileParams = new Message.FileParams();
+        Cid[] cids = new Cid[0];
+        try {
+            cids = calculateCids(new FileInputStream(file));
+            fileParams.setCids(List.of(cids));
+        } catch (final IOException | NoSuchAlgorithmException e) { }
         if (url == null) {
             for (Cid cid : cids) {
                 url = mXmppConnectionService.getUrlForCid(cid);
@@ -1761,6 +1762,7 @@ public class FileBackend {
         } else {
             fileParams.url = url;
         }
+        fileParams.setName(file.getName());
         if (encrypted && !file.exists()) {
             Log.d(Config.LOGTAG, "skipping updateFileParams because file is encrypted");
             final DownloadableFile encryptedFile = getFile(message, false);