Renamed FileServerAPIV2 to FileServerAPI
Updated the direct file upload/download to use the non-base64 approaches as well Updated the attachment 'serverId' value to be a string instead of a UInt64 (future-proofing) Updated the OnionRequest V4 response handling to avoid converting the "response body" part to a string and processing that, instead just slice the byte array (ie. stopped it from being broken from multiple conversions) Removed the base64-based file upload/download endpoints (no use including them when they are inefficient and we don't want to use them)
This commit is contained in:
parent
1c474955de
commit
81f563229f
|
@ -203,7 +203,7 @@
|
|||
B875885A264503A6000E60D0 /* JoinOpenGroupModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8758859264503A6000E60D0 /* JoinOpenGroupModal.swift */; };
|
||||
B8783E9E23EB948D00404FB8 /* UILabel+Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8783E9D23EB948D00404FB8 /* UILabel+Interaction.swift */; };
|
||||
B879D449247E1BE300DB3608 /* PathVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B879D448247E1BE300DB3608 /* PathVC.swift */; };
|
||||
B87EF17126367CF800124B3C /* FileServerAPIV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B87EF17026367CF800124B3C /* FileServerAPIV2.swift */; };
|
||||
B87EF17126367CF800124B3C /* FileServerAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B87EF17026367CF800124B3C /* FileServerAPI.swift */; };
|
||||
B87EF18126377A1D00124B3C /* Features.swift in Sources */ = {isa = PBXBuildFile; fileRef = B87EF18026377A1D00124B3C /* Features.swift */; };
|
||||
B8856CA8256F0F42001CE70E /* OWSBackupFragment.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB07255A580700E217F9 /* OWSBackupFragment.m */; };
|
||||
B8856CB1256F0F47001CE70E /* OWSBackupFragment.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAEA255A580500E217F9 /* OWSBackupFragment.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
|
@ -827,12 +827,8 @@
|
|||
FDC4384C27B47F7700C60D73 /* OpenGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4384B27B47F7700C60D73 /* OpenGroup.swift */; };
|
||||
FDC4384F27B4804F00C60D73 /* Header.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4384E27B4804F00C60D73 /* Header.swift */; };
|
||||
FDC4385127B4807400C60D73 /* QueryParam.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4385027B4807400C60D73 /* QueryParam.swift */; };
|
||||
FDC4385727B484B700C60D73 /* LegacyFileUploadResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4385627B484B700C60D73 /* LegacyFileUploadResponse.swift */; };
|
||||
FDC4385927B484E800C60D73 /* FileUploadBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4385827B484E800C60D73 /* FileUploadBody.swift */; };
|
||||
FDC4385B27B485DE00C60D73 /* LegacyFileDownloadResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4385A27B485DE00C60D73 /* LegacyFileDownloadResponse.swift */; };
|
||||
FDC4385D27B4C18900C60D73 /* Room.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4385C27B4C18900C60D73 /* Room.swift */; };
|
||||
FDC4385F27B4C4A200C60D73 /* PinnedMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4385E27B4C4A200C60D73 /* PinnedMessage.swift */; };
|
||||
FDC4386127B4CDDF00C60D73 /* FileResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4386027B4CDDF00C60D73 /* FileResponse.swift */; };
|
||||
FDC4386327B4D94E00C60D73 /* SOGSMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4386227B4D94E00C60D73 /* SOGSMessage.swift */; };
|
||||
FDC4386527B4DE7600C60D73 /* RoomPollInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4386427B4DE7600C60D73 /* RoomPollInfo.swift */; };
|
||||
FDC4386727B4E10E00C60D73 /* Capabilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4386627B4E10E00C60D73 /* Capabilities.swift */; };
|
||||
|
@ -841,7 +837,6 @@
|
|||
FDC4386C27B4E90300C60D73 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; };
|
||||
FDC4387227B5BB3B00C60D73 /* FileUploadResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4387127B5BB3B00C60D73 /* FileUploadResponse.swift */; };
|
||||
FDC4387427B5BB9B00C60D73 /* Promise+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4387327B5BB9B00C60D73 /* Promise+Utilities.swift */; };
|
||||
FDC4387627B5BEF300C60D73 /* FileDownloadResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4387527B5BEF300C60D73 /* FileDownloadResponse.swift */; };
|
||||
FDC4387827B5C35400C60D73 /* SendMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4387727B5C35400C60D73 /* SendMessageRequest.swift */; };
|
||||
FDC4389227B9FFC700C60D73 /* SessionMessagingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A6F025539DE700C340D1 /* SessionMessagingKit.framework */; platformFilter = ios; };
|
||||
FDC4389A27BA002500C60D73 /* OpenGroupAPISpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC4389927BA002500C60D73 /* OpenGroupAPISpec.swift */; };
|
||||
|
@ -1341,7 +1336,7 @@
|
|||
B8783E9D23EB948D00404FB8 /* UILabel+Interaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+Interaction.swift"; sourceTree = "<group>"; };
|
||||
B879D448247E1BE300DB3608 /* PathVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PathVC.swift; sourceTree = "<group>"; };
|
||||
B879D44A247E1D9200DB3608 /* PathStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PathStatusView.swift; sourceTree = "<group>"; };
|
||||
B87EF17026367CF800124B3C /* FileServerAPIV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileServerAPIV2.swift; sourceTree = "<group>"; };
|
||||
B87EF17026367CF800124B3C /* FileServerAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileServerAPI.swift; sourceTree = "<group>"; };
|
||||
B87EF18026377A1D00124B3C /* Features.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Features.swift; sourceTree = "<group>"; };
|
||||
B883F8C5D6D90C5077B2FD14 /* Pods_GlobalDependencies_Session.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_Session.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B8856D5F256F129B001CE70E /* OWSAlerts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAlerts.swift; sourceTree = "<group>"; };
|
||||
|
@ -1985,12 +1980,8 @@
|
|||
FDC4384B27B47F7700C60D73 /* OpenGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenGroup.swift; sourceTree = "<group>"; };
|
||||
FDC4384E27B4804F00C60D73 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = "<group>"; };
|
||||
FDC4385027B4807400C60D73 /* QueryParam.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryParam.swift; sourceTree = "<group>"; };
|
||||
FDC4385627B484B700C60D73 /* LegacyFileUploadResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyFileUploadResponse.swift; sourceTree = "<group>"; };
|
||||
FDC4385827B484E800C60D73 /* FileUploadBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUploadBody.swift; sourceTree = "<group>"; };
|
||||
FDC4385A27B485DE00C60D73 /* LegacyFileDownloadResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyFileDownloadResponse.swift; sourceTree = "<group>"; };
|
||||
FDC4385C27B4C18900C60D73 /* Room.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Room.swift; sourceTree = "<group>"; };
|
||||
FDC4385E27B4C4A200C60D73 /* PinnedMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedMessage.swift; sourceTree = "<group>"; };
|
||||
FDC4386027B4CDDF00C60D73 /* FileResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileResponse.swift; sourceTree = "<group>"; };
|
||||
FDC4386227B4D94E00C60D73 /* SOGSMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOGSMessage.swift; sourceTree = "<group>"; };
|
||||
FDC4386427B4DE7600C60D73 /* RoomPollInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollInfo.swift; sourceTree = "<group>"; };
|
||||
FDC4386627B4E10E00C60D73 /* Capabilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Capabilities.swift; sourceTree = "<group>"; };
|
||||
|
@ -1998,7 +1989,6 @@
|
|||
FDC4386A27B4E88F00C60D73 /* BatchRequestInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatchRequestInfo.swift; sourceTree = "<group>"; };
|
||||
FDC4387127B5BB3B00C60D73 /* FileUploadResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUploadResponse.swift; sourceTree = "<group>"; };
|
||||
FDC4387327B5BB9B00C60D73 /* Promise+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Promise+Utilities.swift"; sourceTree = "<group>"; };
|
||||
FDC4387527B5BEF300C60D73 /* FileDownloadResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileDownloadResponse.swift; sourceTree = "<group>"; };
|
||||
FDC4387727B5C35400C60D73 /* SendMessageRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendMessageRequest.swift; sourceTree = "<group>"; };
|
||||
FDC4388E27B9FFC700C60D73 /* SessionMessagingKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SessionMessagingKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FDC4389927BA002500C60D73 /* OpenGroupAPISpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupAPISpec.swift; sourceTree = "<group>"; };
|
||||
|
@ -3423,7 +3413,7 @@
|
|||
children = (
|
||||
FDC4383227B385B200C60D73 /* Models */,
|
||||
FD83B9CA27D179AF005E1583 /* Types */,
|
||||
B87EF17026367CF800124B3C /* FileServerAPIV2.swift */,
|
||||
B87EF17026367CF800124B3C /* FileServerAPI.swift */,
|
||||
);
|
||||
path = "File Server";
|
||||
sourceTree = "<group>";
|
||||
|
@ -3947,7 +3937,6 @@
|
|||
FDC4385C27B4C18900C60D73 /* Room.swift */,
|
||||
FDC4386427B4DE7600C60D73 /* RoomPollInfo.swift */,
|
||||
FDC4385E27B4C4A200C60D73 /* PinnedMessage.swift */,
|
||||
FDC4386027B4CDDF00C60D73 /* FileResponse.swift */,
|
||||
FDC4387727B5C35400C60D73 /* SendMessageRequest.swift */,
|
||||
FDC438CA27BB7DB100C60D73 /* UpdateMessageRequest.swift */,
|
||||
FDC4386227B4D94E00C60D73 /* SOGSMessage.swift */,
|
||||
|
@ -4006,11 +3995,7 @@
|
|||
FDC4385527B484AE00C60D73 /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDC4385827B484E800C60D73 /* FileUploadBody.swift */,
|
||||
FDC4387127B5BB3B00C60D73 /* FileUploadResponse.swift */,
|
||||
FDC4387527B5BEF300C60D73 /* FileDownloadResponse.swift */,
|
||||
FDC4385627B484B700C60D73 /* LegacyFileUploadResponse.swift */,
|
||||
FDC4385A27B485DE00C60D73 /* LegacyFileDownloadResponse.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
|
@ -5333,7 +5318,6 @@
|
|||
C3C2A7842553AAF300C340D1 /* SNProto.swift in Sources */,
|
||||
C32C5DC0256DD743003C73A2 /* Poller.swift in Sources */,
|
||||
C3C2A7682553A3D900C340D1 /* VisibleMessage+Contact.swift in Sources */,
|
||||
FDC4386127B4CDDF00C60D73 /* FileResponse.swift in Sources */,
|
||||
C3A3A171256E1D25004D228D /* SSKReachabilityManager.swift in Sources */,
|
||||
C3A71D0B2558989C0043A11F /* MessageWrapper.swift in Sources */,
|
||||
B8F5F60325EDE16F003BF8D4 /* DataExtractionNotification.swift in Sources */,
|
||||
|
@ -5354,7 +5338,6 @@
|
|||
C300A5BD2554B00D00555489 /* ReadReceipt.swift in Sources */,
|
||||
FD83B9CC27D179BC005E1583 /* FSEndpoint.swift in Sources */,
|
||||
C32C5AB5256DBE8F003C73A2 /* TSOutgoingMessage+Conversion.swift in Sources */,
|
||||
FDC4385927B484E800C60D73 /* FileUploadBody.swift in Sources */,
|
||||
C32C5E5B256DDF45003C73A2 /* OWSStorage.m in Sources */,
|
||||
C32C5E15256DDC78003C73A2 /* SSKPreferences.swift in Sources */,
|
||||
FDC438C727BB6DF000C60D73 /* DirectMessage.swift in Sources */,
|
||||
|
@ -5371,7 +5354,6 @@
|
|||
C32C5EDC256DF501003C73A2 /* YapDatabaseConnection+OWS.m in Sources */,
|
||||
FDC4381527B329CE00C60D73 /* NonceGenerator.swift in Sources */,
|
||||
C3BBE0762554CDA60050F1E3 /* Configuration.swift in Sources */,
|
||||
FDC4387627B5BEF300C60D73 /* FileDownloadResponse.swift in Sources */,
|
||||
C35D76DB26606304009AA5FB /* ThreadUpdateBatcher.swift in Sources */,
|
||||
FDC4382C27B380E300C60D73 /* LegacyMemberCountResponse.swift in Sources */,
|
||||
B8B32033258B235D0020074B /* Storage+Contacts.swift in Sources */,
|
||||
|
@ -5427,7 +5409,7 @@
|
|||
C32C5FBB256E0206003C73A2 /* OWSBackgroundTask.m in Sources */,
|
||||
B8856CA8256F0F42001CE70E /* OWSBackupFragment.m in Sources */,
|
||||
C32C5C3D256DCBAF003C73A2 /* AppReadiness.m in Sources */,
|
||||
B87EF17126367CF800124B3C /* FileServerAPIV2.swift in Sources */,
|
||||
B87EF17126367CF800124B3C /* FileServerAPI.swift in Sources */,
|
||||
C3A3A18A256E2092004D228D /* SignalRecipient.m in Sources */,
|
||||
C3C2A74425539EB700C340D1 /* Message.swift in Sources */,
|
||||
C32C5F11256DF79A003C73A2 /* SSKIncrementingIdFinder.swift in Sources */,
|
||||
|
@ -5452,8 +5434,6 @@
|
|||
C32C5B62256DC333003C73A2 /* OWSDisappearingConfigurationUpdateInfoMessage.m in Sources */,
|
||||
FD83B9C927D0487A005E1583 /* SendDirectMessageResponse.swift in Sources */,
|
||||
C352A2F525574B4700338F3E /* Job.swift in Sources */,
|
||||
FDC4385727B484B700C60D73 /* LegacyFileUploadResponse.swift in Sources */,
|
||||
FDC4385B27B485DE00C60D73 /* LegacyFileDownloadResponse.swift in Sources */,
|
||||
C32C5C01256DC9A0003C73A2 /* OWSIdentityManager.m in Sources */,
|
||||
FDC438AA27BB12BB00C60D73 /* UserModeratorRequest.swift in Sources */,
|
||||
C32C59C4256DB41F003C73A2 /* TSContactThread.m in Sources */,
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
// TODO: Update this (looks like it's getting changed to just be the data, the properties are send through as headers)
|
||||
public struct FileDownloadResponse: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case fileName = "filename"
|
||||
case size
|
||||
case uploaded
|
||||
case expires
|
||||
case base64EncodedData = "result" // TODO: Confirm the name of this value
|
||||
}
|
||||
|
||||
public let fileName: String
|
||||
public let size: Int64
|
||||
public let uploaded: TimeInterval
|
||||
public let expires: TimeInterval?
|
||||
public let data: Data
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container: KeyedEncodingContainer<CodingKeys> = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(fileName, forKey: .fileName)
|
||||
try container.encode(size, forKey: .size)
|
||||
try container.encode(uploaded, forKey: .uploaded)
|
||||
try container.encodeIfPresent(expires, forKey: .expires)
|
||||
try container.encode(data.base64EncodedString(), forKey: .base64EncodedData)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Decoder
|
||||
|
||||
extension FileDownloadResponse {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container: KeyedDecodingContainer<CodingKeys> = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
let base64EncodedData: String = try container.decode(String.self, forKey: .base64EncodedData)
|
||||
|
||||
guard let data = Data(base64Encoded: base64EncodedData) else { throw HTTP.Error.parsingFailed }
|
||||
|
||||
self = FileDownloadResponse(
|
||||
fileName: try container.decode(String.self, forKey: .fileName),
|
||||
size: try container.decode(Int64.self, forKey: .size),
|
||||
uploaded: try container.decode(TimeInterval.self, forKey: .uploaded),
|
||||
expires: try? container.decode(TimeInterval.self, forKey: .expires),
|
||||
data: data
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
struct FileUploadBody: Codable {
|
||||
let file: String
|
||||
}
|
|
@ -1,5 +1,25 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
public struct FileUploadResponse: Codable {
|
||||
public let id: UInt64
|
||||
public let id: String
|
||||
}
|
||||
|
||||
// MARK: - Codable
|
||||
|
||||
extension FileUploadResponse {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container: KeyedDecodingContainer<CodingKeys> = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
// Note: SOGS returns an 'int' value but we want to avoid handling both cases so parse
|
||||
// that and convert the value to a string so we can be consistent (SOGS is able to handle
|
||||
// an array of Strings for the `files` param when posting a message just fine)
|
||||
if let intValue: Int64 = try? container.decode(Int64.self, forKey: .id) {
|
||||
self = FileUploadResponse(id: "\(intValue)")
|
||||
return
|
||||
}
|
||||
|
||||
self = FileUploadResponse(
|
||||
id: try container.decode(String.self, forKey: .id)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
struct LegacyFileDownloadResponse: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case base64EncodedData = "result"
|
||||
}
|
||||
|
||||
let data: Data
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container: KeyedEncodingContainer<CodingKeys> = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(data.base64EncodedString(), forKey: .base64EncodedData)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Decoder
|
||||
|
||||
extension LegacyFileDownloadResponse {
|
||||
init(from decoder: Decoder) throws {
|
||||
let container: KeyedDecodingContainer<CodingKeys> = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
let base64EncodedData: String = try container.decode(String.self, forKey: .base64EncodedData)
|
||||
|
||||
guard let data = Data(base64Encoded: base64EncodedData) else { throw HTTP.Error.parsingFailed }
|
||||
|
||||
self = LegacyFileDownloadResponse(
|
||||
data: data
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
struct LegacyFileUploadResponse: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case fileId = "result"
|
||||
}
|
||||
|
||||
public let fileId: UInt64
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import PromiseKit
|
||||
import SessionSnodeKit
|
||||
|
||||
@objc(SNFileServerAPIV2)
|
||||
public final class FileServerAPIV2 : NSObject {
|
||||
@objc(SNFileServerAPI)
|
||||
public final class FileServerAPI: NSObject {
|
||||
|
||||
// MARK: - Settings
|
||||
|
||||
|
@ -19,30 +19,27 @@ public final class FileServerAPIV2 : NSObject {
|
|||
/// possible after proof of work has been calculated and the onion request encryption has happened, which takes several seconds.
|
||||
public static let fileSizeORMultiplier: Double = 2
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
private override init() { }
|
||||
|
||||
// MARK: - File Storage
|
||||
|
||||
@objc(upload:)
|
||||
public static func objc_upload(file: Data) -> AnyPromise {
|
||||
return AnyPromise.from(upload(file).map { String($0) })
|
||||
return AnyPromise.from(upload(file).map { String($0.id) })
|
||||
}
|
||||
|
||||
public static func upload(_ file: Data) -> Promise<UInt64> {
|
||||
let requestBody: FileUploadBody = FileUploadBody(file: file.base64EncodedString())
|
||||
|
||||
public static func upload(_ file: Data) -> Promise<FileUploadResponse> {
|
||||
let request = Request(
|
||||
method: .post,
|
||||
server: server,
|
||||
endpoint: Endpoint.files,
|
||||
body: requestBody
|
||||
endpoint: Endpoint.file,
|
||||
headers: [
|
||||
.contentDisposition: "attachment",
|
||||
.contentType: "application/octet-stream"
|
||||
],
|
||||
body: Array(file)
|
||||
)
|
||||
|
||||
|
||||
return send(request, serverPublicKey: serverPublicKey)
|
||||
.decoded(as: LegacyFileUploadResponse.self, on: .global(qos: .userInitiated), error: HTTP.Error.parsingFailed)
|
||||
.map { response in response.fileId }
|
||||
.decoded(as: FileUploadResponse.self, on: .global(qos: .userInitiated))
|
||||
}
|
||||
|
||||
@objc(download:useOldServer:)
|
||||
|
@ -55,12 +52,10 @@ public final class FileServerAPIV2 : NSObject {
|
|||
let serverPublicKey: String = (useOldServer ? oldServerPublicKey : serverPublicKey)
|
||||
let request = Request<NoBody, Endpoint>(
|
||||
server: (useOldServer ? oldServer : server),
|
||||
endpoint: .file(fileId: file)
|
||||
endpoint: .fileIndividual(fileId: file)
|
||||
)
|
||||
|
||||
return send(request, serverPublicKey: serverPublicKey)
|
||||
.decoded(as: LegacyFileDownloadResponse.self, on: .global(qos: .userInitiated), error: HTTP.Error.parsingFailed)
|
||||
.map { response in response.data }
|
||||
}
|
||||
|
||||
public static func getVersion(_ platform: String) -> Promise<String> {
|
||||
|
@ -73,7 +68,7 @@ public final class FileServerAPIV2 : NSObject {
|
|||
)
|
||||
|
||||
return send(request, serverPublicKey: serverPublicKey)
|
||||
.decoded(as: VersionResponse.self, on: .global(qos: .userInitiated), error: HTTP.Error.parsingFailed)
|
||||
.decoded(as: VersionResponse.self, on: .global(qos: .userInitiated))
|
||||
.map { response in response.version }
|
||||
}
|
||||
|
||||
|
@ -93,7 +88,6 @@ public final class FileServerAPIV2 : NSObject {
|
|||
return Promise(error: error)
|
||||
}
|
||||
|
||||
// TODO: Rename file to be 'FileServerAPI' (drop the 'V2')
|
||||
return OnionRequestAPI.sendOnionRequest(urlRequest, to: request.server, with: serverPublicKey)
|
||||
.map2 { _, response in
|
||||
guard let response: Data = response else { throw HTTP.Error.parsingFailed }
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
extension FileServerAPIV2 {
|
||||
extension FileServerAPI {
|
||||
struct VersionResponse: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case version = "version"
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
extension FileServerAPIV2 {
|
||||
extension FileServerAPI {
|
||||
public enum Endpoint: EndpointType {
|
||||
case files
|
||||
case file(fileId: UInt64)
|
||||
case file
|
||||
case fileIndividual(fileId: UInt64)
|
||||
case sessionVersion
|
||||
|
||||
var path: String {
|
||||
switch self {
|
||||
case .files: return "files"
|
||||
case .file(let fileId): return "files/\(fileId)"
|
||||
case .file: return "file"
|
||||
case .fileIndividual(let fileId): return "file/\(fileId)"
|
||||
case .sessionVersion: return "session_version"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,60 +63,78 @@ public final class AttachmentDownloadJob : NSObject, Job, NSCoding { // NSObject
|
|||
if let id = id {
|
||||
JobQueue.currentlyExecutingJobs.insert(id)
|
||||
}
|
||||
|
||||
guard !isDeferred else { return }
|
||||
|
||||
if TSAttachment.fetch(uniqueId: attachmentID) is TSAttachmentStream {
|
||||
// FIXME: It's not clear * how * this happens, but apparently we can get to this point
|
||||
// from time to time with an already downloaded attachment.
|
||||
return handleSuccess()
|
||||
}
|
||||
|
||||
guard let pointer = TSAttachment.fetch(uniqueId: attachmentID) as? TSAttachmentPointer else {
|
||||
return handleFailure(error: Error.noAttachment)
|
||||
}
|
||||
|
||||
let storage = SNMessagingKitConfiguration.shared.storage
|
||||
storage.write(with: { transaction in
|
||||
storage.setAttachmentState(to: .downloading, for: pointer, associatedWith: self.tsMessageID, using: transaction)
|
||||
}, completion: { })
|
||||
|
||||
let temporaryFilePath = URL(fileURLWithPath: OWSTemporaryDirectoryAccessibleAfterFirstAuth() + UUID().uuidString)
|
||||
let handleFailure: (Swift.Error) -> Void = { error in // Intentionally capture self
|
||||
OWSFileSystem.deleteFile(temporaryFilePath.absoluteString)
|
||||
|
||||
if let error = error as? Error, case .noAttachment = error {
|
||||
storage.write(with: { transaction in
|
||||
storage.write { transaction in
|
||||
storage.setAttachmentState(to: .failed, for: pointer, associatedWith: self.tsMessageID, using: transaction)
|
||||
}, completion: { })
|
||||
}
|
||||
|
||||
self.handlePermanentFailure(error: error)
|
||||
} else if let error = error as? OnionRequestAPI.Error, case .httpRequestFailedAtDestination(let statusCode, _, _) = error,
|
||||
statusCode == 400 {
|
||||
}
|
||||
else if let error = error as? OnionRequestAPI.Error, case .httpRequestFailedAtDestination(let statusCode, _, _) = error, statusCode == 400 {
|
||||
// Otherwise, the attachment will show a state of downloading forever,
|
||||
// and the message won't be able to be marked as read.
|
||||
storage.write(with: { transaction in
|
||||
storage.write { transaction in
|
||||
storage.setAttachmentState(to: .failed, for: pointer, associatedWith: self.tsMessageID, using: transaction)
|
||||
}, completion: { })
|
||||
}
|
||||
|
||||
// This usually indicates a file that has expired on the server, so there's no need to retry.
|
||||
self.handlePermanentFailure(error: error)
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
self.handleFailure(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
if let tsMessage = TSMessage.fetch(uniqueId: tsMessageID), let openGroup = storage.getOpenGroup(for: tsMessage.uniqueThreadId) {
|
||||
guard let fileAsString = pointer.downloadURL.split(separator: "/").last, let fileId = UInt64(fileAsString) else {
|
||||
return handleFailure(Error.invalidURL)
|
||||
}
|
||||
// TODO: Upgrade this to use the non-legacy version
|
||||
OpenGroupAPI.legacyDownload(file, from: openGroup.room, on: openGroup.server).done(on: DispatchQueue.global(qos: .userInitiated)) { data in
|
||||
self.handleDownloadedAttachment(data: data, temporaryFilePath: temporaryFilePath, pointer: pointer, failureHandler: handleFailure)
|
||||
}.catch(on: DispatchQueue.global()) { error in
|
||||
handleFailure(error)
|
||||
}
|
||||
} else {
|
||||
|
||||
OpenGroupAPI
|
||||
.downloadFile(fileId, from: openGroup.room, on: openGroup.server)
|
||||
.done(on: DispatchQueue.global(qos: .userInitiated)) { [weak self] _, data in
|
||||
self?.handleDownloadedAttachment(data: data, temporaryFilePath: temporaryFilePath, pointer: pointer, failureHandler: handleFailure)
|
||||
}
|
||||
.catch(on: DispatchQueue.global()) { error in
|
||||
handleFailure(error)
|
||||
}
|
||||
}
|
||||
else {
|
||||
guard let fileAsString = pointer.downloadURL.split(separator: "/").last, let file = UInt64(fileAsString) else {
|
||||
return handleFailure(Error.invalidURL)
|
||||
}
|
||||
let useOldServer = pointer.downloadURL.contains(FileServerAPIV2.oldServer)
|
||||
FileServerAPIV2.download(file, useOldServer: useOldServer).done(on: DispatchQueue.global(qos: .userInitiated)) { data in
|
||||
self.handleDownloadedAttachment(data: data, temporaryFilePath: temporaryFilePath, pointer: pointer, failureHandler: handleFailure)
|
||||
}.catch(on: DispatchQueue.global()) { error in
|
||||
handleFailure(error)
|
||||
}
|
||||
|
||||
let useOldServer = pointer.downloadURL.contains(FileServerAPI.oldServer)
|
||||
FileServerAPI
|
||||
.download(file, useOldServer: useOldServer)
|
||||
.done(on: DispatchQueue.global(qos: .userInitiated)) { [weak self] data in
|
||||
self?.handleDownloadedAttachment(data: data, temporaryFilePath: temporaryFilePath, pointer: pointer, failureHandler: handleFailure)
|
||||
}
|
||||
.catch(on: DispatchQueue.global()) { error in
|
||||
handleFailure(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N
|
|||
stream,
|
||||
using: { data in
|
||||
OpenGroupAPI.uploadFile(data.bytes, to: openGroup.room, on: openGroup.server)
|
||||
.map { _, response -> UInt64 in response.id }
|
||||
.map { _, response -> String in response.id }
|
||||
},
|
||||
encrypt: false,
|
||||
onSuccess: { [weak self] fileId in self?.handleSuccess(fileId) },
|
||||
|
@ -84,7 +84,10 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N
|
|||
else {
|
||||
AttachmentUploadJob.upload(
|
||||
stream,
|
||||
using: FileServerAPIV2.upload,
|
||||
using: { data in
|
||||
FileServerAPI.upload(data)
|
||||
.map { response -> String in response.id }
|
||||
},
|
||||
encrypt: true,
|
||||
onSuccess: { [weak self] fileId in self?.handleSuccess(fileId) },
|
||||
onFailure: handleFailure
|
||||
|
@ -92,7 +95,7 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N
|
|||
}
|
||||
}
|
||||
|
||||
public static func upload(_ stream: TSAttachmentStream, using upload: (Data) -> Promise<UInt64>, encrypt: Bool, onSuccess: ((UInt64) -> Void)?, onFailure: ((Swift.Error) -> Void)?) {
|
||||
public static func upload(_ stream: TSAttachmentStream, using upload: (Data) -> Promise<String>, encrypt: Bool, onSuccess: ((String) -> Void)?, onFailure: ((Swift.Error) -> Void)?) {
|
||||
// Get the attachment
|
||||
guard var data = try? stream.readDataFromFile() else {
|
||||
SNLog("Couldn't read attachment from disk.")
|
||||
|
@ -112,7 +115,7 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N
|
|||
}
|
||||
// Check the file size
|
||||
SNLog("File size: \(data.count) bytes.")
|
||||
if Double(data.count) > Double(FileServerAPIV2.maxFileSize) / FileServerAPIV2.fileSizeORMultiplier {
|
||||
if Double(data.count) > Double(FileServerAPI.maxFileSize) / FileServerAPI.fileSizeORMultiplier {
|
||||
onFailure?(HTTP.Error.maxFileSizeExceeded)
|
||||
return
|
||||
}
|
||||
|
@ -121,7 +124,7 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N
|
|||
stream.isUploaded = false
|
||||
stream.save()
|
||||
upload(data).done(on: DispatchQueue.global(qos: .userInitiated)) { fileId in
|
||||
let downloadURL = "\(FileServerAPIV2.server)/files/\(fileId)"
|
||||
let downloadURL = "\(FileServerAPI.server)/files/\(fileId)"
|
||||
stream.serverId = fileId
|
||||
stream.isUploaded = true
|
||||
stream.downloadURL = downloadURL
|
||||
|
@ -132,7 +135,7 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N
|
|||
}
|
||||
}
|
||||
|
||||
private func handleSuccess(_ fileId: UInt64) {
|
||||
private func handleSuccess(_ fileId: String) {
|
||||
SNLog("Attachment uploaded successfully.")
|
||||
delegate?.handleJobSucceeded(self)
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ public final class MessageSendJob : NSObject, Job, NSCoding { // NSObject/NSCodi
|
|||
.replacingOccurrences(of: "]", with: "")
|
||||
.split(separator: "|")
|
||||
.map { String($0) }
|
||||
let fileIds: [UInt64]? = (fileIdStrings.isEmpty ? nil : fileIdStrings.compactMap { UInt64($0) })
|
||||
let fileIds: [String]? = (fileIdStrings.isEmpty ? nil : fileIdStrings)
|
||||
|
||||
destination = .openGroup(
|
||||
roomToken: roomToken,
|
||||
|
|
|
@ -10,11 +10,11 @@ public extension Message {
|
|||
server: String,
|
||||
whisperTo: String? = nil,
|
||||
whisperMods: Bool = false,
|
||||
fileIds: [UInt64]? = nil
|
||||
fileIds: [String]? = nil
|
||||
)
|
||||
case openGroupInbox(server: String, openGroupPublicKey: String, blindedPublicKey: String)
|
||||
|
||||
static func from(_ thread: TSThread, fileIds: [UInt64]? = nil) -> Message.Destination {
|
||||
static func from(_ thread: TSThread, fileIds: [String]? = nil) -> Message.Destination {
|
||||
if let thread = thread as? TSContactThread {
|
||||
if SessionId.Prefix(from: thread.contactSessionID()) == .blinded {
|
||||
guard let server: String = thread.originalOpenGroupServer, let publicKey: String = thread.originalOpenGroupPublicKey else {
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
extension OpenGroupAPI {
|
||||
public struct FileResponse: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case fileName = "filename"
|
||||
case size
|
||||
case uploaded
|
||||
case expires
|
||||
}
|
||||
|
||||
let fileName: String?
|
||||
let size: Int64
|
||||
let uploaded: TimeInterval
|
||||
let expires: TimeInterval?
|
||||
}
|
||||
}
|
|
@ -40,7 +40,12 @@ extension OpenGroupAPI {
|
|||
///
|
||||
/// When submitting a message edit this field must contain the IDs of any newly uploaded files that are part of the edit; existing
|
||||
/// attachment IDs may also be included, but are not required
|
||||
let fileIds: [UInt64]?
|
||||
///
|
||||
/// **Note:** The SOGS API actually expects an array of Int64 (ie. what is returned when uploading a file to SOGS) but
|
||||
/// when uploading direct to the FileServer we get a string id back. In order to avoid supporting both cases we convert
|
||||
/// the id returned by SOGS to a string and send those through - luckily SOGS converts the values to ints so supports
|
||||
/// receipving an array of String values
|
||||
let fileIds: [String]?
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
|
@ -49,7 +54,7 @@ extension OpenGroupAPI {
|
|||
signature: Data,
|
||||
whisperTo: String? = nil,
|
||||
whisperMods: Bool? = nil,
|
||||
fileIds: [UInt64]? = nil
|
||||
fileIds: [String]? = nil
|
||||
) {
|
||||
self.data = data
|
||||
self.signature = signature
|
||||
|
|
|
@ -331,7 +331,7 @@ public final class OpenGroupAPI: NSObject {
|
|||
on server: String,
|
||||
whisperTo: String?,
|
||||
whisperMods: Bool,
|
||||
fileIds: [UInt64]?,
|
||||
fileIds: [String]?,
|
||||
using dependencies: Dependencies = Dependencies()
|
||||
) -> Promise<(OnionRequestResponseInfoType, Message)> {
|
||||
guard let signResult: (publicKey: String, signature: Bytes) = sign(plaintext.bytes, for: server, using: dependencies) else {
|
||||
|
@ -558,16 +558,6 @@ public final class OpenGroupAPI: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
public static func downloadFileJson(_ fileId: UInt64, from roomToken: String, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, FileDownloadResponse)> {
|
||||
let request: Request = Request<NoBody, Endpoint>(
|
||||
server: server,
|
||||
endpoint: .roomFileIndividualJson(roomToken, fileId)
|
||||
)
|
||||
// TODO: This endpoint is getting rewritten to return just data (properties would come through as headers).
|
||||
return send(request, using: dependencies)
|
||||
.decoded(as: FileDownloadResponse.self, on: OpenGroupAPI.workQueue, using: dependencies)
|
||||
}
|
||||
|
||||
// MARK: - Inbox/Outbox (Message Requests)
|
||||
|
||||
/// Retrieves all of the user's current DMs (up to limit)
|
||||
|
|
|
@ -35,7 +35,6 @@ extension OpenGroupAPI {
|
|||
|
||||
case roomFile(String)
|
||||
case roomFileIndividual(String, UInt64)
|
||||
case roomFileIndividualJson(String, UInt64)
|
||||
|
||||
// Inbox/Outbox (Message Requests)
|
||||
|
||||
|
@ -125,14 +124,7 @@ extension OpenGroupAPI {
|
|||
// Files
|
||||
|
||||
case .roomFile(let roomToken): return "room/\(roomToken)/file"
|
||||
case .roomFileIndividual(let roomToken, let fileId):
|
||||
// Note: The 'fileName' value is ignored by the server and is only used to distinguish
|
||||
// this from the 'Json' variant
|
||||
let fileName: String = ""
|
||||
return "room/\(roomToken)/file/\(fileId)/\(fileName)"
|
||||
|
||||
case .roomFileIndividualJson(let roomToken, let fileId):
|
||||
return "room/\(roomToken)/file/\(fileId)"
|
||||
case .roomFileIndividual(let roomToken, let fileId): return "room/\(roomToken)/file/\(fileId)"
|
||||
|
||||
// Inbox/Outbox (Message Requests)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ typedef NS_ENUM(NSUInteger, TSAttachmentType) {
|
|||
// The attachmentSchemaVersion and serverId properties only apply to
|
||||
// TSAttachmentPointer, which can be distinguished by the isDownloaded
|
||||
// property.
|
||||
@property (atomic, readwrite) UInt64 serverId;
|
||||
@property (atomic, readwrite) NSString *serverId;
|
||||
@property (atomic, readwrite, nullable) NSData *encryptionKey;
|
||||
@property (nonatomic, readonly) NSString *contentType;
|
||||
@property (atomic, readwrite) BOOL isDownloaded;
|
||||
|
|
|
@ -27,7 +27,7 @@ NSUInteger const TSAttachmentSchemaVersion = 4;
|
|||
|
||||
// This constructor is used for new instances of TSAttachmentPointer,
|
||||
// i.e. undownloaded incoming attachments.
|
||||
- (instancetype)initWithServerId:(UInt64)serverId
|
||||
- (instancetype)initWithServerId:(NSString *)serverId
|
||||
encryptionKey:(nullable NSData *)encryptionKey
|
||||
byteCount:(UInt32)byteCount
|
||||
contentType:(NSString *)contentType
|
||||
|
|
|
@ -169,10 +169,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// Legacy instances of TSAttachmentPointer apparently used the serverId as their
|
||||
// uniqueId.
|
||||
if (attachmentSchemaVersion < 2 && self.serverId == 0) {
|
||||
if ([self isDecimalNumberText:self.uniqueId]) {
|
||||
// For legacy instances, try to parse the serverId from the uniqueId.
|
||||
self.serverId = (UInt64)[self.uniqueId integerValue];
|
||||
}
|
||||
// For legacy instances, try to parse the serverId from the uniqueId.
|
||||
self.serverId = self.uniqueId;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,15 +9,15 @@ extension OpenGroupAPI.Dependencies {
|
|||
}
|
||||
|
||||
public extension Data {
|
||||
func decoded<T: Decodable>(as type: T.Type, customError: Error? = nil, using dependencies: OpenGroupAPI.Dependencies = OpenGroupAPI.Dependencies()) throws -> T {
|
||||
func decoded<T: Decodable>(as type: T.Type, using dependencies: OpenGroupAPI.Dependencies = OpenGroupAPI.Dependencies()) throws -> T {
|
||||
do {
|
||||
let decoder: JSONDecoder = JSONDecoder()
|
||||
decoder.userInfo = [ OpenGroupAPI.Dependencies.userInfoKey: dependencies ]
|
||||
|
||||
return try decoder.decode(type, from: self)
|
||||
}
|
||||
catch let error {
|
||||
throw (customError ?? error)
|
||||
catch {
|
||||
throw HTTP.Error.parsingFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ import PromiseKit
|
|||
import SessionSnodeKit
|
||||
|
||||
extension Promise where T == Data {
|
||||
func decoded<R: Decodable>(as type: R.Type, on queue: DispatchQueue? = nil, error: Error? = nil, using dependencies: OpenGroupAPI.Dependencies = OpenGroupAPI.Dependencies()) -> Promise<R> {
|
||||
func decoded<R: Decodable>(as type: R.Type, on queue: DispatchQueue? = nil, using dependencies: OpenGroupAPI.Dependencies = OpenGroupAPI.Dependencies()) -> Promise<R> {
|
||||
self.map(on: queue) { data -> R in
|
||||
try data.decoded(as: type, customError: error, using: dependencies)
|
||||
try data.decoded(as: type, using: dependencies)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,6 +148,7 @@ class OpenGroupAPISpec: QuickSpec {
|
|||
testStorage = nil
|
||||
response = nil
|
||||
pollResponse = nil
|
||||
error = nil
|
||||
}
|
||||
|
||||
// MARK: - Batching & Polling
|
||||
|
@ -424,10 +425,10 @@ class OpenGroupAPISpec: QuickSpec {
|
|||
// MARK: - Files
|
||||
|
||||
context("when uploading files") {
|
||||
it("doesn't add a fileName header when not provided") {
|
||||
it("doesn't add a fileName to the content-disposition header when not provided") {
|
||||
class LocalTestApi: TestApi {
|
||||
override class var mockResponse: Data? {
|
||||
return try! JSONEncoder().encode(FileUploadResponse(id: 1))
|
||||
return try! JSONEncoder().encode(FileUploadResponse(id: "1"))
|
||||
}
|
||||
}
|
||||
dependencies = dependencies.with(api: LocalTestApi.self)
|
||||
|
@ -448,15 +449,15 @@ class OpenGroupAPISpec: QuickSpec {
|
|||
let requestData: TestApi.RequestData? = (response?.0 as? TestResponseInfo)?.requestData
|
||||
expect(requestData?.urlString).to(equal("testServer/room/testRoom/file"))
|
||||
expect(requestData?.httpMethod).to(equal("POST"))
|
||||
expect(requestData?.headers).to(haveCount(4))
|
||||
expect(requestData?.headers).to(haveCount(6))
|
||||
expect(requestData?.headers[Header.contentDisposition.rawValue])
|
||||
.toNot(contain("filename"))
|
||||
}
|
||||
|
||||
it("adds a fileName header when provided") {
|
||||
it("adds the fileName to the content-disposition header when provided") {
|
||||
class LocalTestApi: TestApi {
|
||||
override class var mockResponse: Data? {
|
||||
return try! JSONEncoder().encode(FileUploadResponse(id: 1))
|
||||
return try! JSONEncoder().encode(FileUploadResponse(id: "1"))
|
||||
}
|
||||
}
|
||||
dependencies = dependencies.with(api: LocalTestApi.self)
|
||||
|
@ -477,7 +478,7 @@ class OpenGroupAPISpec: QuickSpec {
|
|||
let requestData: TestApi.RequestData? = (response?.0 as? TestResponseInfo)?.requestData
|
||||
expect(requestData?.urlString).to(equal("testServer/room/testRoom/file"))
|
||||
expect(requestData?.httpMethod).to(equal("POST"))
|
||||
expect(requestData?.headers).to(haveCount(5))
|
||||
expect(requestData?.headers).to(haveCount(6))
|
||||
expect(requestData?.headers[Header.contentDisposition.rawValue]).to(contain("TestFileName"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ class TestStorage: SessionMessagingKitStorageProtocol, Mockable {
|
|||
func getAllPendingJobs(of type: Job.Type) -> [Job] { return [] }
|
||||
func getAttachmentUploadJob(for attachmentID: String) -> AttachmentUploadJob? { return nil }
|
||||
func getMessageSendJob(for messageSendJobID: String) -> MessageSendJob? { return nil }
|
||||
func getMessageSendJob(for messageSendJobID: String, using transaction: Any) -> MessageSendJob? { return nil }
|
||||
func resumeMessageSendJobIfNeeded(_ messageSendJobID: String) {}
|
||||
func isJobCanceled(_ job: Job) -> Bool { return true }
|
||||
|
||||
|
|
|
@ -644,17 +644,15 @@ public enum OnionRequestAPI: OnionRequestAPIType {
|
|||
let dataString: String = String(responseString.suffix(from: infoStringEndIndex))
|
||||
let dataStringParts: [String.SubSequence] = dataString.split(separator: ":")
|
||||
|
||||
guard dataStringParts.count > 1, let finalDataLength: Int = Int(dataStringParts[0]) else {
|
||||
guard dataStringParts.count > 1, let finalDataLength: Int = Int(dataStringParts[0]), let suffixData: Data = "e".data(using: .utf8) else {
|
||||
return seal.reject(HTTP.Error.invalidResponse)
|
||||
}
|
||||
|
||||
let finalDataStringStartIndex: String.Index = responseString.index(infoStringEndIndex, offsetBy: "\(finalDataLength):".count)
|
||||
let finalDataStringEndIndex: String.Index = responseString.index(finalDataStringStartIndex, offsetBy: finalDataLength)
|
||||
let finalDataString: String = String(responseString[finalDataStringStartIndex..<finalDataStringEndIndex])
|
||||
|
||||
guard let finalData: Data = finalDataString.data(using: .ascii) else {
|
||||
return seal.reject(HTTP.Error.invalidResponse)
|
||||
}
|
||||
let dataBytes: Array<UInt8> = Array(data)
|
||||
let dataEndIndex: Int = (dataBytes.count - suffixData.count)
|
||||
let dataStartIndex: Int = (dataEndIndex - finalDataLength)
|
||||
let finalDataBytes: ArraySlice<UInt8> = dataBytes[dataStartIndex..<dataEndIndex]
|
||||
let finalData: Data = Data(finalDataBytes)
|
||||
|
||||
return seal.fulfill((responseInfo, finalData))
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ public final class Configuration : NSObject {
|
|||
@objc public static func performMainSetup() {
|
||||
SNMessagingKit.configure(storage: Storage.shared)
|
||||
SNSnodeKit.configure(storage: Storage.shared)
|
||||
SNUtilitiesKit.configure(owsPrimaryStorage: OWSPrimaryStorage.shared(), maxFileSize: UInt(Double(FileServerAPIV2.maxFileSize) / FileServerAPIV2.fileSizeORMultiplier))
|
||||
SNUtilitiesKit.configure(
|
||||
owsPrimaryStorage: OWSPrimaryStorage.shared(),
|
||||
maxFileSize: UInt(Double(FileServerAPI.maxFileSize) / FileServerAPI.fileSizeORMultiplier)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,11 +43,11 @@ extension MessageSender {
|
|||
TSAttachment.fetch(uniqueId: $0, transaction: transaction) as? TSAttachmentStream
|
||||
}
|
||||
let attachmentsToUpload = attachments.filter { !$0.isUploaded }
|
||||
let attachmentUploadPromises: [Promise<UInt64>] = attachmentsToUpload.map { stream in
|
||||
let attachmentUploadPromises: [Promise<String>] = attachmentsToUpload.map { stream in
|
||||
let storage = SNMessagingKitConfiguration.shared.storage
|
||||
|
||||
if let threadId: String = thread.uniqueId, let openGroup = storage.getOpenGroup(for: threadId) {
|
||||
let (promise, seal) = Promise<UInt64>.pending()
|
||||
let (promise, seal) = Promise<String>.pending()
|
||||
AttachmentUploadJob.upload(
|
||||
stream,
|
||||
using: { data in
|
||||
|
@ -57,7 +57,7 @@ extension MessageSender {
|
|||
to: openGroup.room,
|
||||
on: openGroup.server
|
||||
)
|
||||
.map { _, response -> UInt64 in response.id }
|
||||
.map { _, response -> String in response.id }
|
||||
},
|
||||
encrypt: false,
|
||||
onSuccess: { fileId in seal.fulfill(fileId) },
|
||||
|
@ -67,10 +67,13 @@ extension MessageSender {
|
|||
return promise
|
||||
}
|
||||
|
||||
let (promise, seal) = Promise<UInt64>.pending()
|
||||
let (promise, seal) = Promise<String>.pending()
|
||||
AttachmentUploadJob.upload(
|
||||
stream,
|
||||
using: FileServerAPIV2.upload,
|
||||
using: { data in
|
||||
FileServerAPI.upload(data)
|
||||
.map { response -> String in response.id }
|
||||
},
|
||||
encrypt: true,
|
||||
onSuccess: { fileId in seal.fulfill(fileId) },
|
||||
onFailure: { seal.reject($0) }
|
||||
|
@ -84,7 +87,7 @@ extension MessageSender {
|
|||
if case .rejected(let error) = result { return error } else { return nil }
|
||||
}
|
||||
if let error = errors.first { return Promise(error: error) }
|
||||
let fileIds: [UInt64] = results.compactMap { result -> UInt64? in
|
||||
let fileIds: [String] = results.compactMap { result -> String? in
|
||||
switch result {
|
||||
case .fulfilled(let fileId): return fileId
|
||||
default: return nil
|
||||
|
@ -95,7 +98,7 @@ extension MessageSender {
|
|||
}
|
||||
}
|
||||
|
||||
public static func sendNonDurably(_ message: Message, in thread: TSThread, with fileIds: [UInt64]? = nil, using transaction: YapDatabaseReadWriteTransaction) -> Promise<Void> {
|
||||
public static func sendNonDurably(_ message: Message, in thread: TSThread, with fileIds: [String]? = nil, using transaction: YapDatabaseReadWriteTransaction) -> Promise<Void> {
|
||||
message.threadID = thread.uniqueId!
|
||||
let destination = Message.Destination.from(thread, fileIds: fileIds)
|
||||
return MessageSender.send(message, to: destination, using: transaction)
|
||||
|
@ -107,11 +110,11 @@ extension MessageSender {
|
|||
}
|
||||
let attachments = message.attachmentIDs.compactMap { TSAttachment.fetch(uniqueId: $0) as? TSAttachmentStream }
|
||||
let attachmentsToUpload = attachments.filter { !$0.isUploaded }
|
||||
let attachmentUploadPromises: [Promise<UInt64>] = attachmentsToUpload.map { stream in
|
||||
let attachmentUploadPromises: [Promise<String>] = attachmentsToUpload.map { stream in
|
||||
let storage = SNMessagingKitConfiguration.shared.storage
|
||||
|
||||
if let openGroup = storage.getOpenGroup(for: thread.uniqueId!) {
|
||||
let (promise, seal) = Promise<UInt64>.pending()
|
||||
let (promise, seal) = Promise<String>.pending()
|
||||
|
||||
AttachmentUploadJob.upload(
|
||||
stream,
|
||||
|
@ -122,7 +125,7 @@ extension MessageSender {
|
|||
to: openGroup.room,
|
||||
on: openGroup.server
|
||||
)
|
||||
.map { _, response in response.id }
|
||||
.map { _, response -> String in response.id }
|
||||
},
|
||||
encrypt: false,
|
||||
onSuccess: { fileId in seal.fulfill(fileId) },
|
||||
|
@ -131,10 +134,13 @@ extension MessageSender {
|
|||
return promise
|
||||
}
|
||||
|
||||
let (promise, seal) = Promise<UInt64>.pending()
|
||||
let (promise, seal) = Promise<String>.pending()
|
||||
AttachmentUploadJob.upload(
|
||||
stream,
|
||||
using: FileServerAPIV2.upload,
|
||||
using: { data in
|
||||
FileServerAPI.upload(data)
|
||||
.map { response -> String in response.id }
|
||||
},
|
||||
encrypt: true,
|
||||
onSuccess: { fileId in seal.fulfill(fileId) },
|
||||
onFailure: { seal.reject($0) }
|
||||
|
@ -148,7 +154,7 @@ extension MessageSender {
|
|||
if case .rejected(let error) = result { return error } else { return nil }
|
||||
}
|
||||
if let error = errors.first { seal.reject(error) }
|
||||
let fileIds: [UInt64] = results.compactMap { result -> UInt64? in
|
||||
let fileIds: [String] = results.compactMap { result -> String? in
|
||||
switch result {
|
||||
case .fulfilled(let fileId): return fileId
|
||||
default: return nil
|
||||
|
|
|
@ -268,10 +268,10 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error);
|
|||
NSData *encryptedAvatarData = [self encryptProfileData:avatarData profileKey:newProfileKey];
|
||||
OWSAssertDebug(encryptedAvatarData.length > 0);
|
||||
|
||||
AnyPromise *promise = [SNFileServerAPIV2 upload:encryptedAvatarData];
|
||||
AnyPromise *promise = [SNFileServerAPI upload:encryptedAvatarData];
|
||||
|
||||
[promise.thenOn(dispatch_get_main_queue(), ^(NSString *fileID) {
|
||||
NSString *downloadURL = [NSString stringWithFormat:@"%@/files/%@", SNFileServerAPIV2.server, fileID];
|
||||
NSString *downloadURL = [NSString stringWithFormat:@"%@/files/%@", SNFileServerAPI.server, fileID];
|
||||
[NSUserDefaults.standardUserDefaults setObject:[NSDate new] forKey:@"lastProfilePictureUpload"];
|
||||
|
||||
SNContact *user = [LKStorage.shared getUser];
|
||||
|
@ -502,8 +502,8 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error);
|
|||
NSString *profilePictureURL = contact.profilePictureURL;
|
||||
|
||||
NSString *file = [profilePictureURL lastPathComponent];
|
||||
BOOL useOldServer = [profilePictureURL containsString:SNFileServerAPIV2.oldServer];
|
||||
AnyPromise *promise = [SNFileServerAPIV2 download:file useOldServer:useOldServer];
|
||||
BOOL useOldServer = [profilePictureURL containsString:SNFileServerAPI.oldServer];
|
||||
AnyPromise *promise = [SNFileServerAPI download:file useOldServer:useOldServer];
|
||||
|
||||
[promise.then(^(NSData *data) {
|
||||
@synchronized(self.currentAvatarDownloads)
|
||||
|
|
Loading…
Reference in New Issue