From dcdf603a19a4d837c7bb4c82d5a6b23ac63ed153 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Tue, 10 Nov 2020 14:43:02 +1100 Subject: [PATCH 1/4] use v3/lsrpc endpoint for more compact (base64) file downloads --- SignalServiceKit/src/Loki/API/DotNetAPI.swift | 4 ++-- .../API/Onion Requests/OnionRequestAPI+Encryption.swift | 8 ++++---- .../src/Loki/API/Onion Requests/OnionRequestAPI.swift | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/DotNetAPI.swift b/SignalServiceKit/src/Loki/API/DotNetAPI.swift index 7fc906bfd..10ac7ce12 100644 --- a/SignalServiceKit/src/Loki/API/DotNetAPI.swift +++ b/SignalServiceKit/src/Loki/API/DotNetAPI.swift @@ -127,11 +127,11 @@ public class DotNetAPI : NSObject { return attempt(maxRetryCount: maxRetryCount, recoveringOn: SnodeAPI.workQueue) { serverPublicKeyPromise.then2 { serverPublicKey in return OnionRequestAPI.sendOnionRequest(request, to: host, using: serverPublicKey, isJSONRequired: false).map2 { json in - guard let body = json["body"] as? JSON, let data = body["data"] as? [UInt8] else { + guard let body = json["result"] as? String, let data = Data(base64Encoded: body) else { print("[Loki] Couldn't parse attachment from: \(json).") throw DotNetAPIError.parsingFailed } - return Data(data) + return data } } } diff --git a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI+Encryption.swift b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI+Encryption.swift index 84a8da122..04ac04160 100644 --- a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI+Encryption.swift +++ b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI+Encryption.swift @@ -26,7 +26,7 @@ extension OnionRequestAPI { let plaintext = try encode(ciphertext: payloadAsData, json: [ "headers" : "" ]) let result = try EncryptionUtilities.encrypt(plaintext, using: snodeX25519PublicKey) seal.fulfill(result) - case .server(_, let serverX25519PublicKey): + case .server(_, _, let serverX25519PublicKey): let plaintext = try JSONSerialization.data(withJSONObject: payload, options: [ .fragmentsAllowed ]) let result = try EncryptionUtilities.encrypt(plaintext, using: serverX25519PublicKey) seal.fulfill(result) @@ -47,8 +47,8 @@ extension OnionRequestAPI { case .snode(let snode): guard let snodeED25519PublicKey = snode.publicKeySet?.ed25519Key else { return seal.reject(Error.snodePublicKeySetMissing) } parameters = [ "destination" : snodeED25519PublicKey ] - case .server(let host, _): - parameters = [ "host" : host, "target" : "/loki/v2/lsrpc", "method" : "POST" ] + case .server(let host, let target, _): + parameters = [ "host" : host, "target" : target, "method" : "POST" ] } parameters["ephemeral_key"] = previousEncryptionResult.ephemeralPublicKey.toHexString() let x25519PublicKey: String @@ -56,7 +56,7 @@ extension OnionRequestAPI { case .snode(let snode): guard let snodeX25519PublicKey = snode.publicKeySet?.x25519Key else { return seal.reject(Error.snodePublicKeySetMissing) } x25519PublicKey = snodeX25519PublicKey - case .server(_, let serverX25519PublicKey): + case .server(_, _, let serverX25519PublicKey): x25519PublicKey = serverX25519PublicKey } do { diff --git a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift index 66432ef61..4b16a3b33 100644 --- a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift +++ b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift @@ -24,7 +24,7 @@ public enum OnionRequestAPI { // MARK: Destination internal enum Destination { case snode(Snode) - case server(host: String, x25519PublicKey: String) + case server(host: String, target: String, x25519PublicKey: String) } // MARK: Error @@ -280,7 +280,7 @@ public enum OnionRequestAPI { } /// Sends an onion request to `server`. Builds new paths as needed. - internal static func sendOnionRequest(_ request: NSURLRequest, to server: String, using x25519PublicKey: String, isJSONRequired: Bool = true) -> Promise { + internal static func sendOnionRequest(_ request: NSURLRequest, to server: String, target: String = "/loki/v3/lsrpc", using x25519PublicKey: String, isJSONRequired: Bool = true) -> Promise { var rawHeaders = request.allHTTPHeaderFields ?? [:] rawHeaders.removeValue(forKey: "User-Agent") var headers: JSON = rawHeaders.mapValues { value in @@ -323,7 +323,7 @@ public enum OnionRequestAPI { "method" : request.httpMethod!, "headers" : headers ] - let destination = Destination.server(host: host, x25519PublicKey: x25519PublicKey) + let destination = Destination.server(host: host, target: target, x25519PublicKey: x25519PublicKey) let promise = sendOnionRequest(with: payload, to: destination, isJSONRequired: isJSONRequired) promise.catch2 { error in print("[Loki] [Onion Request API] Couldn't reach server: \(url) due to error: \(error).") From 2915a51a287638d28ca25992fc5d8cc482ad850e Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Wed, 11 Nov 2020 09:41:57 +1100 Subject: [PATCH 2/4] set fileSizeORMultiplier to 2 --- SignalServiceKit/src/Loki/API/FileServerAPI.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SignalServiceKit/src/Loki/API/FileServerAPI.swift b/SignalServiceKit/src/Loki/API/FileServerAPI.swift index 003785850..0f378806d 100644 --- a/SignalServiceKit/src/Loki/API/FileServerAPI.swift +++ b/SignalServiceKit/src/Loki/API/FileServerAPI.swift @@ -16,7 +16,7 @@ public final class FileServerAPI : DotNetAPI { /// be other parameters in the request. On average the multiplier appears to be about 1.5, so when checking whether the file will exceed the file size limit when /// uploading a file we just divide the size of the file by this number. The alternative would be to actually check the size of the HTTP request but that's only /// possible after proof of work has been calculated and the onion request encryption has happened, which takes several seconds. - public static let fileSizeORMultiplier: Double = 6 // TODO: It should be possible to set this to 1.5? + public static let fileSizeORMultiplier: Double = 2 // TODO: It should be possible to set this to 1.5? @objc public static let server = "https://file.getsession.org" @objc public static let fileStorageBucketURL = "https://file-static.lokinet.org" From 701e8444beb67031bd4e82c507925e357cae23a8 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Wed, 11 Nov 2020 15:44:11 +1100 Subject: [PATCH 3/4] fix open group avatar issue --- .../src/Loki/API/Open Groups/PublicChatAPI.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SignalServiceKit/src/Loki/API/Open Groups/PublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Open Groups/PublicChatAPI.swift index 1661414bc..71ff23253 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/PublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/PublicChatAPI.swift @@ -388,7 +388,11 @@ public final class PublicChatAPI : DotNetAPI { if oldProfilePictureURL != info.profilePictureURL || groupModel.groupImage == nil { storage.setProfilePictureURL(info.profilePictureURL, forPublicChatWithID: publicChatID, in: transaction) if let profilePictureURL = info.profilePictureURL { - let url = server.hasSuffix("/") ? "\(server)\(profilePictureURL)" : "\(server)/\(profilePictureURL)" + var sanitizedServerURL = server + var sanitizedProfilePictureURL = profilePictureURL + while sanitizedServerURL.hasSuffix("/") { sanitizedServerURL.removeLast(1) } + while sanitizedProfilePictureURL.hasPrefix("/") { sanitizedProfilePictureURL.removeFirst(1) } + let url = "\(sanitizedServerURL)/\(sanitizedProfilePictureURL)" FileServerAPI.downloadAttachment(from: url).map2 { data in let attachmentStream = TSAttachmentStream(contentType: OWSMimeTypeImageJpeg, byteCount: UInt32(data.count), sourceFilename: nil, caption: nil, albumMessageId: nil) try attachmentStream.write(data) From e13a7d7e155c19c7fa431742b42dc8a50d829800 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Thu, 12 Nov 2020 11:18:07 +1100 Subject: [PATCH 4/4] set PN server request target as "/loki/v2/lsrpc", --- .../Push Notifications/LokiPushNotificationManager.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SignalServiceKit/src/Loki/Push Notifications/LokiPushNotificationManager.swift b/SignalServiceKit/src/Loki/Push Notifications/LokiPushNotificationManager.swift index 253e63be7..2333a7970 100644 --- a/SignalServiceKit/src/Loki/Push Notifications/LokiPushNotificationManager.swift +++ b/SignalServiceKit/src/Loki/Push Notifications/LokiPushNotificationManager.swift @@ -30,7 +30,7 @@ public final class LokiPushNotificationManager : NSObject { let request = TSRequest(url: url, method: "POST", parameters: parameters) request.allHTTPHeaderFields = [ "Content-Type" : "application/json" ] let promise: Promise = attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global()) { - OnionRequestAPI.sendOnionRequest(request, to: server, using: pnServerPublicKey).map2 { response in + OnionRequestAPI.sendOnionRequest(request, to: server, target: "/loki/v2/lsrpc", using: pnServerPublicKey).map2 { response in guard let json = response["body"] as? JSON else { return print("[Loki] Couldn't unregister from push notifications.") } @@ -72,7 +72,7 @@ public final class LokiPushNotificationManager : NSObject { let request = TSRequest(url: url, method: "POST", parameters: parameters) request.allHTTPHeaderFields = [ "Content-Type" : "application/json" ] let promise: Promise = attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global()) { - OnionRequestAPI.sendOnionRequest(request, to: server, using: pnServerPublicKey).map2 { response in + OnionRequestAPI.sendOnionRequest(request, to: server, target: "/loki/v2/lsrpc", using: pnServerPublicKey).map2 { response in guard let json = response["body"] as? JSON else { return print("[Loki] Couldn't register device token.") } @@ -109,7 +109,7 @@ public final class LokiPushNotificationManager : NSObject { let request = TSRequest(url: url, method: "POST", parameters: parameters) request.allHTTPHeaderFields = [ "Content-Type" : "application/json" ] let promise: Promise = attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global()) { - OnionRequestAPI.sendOnionRequest(request, to: server, using: pnServerPublicKey).map2 { response in + OnionRequestAPI.sendOnionRequest(request, to: server, target: "/loki/v2/lsrpc", using: pnServerPublicKey).map2 { response in guard let json = response["body"] as? JSON else { return print("[Loki] Couldn't subscribe/unsubscribe closed group: \(closedGroupPublicKey).") } @@ -131,7 +131,7 @@ public final class LokiPushNotificationManager : NSObject { let request = TSRequest(url: url, method: "POST", parameters: parameters) request.allHTTPHeaderFields = [ "Content-Type" : "application/json" ] let promise: Promise = attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global()) { - OnionRequestAPI.sendOnionRequest(request, to: server, using: pnServerPublicKey).map2 { response in + OnionRequestAPI.sendOnionRequest(request, to: server, target: "/loki/v2/lsrpc", using: pnServerPublicKey).map2 { response in guard let json = response["body"] as? JSON else { return print("[Loki] Couldn't notify PN server.") }