This commit is contained in:
Niels Andriesse 2020-02-03 16:50:14 +11:00
parent 2c15cd06f5
commit 55344700d7
4 changed files with 66 additions and 34 deletions

View file

@ -5,7 +5,7 @@
<key>BuildDetails</key>
<dict>
<key>CarthageVersion</key>
<string>0.33.0</string>
<string>0.34.0</string>
<key>OSXVersion</key>
<string>10.15.2</string>
<key>WebRTCCommit</key>

View file

@ -74,37 +74,56 @@ public class LokiDotNetAPI : NSObject {
throw error
}
// Send the request
let task = AFURLSessionManager(sessionConfiguration: .default).uploadTask(withStreamedRequest: request as URLRequest, progress: { rawProgress in
// Broadcast progress updates
let progress = max(0.1, rawProgress.fractionCompleted)
let userInfo: [String:Any] = [ kAttachmentUploadProgressKey : progress, kAttachmentUploadAttachmentIDKey : attachmentID ]
DispatchQueue.main.async {
NotificationCenter.default.post(name: .attachmentUploadProgress, object: nil, userInfo: userInfo)
let isLokiFileServer = server.contains("file.lokinet.org") || server.contains("file-dev.lokinet.org")
if isLokiFileServer {
LokiFileServerProxy(for: server).performLokiFileServerNSURLRequest(request as NSURLRequest).done { responseObject in
// Parse the server ID & download URL
guard let json = responseObject as? JSON, let data = json["data"] as? JSON, let serverID = data["id"] as? UInt64, let downloadURL = data["url"] as? String else {
print("[Loki] Couldn't parse attachment from: \(responseObject).")
return seal.reject(Error.parsingFailed)
}
// Update the attachment
attachment.serverId = serverID
attachment.isUploaded = true
attachment.downloadURL = downloadURL
attachment.save()
seal.fulfill(())
}.catch { error in
seal.reject(error)
}
}, completionHandler: { response, responseObject, error in
if let error = error {
print("[Loki] Couldn't upload attachment due to error: \(error).")
return seal.reject(error)
}
let statusCode = (response as! HTTPURLResponse).statusCode
let isSuccessful = (200...299) ~= statusCode
guard isSuccessful else {
print("[Loki] Couldn't upload attachment.")
return seal.reject(Error.generic)
}
// Parse the server ID & download URL
guard let json = responseObject as? JSON, let data = json["data"] as? JSON, let serverID = data["id"] as? UInt64, let downloadURL = data["url"] as? String else {
print("[Loki] Couldn't parse attachment from: \(responseObject).")
return seal.reject(Error.parsingFailed)
}
// Update the attachment
attachment.serverId = serverID
attachment.isUploaded = true
attachment.downloadURL = downloadURL
attachment.save()
return seal.fulfill(())
})
task.resume()
} else {
let task = AFURLSessionManager(sessionConfiguration: .default).uploadTask(withStreamedRequest: request as URLRequest, progress: { rawProgress in
// Broadcast progress updates
let progress = max(0.1, rawProgress.fractionCompleted)
let userInfo: [String:Any] = [ kAttachmentUploadProgressKey : progress, kAttachmentUploadAttachmentIDKey : attachmentID ]
DispatchQueue.main.async {
NotificationCenter.default.post(name: .attachmentUploadProgress, object: nil, userInfo: userInfo)
}
}, completionHandler: { response, responseObject, error in
if let error = error {
print("[Loki] Couldn't upload attachment due to error: \(error).")
return seal.reject(error)
}
let statusCode = (response as! HTTPURLResponse).statusCode
let isSuccessful = (200...299) ~= statusCode
guard isSuccessful else {
print("[Loki] Couldn't upload attachment.")
return seal.reject(Error.generic)
}
// Parse the server ID & download URL
guard let json = responseObject as? JSON, let data = json["data"] as? JSON, let serverID = data["id"] as? UInt64, let downloadURL = data["url"] as? String else {
print("[Loki] Couldn't parse attachment from: \(responseObject).")
return seal.reject(Error.parsingFailed)
}
// Update the attachment
attachment.serverId = serverID
attachment.isUploaded = true
attachment.downloadURL = downloadURL
attachment.save()
return seal.fulfill(())
})
task.resume()
}
}.catch(on: DispatchQueue.global()) { error in
print("[Loki] Couldn't upload attachment.")
seal.reject(error)

View file

@ -39,6 +39,10 @@ internal class LokiFileServerProxy : LokiHTTPClient {
override internal func perform(_ request: TSRequest, withCompletionQueue queue: DispatchQueue = DispatchQueue.main) -> LokiAPI.RawResponsePromise {
let isLokiFileServer = server.contains("file.lokinet.org") || server.contains("file-dev.lokinet.org")
guard isLokiFileServer else { return super.perform(request, withCompletionQueue: queue) } // Don't proxy open group requests for now
return performLokiFileServerNSURLRequest(request, withCompletionQueue: queue)
}
internal func performLokiFileServerNSURLRequest(_ request: NSURLRequest, withCompletionQueue queue: DispatchQueue = DispatchQueue.main) -> LokiAPI.RawResponsePromise {
let uncheckedSymmetricKey = try? Curve25519.generateSharedSecret(fromPublicKey: LokiFileServerProxy.fileServerPublicKey, privateKey: keyPair.privateKey)
guard let symmetricKey = uncheckedSymmetricKey else { return Promise(error: Error.symmetricKeyGenerationFailed) }
var headers = getCanonicalHeaders(for: request)
@ -50,8 +54,17 @@ internal class LokiFileServerProxy : LokiHTTPClient {
serverURLEndIndex < urlAsString.endIndex else { throw Error.endpointParsingFailed }
let endpointStartIndex = urlAsString.index(after: serverURLEndIndex)
let endpoint = String(urlAsString[endpointStartIndex..<urlAsString.endIndex])
let parametersAsData = try JSONSerialization.data(withJSONObject: request.parameters, options: [])
let parametersAsString = !request.parameters.isEmpty ? String(bytes: parametersAsData, encoding: .utf8)! : "null"
let parametersAsString: String
if let tsRequest = request as? TSRequest {
let parametersAsData = try JSONSerialization.data(withJSONObject: tsRequest.parameters, options: [])
parametersAsString = !tsRequest.parameters.isEmpty ? String(bytes: parametersAsData, encoding: .utf8)! : "null"
} else {
if let parametersAsData = request.httpBody {
parametersAsString = "{ \"fileUpload\" : \"\(String(data: parametersAsData.base64EncodedData(), encoding: .utf8) ?? "null")\" }"
} else {
parametersAsString = "null"
}
}
let proxyRequestParameters: JSON = [
"body" : parametersAsString,
"endpoint": endpoint,

View file

@ -19,7 +19,7 @@ internal class LokiHTTPClient {
}
}
internal func getCanonicalHeaders(for request: TSRequest) -> [String: Any] {
internal func getCanonicalHeaders(for request: NSURLRequest) -> [String:Any] {
guard let headers = request.allHTTPHeaderFields else { return [:] }
return headers.mapValues { value in
switch value.lowercased() {