Apply DataSource to message sender.

// FREEBIE
pull/1/head
Matthew Chen 8 years ago
parent 20e5013aae
commit b95b5f69de

@ -43,7 +43,8 @@ import PromiseKit
identityManager: self.identityManager,
profileManager: self.profileManager)
self.messageSender.sendTemporaryAttachmentData(syncContactsMessage.buildPlainTextAttachmentData(),
let dataSource = DataSourceValue.dataSource(withSyncMessage:syncContactsMessage.buildPlainTextAttachmentData())
self.messageSender.sendTemporaryAttachmentData(dataSource,
contentType: OWSMimeTypeApplicationOctetStream,
in: syncContactsMessage,
success: {

@ -4053,7 +4053,9 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
}];
if (newGroupModel.groupImage) {
[self.messageSender sendAttachmentData:UIImagePNGRepresentation(newGroupModel.groupImage)
NSData *data = UIImagePNGRepresentation(newGroupModel.groupImage);
id<DataSource> _Nullable dataSource = [DataSourceValue dataSourceWithData:data fileExtension:@"png"];
[self.messageSender sendAttachmentData:dataSource
contentType:OWSMimeTypeImagePng
sourceFilename:nil
inMessage:message

@ -952,8 +952,8 @@ NS_ASSUME_NONNULL_BEGIN
[[TSAttachmentStream alloc] initWithContentType:@"audio/mp3" sourceFilename:filename];
NSError *error;
[attachmentStream writeData:[self createRandomNSDataOfSize:16] error:&error];
OWSAssert(!error);
BOOL success = [attachmentStream writeData:[self createRandomNSDataOfSize:16] error:&error];
OWSAssert(success && !error);
[attachmentStream saveWithTransaction:transaction];
[message.attachmentIds addObject:attachmentStream.uniqueId];

@ -500,7 +500,10 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
[message updateWithCustomMessage:NSLocalizedString(@"GROUP_CREATED", nil)];
if (model.groupImage) {
[self.messageSender sendAttachmentData:UIImagePNGRepresentation(model.groupImage)
NSData *data = UIImagePNGRepresentation(model.groupImage);
id<DataSource> _Nullable dataSource =
[DataSourceValue dataSourceWithData:data fileExtension:@"png"];
[self.messageSender sendAttachmentData:dataSource
contentType:OWSMimeTypeImagePng
sourceFilename:nil
inMessage:message

@ -6,6 +6,7 @@
#import "OWSContactsManager.h"
#import "OWSProfileManager.h"
#import "TSAccountManager.h"
#import <SignalServiceKit/DataSource.h>
#import <SignalServiceKit/MIMETypeUtil.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSSyncContactsMessage.h>
@ -112,7 +113,9 @@ NSString *const kTSStorageManagerOWSContactsSyncingLastMessageKey =
self.isRequestInFlight = YES;
[self.messageSender sendTemporaryAttachmentData:[syncContactsMessage buildPlainTextAttachmentData]
id<DataSource> dataSource =
[DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]];
[self.messageSender sendTemporaryAttachmentData:dataSource
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncContactsMessage
success:^{

@ -115,7 +115,7 @@ NS_ASSUME_NONNULL_BEGIN
inThread:thread
isVoiceMessage:[attachment isVoiceMessage]
expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0)];
[messageSender sendAttachmentData:attachment.data
[messageSender sendAttachmentData:attachment.dataSource
contentType:attachment.mimeType
sourceFilename:attachment.filenameOrDefault
inMessage:message

@ -136,9 +136,6 @@
/* Accessibility label for attaching photos */
"ATTACHMENT_LABEL" = "Attachment";
/* Alert title when picking a document fails for an unknown reason */
"ATTACHMENT_PICKER_DOCUMENTS_FAILED_ALERT_TITLE" = "Failed to choose document.";
/* Alert body when picking a document fails because user picked a directory/bundle */
"ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_BODY" = "Signal can't handle that file as is. Try zipping it before sending.";
@ -520,6 +517,9 @@
/* Error mesage indicating that message send failed due to block list */
"ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_BLOCK_LIST" = "Failed to message user because you blocked them.";
/* Error mesage indicating that message send failed due to failed attachment write */
"ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_FAILED_ATTACHMENT_WRITE" = "Failed due to failed attachment write.";
/* Generic error used whenver Signal can't contact the server */
"ERROR_DESCRIPTION_NO_INTERNET" = "Signal was unable to connect to the internet. Please try from another WiFi network or use mobile data.";
@ -577,9 +577,6 @@
/* Message for the alert indicating the 'export with signal' attachment couldn't be loaded. */
"EXPORT_WITH_SIGNAL_ERROR_MESSAGE_MISSING_ATTACHMENT" = "Couldn't load file.";
/* Message for the alert indicating the 'export with signal' data couldn't be loaded. */
"EXPORT_WITH_SIGNAL_ERROR_MESSAGE_MISSING_DATA" = "Couldn't load file.";
/* Message for the alert indicating the 'export with signal' file had unknown type. */
"EXPORT_WITH_SIGNAL_ERROR_MESSAGE_UNKNOWN_TYPE" = "Unknown file type.";

@ -2,6 +2,7 @@
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "DataSource.h"
#import "TSAttachment.h"
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
@ -43,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable NSData *)readDataFromFileWithError:(NSError **)error;
- (BOOL)writeData:(NSData *)data error:(NSError **)error;
- (BOOL)writeDataSource:(id<DataSource>)dataSource;
+ (void)deleteAttachments;
+ (NSString *)attachmentsFolder;

@ -150,6 +150,8 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)writeData:(NSData *)data error:(NSError **)error
{
OWSAssert(data);
*error = nil;
NSString *_Nullable filePath = self.filePath;
if (!filePath) {
@ -161,6 +163,20 @@ NS_ASSUME_NONNULL_BEGIN
return [data writeToFile:filePath options:0 error:error];
}
- (BOOL)writeDataSource:(id<DataSource>)dataSource
{
OWSAssert(dataSource);
NSString *_Nullable filePath = self.filePath;
if (!filePath) {
DDLogError(@"%@ Missing path for attachment.", self.tag);
OWSAssert(0);
return NO;
}
DDLogInfo(@"%@ Writing attachment to file: %@", self.tag, filePath);
return [dataSource writeToPath:filePath];
}
+ (NSString *)attachmentsFolder
{
static NSString *attachmentsFolder = nil;

@ -2,6 +2,8 @@
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "DataSource.h"
NS_ASSUME_NONNULL_BEGIN
@class ContactsUpdater;
@ -70,7 +72,7 @@ NS_SWIFT_NAME(MessageSender)
* Takes care of allocating and uploading the attachment, then sends the message.
* Only necessary to call once. If sending fails, retry with `sendMessage:`.
*/
- (void)sendAttachmentData:(NSData *)attachmentData
- (void)sendAttachmentData:(id<DataSource>)dataSource
contentType:(NSString *)contentType
sourceFilename:(nullable NSString *)sourceFilename
inMessage:(TSOutgoingMessage *)outgoingMessage
@ -81,7 +83,7 @@ NS_SWIFT_NAME(MessageSender)
* Same as `sendAttachmentData:`, but deletes the local copy of the attachment after sending.
* Used for sending sync request data, not for user visible attachments.
*/
- (void)sendTemporaryAttachmentData:(NSData *)attachmentData
- (void)sendTemporaryAttachmentData:(id<DataSource>)dataSource
contentType:(NSString *)contentType
inMessage:(TSOutgoingMessage *)outgoingMessage
success:(void (^)())successHandler

@ -486,12 +486,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
failure:failureHandler];
}
- (void)sendTemporaryAttachmentData:(NSData *)attachmentData
- (void)sendTemporaryAttachmentData:(id<DataSource>)dataSource
contentType:(NSString *)contentType
inMessage:(TSOutgoingMessage *)message
success:(void (^)())successHandler
failure:(void (^)(NSError *error))failureHandler
{
OWSAssert(dataSource);
void (^successWithDeleteHandler)() = ^() {
successHandler();
@ -506,7 +508,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[message remove];
};
[self sendAttachmentData:attachmentData
[self sendAttachmentData:dataSource
contentType:contentType
sourceFilename:nil
inMessage:message
@ -514,19 +516,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
failure:failureWithDeleteHandler];
}
- (void)sendAttachmentData:(NSData *)data
- (void)sendAttachmentData:(id<DataSource>)dataSource
contentType:(NSString *)contentType
sourceFilename:(nullable NSString *)sourceFilename
inMessage:(TSOutgoingMessage *)message
success:(void (^)())successHandler
failure:(void (^)(NSError *error))failureHandler
{
// There's an odd bug wherein instances of NSData/Data created in Swift
// code reliably crash on iOS 9 when calling [NSData writeToFile:...].
// We can avoid these crashes by simply copying the Data.
//
// TODO: Move the iOSVersion header to SSK.
NSData *dataCopy = (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(10, 0) ? data : [data copy]);
OWSAssert(dataSource);
dispatch_async([OWSDispatch attachmentsQueue], ^{
TSAttachmentStream *attachmentStream =
@ -535,10 +532,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
attachmentStream.attachmentType = TSAttachmentTypeVoiceMessage;
}
NSError *error;
[attachmentStream writeData:dataCopy error:&error];
if (error) {
if (![attachmentStream writeDataSource:dataSource]) {
OWSProdError([OWSAnalyticsEvents messageSenderErrorCouldNotWriteAttachment]);
NSError *error = OWSErrorMakeWriteAttachmentDataError();
return failureHandler(error);
}

@ -6,6 +6,7 @@
#import "ContactsManagerProtocol.h"
#import "ContactsUpdater.h"
#import "Cryptography.h"
#import "DataSource.h"
#import "MimeTypeUtil.h"
#import "NSData+messagePadding.h"
#import "NSDate+millisecondTimeStamp.h"
@ -742,28 +743,30 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSSyncContactsMessage alloc] initWithSignalAccounts:self.contactsManager.signalAccounts
identityManager:self.identityManager
profileManager:self.profileManager];
[self.messageSender sendTemporaryAttachmentData:[syncContactsMessage buildPlainTextAttachmentData]
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncContactsMessage
success:^{
DDLogInfo(@"%@ Successfully sent Contacts response syncMessage.", self.tag);
}
failure:^(NSError *error) {
DDLogError(@"%@ Failed to send Contacts response syncMessage with error: %@", self.tag, error);
}];
id<DataSource> dataSource =
[DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]];
[self.messageSender sendTemporaryAttachmentData:dataSource
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncContactsMessage
success:^{
DDLogInfo(@"%@ Successfully sent Contacts response syncMessage.", self.tag);
}
failure:^(NSError *error) {
DDLogError(@"%@ Failed to send Contacts response syncMessage with error: %@", self.tag, error);
}];
} else if (syncMessage.request.type == OWSSignalServiceProtosSyncMessageRequestTypeGroups) {
OWSSyncGroupsMessage *syncGroupsMessage = [[OWSSyncGroupsMessage alloc] init];
[self.messageSender sendTemporaryAttachmentData:[syncGroupsMessage buildPlainTextAttachmentData]
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncGroupsMessage
success:^{
DDLogInfo(@"%@ Successfully sent Groups response syncMessage.", self.tag);
}
failure:^(NSError *error) {
DDLogError(@"%@ Failed to send Groups response syncMessage with error: %@", self.tag, error);
}];
id<DataSource> dataSource =
[DataSourceValue dataSourceWithSyncMessage:[syncGroupsMessage buildPlainTextAttachmentData]];
[self.messageSender sendTemporaryAttachmentData:dataSource
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncGroupsMessage
success:^{
DDLogInfo(@"%@ Successfully sent Groups response syncMessage.", self.tag);
}
failure:^(NSError *error) {
DDLogError(@"%@ Failed to send Groups response syncMessage with error: %@", self.tag, error);
}];
} else {
DDLogWarn(@"%@ ignoring unsupported sync request message", self.tag);
}
@ -878,7 +881,9 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(message);
if (gThread.groupModel.groupImage) {
[self.messageSender sendAttachmentData:UIImagePNGRepresentation(gThread.groupModel.groupImage)
NSData *data = UIImagePNGRepresentation(gThread.groupModel.groupImage);
id<DataSource> _Nullable dataSource = [DataSourceValue dataSourceWithData:data fileExtension:@"png"];
[self.messageSender sendAttachmentData:dataSource
contentType:OWSMimeTypeImagePng
sourceFilename:nil
inMessage:message

@ -42,6 +42,9 @@ NS_ASSUME_NONNULL_BEGIN
// Will return zero in the error case.
- (NSUInteger)dataLength;
// Returns YES on success.
- (BOOL)writeToPath:(NSString *)dstFilePath;
@end
#pragma mark -
@ -54,6 +57,8 @@ NS_ASSUME_NONNULL_BEGIN
+ (nullable id<DataSource>)dataSourceWithOversizeText:(NSString *_Nullable)text;
+ (id<DataSource>)dataSourceWithSyncMessage:(NSData *)data;
+ (id<DataSource>)emptyDataSource;
@end

@ -54,6 +54,11 @@ NS_ASSUME_NONNULL_BEGIN
return [self dataSourceWithData:data fileExtension:kOversizeTextAttachmentFileExtension];
}
+ (id<DataSource>)dataSourceWithSyncMessage:(NSData *)data
{
return [self dataSourceWithData:data fileExtension:kSyncMessageFileExtension];
}
+ (id<DataSource>)emptyDataSource
{
return [self dataSourceWithData:[NSData new] fileExtension:@"bin"];
@ -82,7 +87,8 @@ NS_ASSUME_NONNULL_BEGIN
NSString *dirPath = NSTemporaryDirectory();
NSString *fileName = [[[NSUUID UUID] UUIDString] stringByAppendingPathExtension:self.fileExtension];
NSString *filePath = [dirPath stringByAppendingPathComponent:fileName];
if ([self.dataValue writeToFile:fileName atomically:YES]) {
DDLogError(@"%@ ---- writing data", self.tag);
if ([self writeToPath:filePath]) {
self.cachedFilePath = filePath;
} else {
OWSFail(@"%@ Could not write data to disk: %@", self.tag, self.fileExtension);
@ -105,6 +111,24 @@ NS_ASSUME_NONNULL_BEGIN
return self.dataValue.length;
}
- (BOOL)writeToPath:(NSString *)dstFilePath
{
OWSAssert(self.dataValue);
// There's an odd bug wherein instances of NSData/Data created in Swift
// code reliably crash on iOS 9 when calling [NSData writeToFile:...].
// We can avoid these crashes by simply copying the Data.
NSData *dataCopy = (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(10, 0) ? self.dataValue : [self.dataValue copy]);
BOOL success = [dataCopy writeToFile:dstFilePath atomically:YES];
if (!success) {
OWSFail(@"%@ Could not write data to disk: %@", self.tag, dstFilePath);
return NO;
} else {
return YES;
}
}
#pragma mark - Logging
+ (NSString *)tag
@ -167,6 +191,7 @@ NS_ASSUME_NONNULL_BEGIN
@synchronized(self)
{
if (!self.cachedData) {
DDLogError(@"%@ ---- reading data", self.tag);
self.cachedData = [NSData dataWithContentsOfFile:self.filePath];
}
if (!self.cachedData) {
@ -220,6 +245,20 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (BOOL)writeToPath:(NSString *)dstFilePath
{
OWSAssert(self.filePath);
NSError *error;
BOOL success = [[NSFileManager defaultManager] copyItemAtPath:self.filePath toPath:dstFilePath error:&error];
if (!success || error) {
OWSFail(@"%@ Could not write data from path: %@, to path: %@", self.tag, self.filePath, dstFilePath);
return NO;
} else {
return YES;
}
}
#pragma mark - Logging
+ (NSString *)tag

@ -12,6 +12,7 @@ extern NSString *const OWSMimeTypeUnknownForTests;
extern NSString *const kOversizeTextAttachmentUTI;
extern NSString *const kOversizeTextAttachmentFileExtension;
extern NSString *const kUnknownTestAttachmentUTI;
extern NSString *const kSyncMessageFileExtension;
@interface MIMETypeUtil : NSObject

@ -19,6 +19,7 @@ NSString *const OWSMimeTypeUnknownForTests = @"unknown/mimetype";
NSString *const kOversizeTextAttachmentUTI = @"org.whispersystems.oversize-text-attachment";
NSString *const kOversizeTextAttachmentFileExtension = @"txt";
NSString *const kUnknownTestAttachmentUTI = @"org.whispersystems.unknown";
NSString *const kSyncMessageFileExtension = @"bin";
@implementation MIMETypeUtil

@ -25,6 +25,7 @@ typedef NS_ENUM(NSInteger, OWSErrorCode) {
OWSErrorCodeMessageSendFailedToBlockList = 777406,
OWSErrorCodeMessageSendNoValidRecipients = 777407,
OWSErrorCodeContactsUpdaterRateLimit = 777407,
OWSErrorCodeCouldNotWriteAttachmentData = 777408,
};
extern NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description);
@ -34,5 +35,6 @@ extern NSError *OWSErrorMakeNoSuchSignalRecipientError();
extern NSError *OWSErrorMakeAssertionError();
extern NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError();
extern NSError *OWSErrorMakeMessageSendFailedToBlockListError();
extern NSError *OWSErrorMakeWriteAttachmentDataError();
NS_ASSUME_NONNULL_END

@ -54,4 +54,11 @@ NSError *OWSErrorMakeMessageSendFailedToBlockListError()
@"Error mesage indicating that message send failed due to block list"));
}
NSError *OWSErrorMakeWriteAttachmentDataError()
{
return OWSErrorWithCodeDescription(OWSErrorCodeCouldNotWriteAttachmentData,
NSLocalizedString(@"ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_FAILED_ATTACHMENT_WRITE",
@"Error mesage indicating that message send failed due to failed attachment write"));
}
NS_ASSUME_NONNULL_END

Loading…
Cancel
Save