From 908b7d4b8fdd7be43687450a36d56a6fb905ca25 Mon Sep 17 00:00:00 2001 From: Dmitry Isaikin Date: Wed, 3 Feb 2016 11:48:30 +0300 Subject: Add method for building message rfc822 body directly to file. --- src/core/rfc822/MCMessageBuilder.cpp | 25 +++++++++++++++++++++++++ src/core/rfc822/MCMessageBuilder.h | 5 ++++- src/objc/rfc822/MCOMessageBuilder.h | 3 +++ src/objc/rfc822/MCOMessageBuilder.mm | 9 +++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/core/rfc822/MCMessageBuilder.cpp b/src/core/rfc822/MCMessageBuilder.cpp index a98cefd1..b3a95249 100644 --- a/src/core/rfc822/MCMessageBuilder.cpp +++ b/src/core/rfc822/MCMessageBuilder.cpp @@ -810,6 +810,31 @@ Data * MessageBuilder::dataForEncryption() return dataAndFilterBccAndForEncryption(false, true); } +ErrorCode MessageBuilder::writeToFile(String * filename) +{ + FILE * f = fopen(filename->fileSystemRepresentation(), "wb"); + if (f == NULL) { + return ErrorFile; + } + + ErrorCode error = ErrorNone; + struct mailmime * mime = mimeAndFilterBccAndForEncryption(false, false); + + int col = 0; + int r = mailmime_write_file(f, &col, mime); + if (r != MAILIMF_NO_ERROR) { + error = ErrorFile; + } + + mailmime_free(mime); + + if (fclose(f) != 0) { + error = ErrorFile; + } + + return error; +} + String * MessageBuilder::htmlRendering(HTMLRendererTemplateCallback * htmlCallback) { MessageParser * message = MessageParser::messageParserWithData(data()); diff --git a/src/core/rfc822/MCMessageBuilder.h b/src/core/rfc822/MCMessageBuilder.h index f03bd09a..3d26ac59 100644 --- a/src/core/rfc822/MCMessageBuilder.h +++ b/src/core/rfc822/MCMessageBuilder.h @@ -40,7 +40,10 @@ namespace mailcore { virtual Data * data(); virtual Data * dataForEncryption(); - + + // Store builded message to file. + virtual ErrorCode writeToFile(String * filename); + virtual String * htmlRendering(HTMLRendererTemplateCallback * htmlCallback = NULL); virtual String * htmlBodyRendering(); diff --git a/src/objc/rfc822/MCOMessageBuilder.h b/src/objc/rfc822/MCOMessageBuilder.h index 1663d6f7..fbebb7f6 100644 --- a/src/objc/rfc822/MCOMessageBuilder.h +++ b/src/objc/rfc822/MCOMessageBuilder.h @@ -61,6 +61,9 @@ /** RFC 822 formatted message for encryption.*/ - (NSData *) dataForEncryption; +/** Store RFC 822 formatted message to file. */ +- (BOOL) writeToFile:(NSString *)filename error:(NSError **)error; + /** Returns an OpenPGP signed message with a given signature. The signature needs to be computed on the data returned by -dataForEncryption diff --git a/src/objc/rfc822/MCOMessageBuilder.mm b/src/objc/rfc822/MCOMessageBuilder.mm index 84cc37f2..31ebc742 100644 --- a/src/objc/rfc822/MCOMessageBuilder.mm +++ b/src/objc/rfc822/MCOMessageBuilder.mm @@ -70,6 +70,15 @@ MCO_OBJC_SYNTHESIZE_STRING(setBoundaryPrefix, boundaryPrefix) return MCO_OBJC_BRIDGE_GET(dataForEncryption); } +- (BOOL) writeToFile:(NSString *)filename error:(NSError **)error +{ + mailcore::ErrorCode errorCode = MCO_NATIVE_INSTANCE->writeToFile(MCO_FROM_OBJC(mailcore::String, filename)); + if (error) { + *error = [NSError mco_errorWithErrorCode:errorCode]; + } + return errorCode == mailcore::ErrorNone; +} + - (NSString *) htmlRenderingWithDelegate:(id )delegate { MCOAbstractMessageRendererCallback * htmlRenderCallback = new MCOAbstractMessageRendererCallback(self, delegate, NULL); -- cgit v1.2.3 From f9cdd2e6193cddfa405723eb70dda9261b26848d Mon Sep 17 00:00:00 2001 From: Dmitry Isaikin Date: Tue, 2 Feb 2016 19:23:58 +0300 Subject: Add file-based interface for sending messages via SMTP (reduce memory usage) --- src/async/imap/MCIMAPAppendMessageOperation.cpp | 19 ++++++++- src/async/imap/MCIMAPAppendMessageOperation.h | 6 ++- src/async/imap/MCIMAPAsyncSession.cpp | 12 ++++++ src/async/imap/MCIMAPAsyncSession.h | 3 +- src/async/smtp/MCSMTPAsyncSession.cpp | 11 ++++++ src/async/smtp/MCSMTPAsyncSession.h | 2 + src/async/smtp/MCSMTPSendWithDataOperation.cpp | 16 ++++++++ src/async/smtp/MCSMTPSendWithDataOperation.h | 7 +++- src/core/imap/MCIMAPSession.cpp | 12 ++++++ src/core/imap/MCIMAPSession.h | 4 +- src/core/smtp/MCSMTPSession.cpp | 51 +++++++++++++++++++------ src/core/smtp/MCSMTPSession.h | 4 +- src/objc/imap/MCOIMAPSession.h | 18 +++++++++ src/objc/imap/MCOIMAPSession.mm | 12 ++++++ src/objc/smtp/MCOSMTPSession.h | 18 +++++++++ src/objc/smtp/MCOSMTPSession.mm | 13 +++++++ 16 files changed, 189 insertions(+), 19 deletions(-) diff --git a/src/async/imap/MCIMAPAppendMessageOperation.cpp b/src/async/imap/MCIMAPAppendMessageOperation.cpp index 23eaaea0..69ed5c5f 100644 --- a/src/async/imap/MCIMAPAppendMessageOperation.cpp +++ b/src/async/imap/MCIMAPAppendMessageOperation.cpp @@ -16,6 +16,7 @@ using namespace mailcore; IMAPAppendMessageOperation::IMAPAppendMessageOperation() { mMessageData = NULL; + mMessageFilepath = NULL; mFlags = MessageFlagNone; mCustomFlags = NULL; mDate = (time_t) -1; @@ -25,6 +26,7 @@ IMAPAppendMessageOperation::IMAPAppendMessageOperation() IMAPAppendMessageOperation::~IMAPAppendMessageOperation() { MC_SAFE_RELEASE(mMessageData); + MC_SAFE_RELEASE(mMessageFilepath); MC_SAFE_RELEASE(mCustomFlags); } @@ -38,6 +40,16 @@ Data * IMAPAppendMessageOperation::messageData() return mMessageData; } +void IMAPAppendMessageOperation::setMessageFilepath(String * path) +{ + MC_SAFE_REPLACE_RETAIN(String, mMessageFilepath, path); +} + +String * IMAPAppendMessageOperation::messageFilepath() +{ + return mMessageFilepath; +} + void IMAPAppendMessageOperation::setFlags(MessageFlag flags) { mFlags = flags; @@ -76,7 +88,12 @@ uint32_t IMAPAppendMessageOperation::createdUID() void IMAPAppendMessageOperation::main() { ErrorCode error; - session()->session()->appendMessageWithCustomFlagsAndDate(folder(), mMessageData, mFlags, mCustomFlags, mDate, this, &mCreatedUID, &error); + if (mMessageFilepath != NULL) { + session()->session()->appendMessageWithCustomFlagsAndDate(folder(), mMessageFilepath, mFlags, mCustomFlags, mDate, this, &mCreatedUID, &error); + } + else { + session()->session()->appendMessageWithCustomFlagsAndDate(folder(), mMessageData, mFlags, mCustomFlags, mDate, this, &mCreatedUID, &error); + } setError(error); } diff --git a/src/async/imap/MCIMAPAppendMessageOperation.h b/src/async/imap/MCIMAPAppendMessageOperation.h index ca3033a6..f711c988 100644 --- a/src/async/imap/MCIMAPAppendMessageOperation.h +++ b/src/async/imap/MCIMAPAppendMessageOperation.h @@ -24,7 +24,10 @@ namespace mailcore { virtual void setMessageData(Data * messageData); virtual Data * messageData(); - + + virtual void setMessageFilepath(String * path); + virtual String * messageFilepath(); + virtual void setFlags(MessageFlag flags); virtual MessageFlag flags(); @@ -41,6 +44,7 @@ namespace mailcore { private: Data * mMessageData; + String * mMessageFilepath; MessageFlag mFlags; Array * mCustomFlags; time_t mDate; diff --git a/src/async/imap/MCIMAPAsyncSession.cpp b/src/async/imap/MCIMAPAsyncSession.cpp index 7f00d105..676d9bc5 100755 --- a/src/async/imap/MCIMAPAsyncSession.cpp +++ b/src/async/imap/MCIMAPAsyncSession.cpp @@ -443,6 +443,18 @@ IMAPAppendMessageOperation * IMAPAsyncSession::appendMessageOperation(String * f return op; } +IMAPAppendMessageOperation * IMAPAsyncSession::appendMessageOperation(String * folder, String * messagePath, MessageFlag flags, Array * customFlags) +{ + IMAPAppendMessageOperation * op = new IMAPAppendMessageOperation(); + op->setMainSession(this); + op->setFolder(folder); + op->setMessageFilepath(messagePath); + op->setFlags(flags); + op->setCustomFlags(customFlags); + op->autorelease(); + return op; +} + IMAPCopyMessagesOperation * IMAPAsyncSession::copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder) { IMAPCopyMessagesOperation * op = new IMAPCopyMessagesOperation(); diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index bbffacbd..b92d8017 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -120,7 +120,8 @@ namespace mailcore { virtual IMAPOperation * unsubscribeFolderOperation(String * folder); virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags, Array * customFlags = NULL); - + virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, String * messagePath, MessageFlag flags, Array * customFlags = NULL); + virtual IMAPCopyMessagesOperation * copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder); virtual IMAPMoveMessagesOperation * moveMessagesOperation(String * folder, IndexSet * uids, String * destFolder); diff --git a/src/async/smtp/MCSMTPAsyncSession.cpp b/src/async/smtp/MCSMTPAsyncSession.cpp index d2f645da..46b25184 100644 --- a/src/async/smtp/MCSMTPAsyncSession.cpp +++ b/src/async/smtp/MCSMTPAsyncSession.cpp @@ -240,6 +240,17 @@ SMTPOperation * SMTPAsyncSession::sendMessageOperation(Address * from, Array * r return (SMTPOperation *) op->autorelease(); } +SMTPOperation * SMTPAsyncSession::sendMessageOperation(Address * from, Array * recipients, + String * filename) +{ + SMTPSendWithDataOperation * op = new SMTPSendWithDataOperation(); + op->setSession(this); + op->setMessageFilepath(filename); + op->setFrom(from); + op->setRecipients(recipients); + return (SMTPOperation *) op->autorelease(); +} + SMTPOperation * SMTPAsyncSession::checkAccountOperation(Address * from) { SMTPCheckAccountOperation * op = new SMTPCheckAccountOperation(); diff --git a/src/async/smtp/MCSMTPAsyncSession.h b/src/async/smtp/MCSMTPAsyncSession.h index 90849797..961df6ef 100644 --- a/src/async/smtp/MCSMTPAsyncSession.h +++ b/src/async/smtp/MCSMTPAsyncSession.h @@ -68,6 +68,8 @@ namespace mailcore { virtual SMTPOperation * sendMessageOperation(Data * messageData); virtual SMTPOperation * sendMessageOperation(Address * from, Array * recipients, Data * messageData); + virtual SMTPOperation * sendMessageOperation(Address * from, Array * recipients, + String * filename); virtual SMTPOperation * checkAccountOperation(Address * from); virtual SMTPOperation * noopOperation(); diff --git a/src/async/smtp/MCSMTPSendWithDataOperation.cpp b/src/async/smtp/MCSMTPSendWithDataOperation.cpp index 03f6a530..4561b5d8 100644 --- a/src/async/smtp/MCSMTPSendWithDataOperation.cpp +++ b/src/async/smtp/MCSMTPSendWithDataOperation.cpp @@ -16,6 +16,7 @@ using namespace mailcore; SMTPSendWithDataOperation::SMTPSendWithDataOperation() { mMessageData = NULL; + mMessageFilepath = NULL; mFrom = NULL; mRecipients = NULL; } @@ -24,6 +25,7 @@ SMTPSendWithDataOperation::~SMTPSendWithDataOperation() { MC_SAFE_RELEASE(mFrom); MC_SAFE_RELEASE(mRecipients); + MC_SAFE_RELEASE(mMessageFilepath); MC_SAFE_RELEASE(mMessageData); } @@ -37,6 +39,16 @@ Data * SMTPSendWithDataOperation::messageData() return mMessageData; } +void SMTPSendWithDataOperation::setMessageFilepath(String * path) +{ + MC_SAFE_REPLACE_RETAIN(String, mMessageFilepath, path); +} + +String * SMTPSendWithDataOperation::messageFilepath() +{ + return mMessageFilepath; +} + void SMTPSendWithDataOperation::setFrom(Address * from) { MC_SAFE_REPLACE_COPY(Address, mFrom, from); @@ -60,6 +72,10 @@ Array * SMTPSendWithDataOperation::recipients() void SMTPSendWithDataOperation::main() { ErrorCode error; + if (mMessageFilepath != NULL) { + session()->session()->sendMessage(mFrom, mRecipients, mMessageFilepath, this, &error); + } + else if ((mFrom != NULL) && (mRecipients != NULL)) { session()->session()->sendMessage(mFrom, mRecipients, mMessageData, this, &error); } diff --git a/src/async/smtp/MCSMTPSendWithDataOperation.h b/src/async/smtp/MCSMTPSendWithDataOperation.h index a8ee2515..768adda9 100644 --- a/src/async/smtp/MCSMTPSendWithDataOperation.h +++ b/src/async/smtp/MCSMTPSendWithDataOperation.h @@ -31,15 +31,18 @@ namespace mailcore { virtual void setMessageData(Data * data); virtual Data * messageData(); - + + virtual void setMessageFilepath(String * path); + virtual String * messageFilepath(); + public: // subclass behavior virtual void main(); private: Data * mMessageData; + String * mMessageFilepath; Array * mRecipients; Address * mFrom; - }; } diff --git a/src/core/imap/MCIMAPSession.cpp b/src/core/imap/MCIMAPSession.cpp index c1209c9d..bc522896 100755 --- a/src/core/imap/MCIMAPSession.cpp +++ b/src/core/imap/MCIMAPSession.cpp @@ -1655,6 +1655,18 @@ void IMAPSession::appendMessageWithCustomFlagsAndDate(String * folder, Data * me * pError = ErrorNone; } +void IMAPSession::appendMessageWithCustomFlagsAndDate(String * folder, String * messagePath, MessageFlag flags, Array * customFlags, time_t date, + IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError) +{ + Data * messageData = Data::dataWithContentsOfFile(messagePath); + if (!messageData) { + * pError = ErrorFile; + return; + } + + return appendMessageWithCustomFlagsAndDate(folder, messageData, flags, customFlags, date, progressCallback, createdUID, pError); +} + void IMAPSession::copyMessages(String * folder, IndexSet * uidSet, String * destFolder, HashMap ** pUidMapping, ErrorCode * pError) { diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index c122e546..578350ac 100755 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -85,7 +85,9 @@ namespace mailcore { IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError); virtual void appendMessageWithCustomFlagsAndDate(String * folder, Data * messageData, MessageFlag flags, Array * customFlags, time_t date, IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError); - + virtual void appendMessageWithCustomFlagsAndDate(String * folder, String * messagePath, MessageFlag flags, Array * customFlags, time_t date, + IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError); + virtual void copyMessages(String * folder, IndexSet * uidSet, String * destFolder, HashMap ** pUidMapping, ErrorCode * pError); diff --git a/src/core/smtp/MCSMTPSession.cpp b/src/core/smtp/MCSMTPSession.cpp index d0711c65..8bcaefff 100644 --- a/src/core/smtp/MCSMTPSession.cpp +++ b/src/core/smtp/MCSMTPSession.cpp @@ -617,7 +617,7 @@ void SMTPSession::sendMessage(Address * from, Array * recipients, Data * message } messageData = dataWithFilteredBcc(messageData); - + mProgressCallback = callback; bodyProgress(0, messageData->length()); @@ -717,13 +717,28 @@ void SMTPSession::sendMessage(Address * from, Array * recipients, Data * message mProgressCallback = NULL; } +void SMTPSession::sendMessage(Address * from, Array * recipients, String * messagePath, + SMTPProgressCallback * callback, ErrorCode * pError) +{ + Data * messageData = Data::dataWithContentsOfFile(messagePath); + if (!messageData) { + * pError = ErrorFile; + return; + } + + return sendMessage(from, recipients, messageData, callback, pError); +} + +static void mmapStringDeallocator(char * bytes, unsigned int length) { + mmap_string_unref(bytes); +} + Data * SMTPSession::dataWithFilteredBcc(Data * data) { int r; size_t idx; struct mailimf_message * msg; - MMAPString * str; - + idx = 0; r = mailimf_message_parse(data->bytes(), data->length(), &idx, &msg); if (r != MAILIMF_NO_ERROR) { @@ -734,15 +749,16 @@ Data * SMTPSession::dataWithFilteredBcc(Data * data) int col = 0; int hasRecipient = 0; - str = mmap_string_new(""); + bool bccWasActuallyRemoved = false; for(clistiter * cur = clist_begin(fields->fld_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailimf_field * field = (struct mailimf_field *) clist_content(cur); if (field->fld_type == MAILIMF_FIELD_BCC) { mailimf_field_free(field); clist_delete(fields->fld_list, cur); + bccWasActuallyRemoved = true; break; } - else if ((field->fld_type == MAILIMF_FIELD_TO) || (field->fld_type == MAILIMF_FIELD_CC) || (field->fld_type == MAILIMF_FIELD_BCC)) { + else if ((field->fld_type == MAILIMF_FIELD_TO) || (field->fld_type == MAILIMF_FIELD_CC)) { hasRecipient = 1; } } @@ -754,13 +770,24 @@ Data * SMTPSession::dataWithFilteredBcc(Data * data) struct mailimf_field * field = mailimf_field_new(MAILIMF_FIELD_TO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, toField, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); mailimf_fields_add(fields, field); } - mailimf_fields_write_mem(str, &col, fields); - mmap_string_append(str, "\n"); - mmap_string_append_len(str, msg->msg_body->bd_text, msg->msg_body->bd_size); - - Data * result = Data::dataWithBytes(str->str, (unsigned int) str->len); - - mmap_string_free(str); + + Data * result; + if (!hasRecipient || bccWasActuallyRemoved) { + MMAPString * str = mmap_string_new(""); + mailimf_fields_write_mem(str, &col, fields); + mmap_string_append(str, "\n"); + mmap_string_append_len(str, msg->msg_body->bd_text, msg->msg_body->bd_size); + + mmap_string_ref(str); + + result = Data::data(); + result->takeBytesOwnership(str->str, (unsigned int) str->len, mmapStringDeallocator); + } + else { + // filter Bcc and modify To: only if necessary. + result = data; + } + mailimf_message_free(msg); return result; diff --git a/src/core/smtp/MCSMTPSession.h b/src/core/smtp/MCSMTPSession.h index 05571bfb..64ff30d0 100644 --- a/src/core/smtp/MCSMTPSession.h +++ b/src/core/smtp/MCSMTPSession.h @@ -60,7 +60,9 @@ namespace mailcore { virtual void sendMessage(Data * messageData, SMTPProgressCallback * callback, ErrorCode * pError); virtual void sendMessage(Address * from, Array * /* Address */ recipients, Data * messageData, SMTPProgressCallback * callback, ErrorCode * pError); - + virtual void sendMessage(Address * from, Array * /* Address */ recipients, String * messagePath, + SMTPProgressCallback * callback, ErrorCode * pError); + virtual void setConnectionLogger(ConnectionLogger * logger); virtual ConnectionLogger * connectionLogger(); diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index bab3be7f..6fd5f76e 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -304,6 +304,24 @@ flags:(MCOMessageFlag)flags customFlags:(NSArray *)customFlags; +/** + Returns an operation to add a message with custom flags to a folder. + + MCOIMAPOperation * op = [session appendMessageOperationWithFolder:@"Sent Mail" + contentsAtPath:rfc822DataFilename + flags:MCOMessageFlagNone + customFlags:@[@"$CNS-Greeting-On"]]; + [op start:^(NSError * __nullable error, uint32_t createdUID) { + if (error == nil) { + NSLog(@"created message with UID %lu", (unsigned long) createdUID); + } + }]; + */ +- (MCOIMAPAppendMessageOperation *)appendMessageOperationWithFolder:(NSString *)folder + contentsAtPath:(NSString *)path + flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags; + /** Returns an operation to copy messages to a folder. diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index 32dd1119..c245cdc3 100755 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -264,6 +264,18 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, return MCO_TO_OBJC_OP(coreOp); } +- (MCOIMAPAppendMessageOperation *)appendMessageOperationWithFolder:(NSString *)folder + contentsAtPath:(NSString *)path + flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags +{ + IMAPAppendMessageOperation * coreOp = MCO_NATIVE_INSTANCE->appendMessageOperation([folder mco_mcString], + MCO_FROM_OBJC(String, path), + (MessageFlag) flags, + MCO_FROM_OBJC(Array, customFlags)); + return MCO_TO_OBJC_OP(coreOp); +} + - (MCOIMAPCopyMessagesOperation *)copyMessagesOperationWithFolder:(NSString *)folder uids:(MCOIndexSet *)uids destFolder:(NSString *)destFolder diff --git a/src/objc/smtp/MCOSMTPSession.h b/src/objc/smtp/MCOSMTPSession.h index 31055335..84d6949d 100644 --- a/src/objc/smtp/MCOSMTPSession.h +++ b/src/objc/smtp/MCOSMTPSession.h @@ -154,6 +154,24 @@ from:(MCOAddress *)from recipients:(NSArray *)recipients; + +/** + Returns an operation that will send the message from the given file through SMTP. + It will use the sender and recipient set from the parameters. + It will also filter out Bcc from the content of the message. + + MCOSMTPOperation * op = [session sendOperationWithContentsOfFile:rfc822DataFilename + from:[MCOAddress addressWithMailbox:@"hoa@etpan.org"] + recipients:[NSArray arrayWithObject: + [MCOAddress addressWithMailbox:@"laura@etpan.org"]]]; + [op start:^(NSError * __nullable error) { + ... + }]; + */ +- (MCOSMTPSendOperation *) sendOperationWithContentsOfFile:(NSString *)path + from:(MCOAddress *)from + recipients:(NSArray *)recipients; + /** Returns an operation that will check whether the SMTP account is valid. diff --git a/src/objc/smtp/MCOSMTPSession.mm b/src/objc/smtp/MCOSMTPSession.mm index 9bcbd48e..9406a719 100644 --- a/src/objc/smtp/MCOSMTPSession.mm +++ b/src/objc/smtp/MCOSMTPSession.mm @@ -170,6 +170,19 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, return result; } +- (MCOSMTPSendOperation *) sendOperationWithContentsOfFile:(NSString *)path + from:(MCOAddress *)from + recipients:(NSArray *)recipients +{ + mailcore::SMTPOperation * coreOp = + MCO_NATIVE_INSTANCE->sendMessageOperation(MCO_FROM_OBJC(Address, from), + MCO_FROM_OBJC(Array, recipients), + MCO_FROM_OBJC(String, path)); + MCOSMTPSendOperation * result = [[[MCOSMTPSendOperation alloc] initWithMCOperation:coreOp] autorelease]; + [result setSession:self]; + return result; +} + - (MCOSMTPOperation *) checkAccountOperationWithFrom:(MCOAddress *)from { mailcore::SMTPOperation *coreOp = MCO_NATIVE_INSTANCE->checkAccountOperation(MCO_FROM_OBJC(mailcore::Address, from)); -- cgit v1.2.3 From d1e587a9cd06a9cf5f619642ec17506d589c687b Mon Sep 17 00:00:00 2001 From: Dmitry Isaikin Date: Tue, 9 Feb 2016 13:48:03 +0300 Subject: Some tests for MessageBuilder::writeToFile --- tests/test-all.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/test-all.cpp b/tests/test-all.cpp index 1858bef1..ba79a3ea 100644 --- a/tests/test-all.cpp +++ b/tests/test-all.cpp @@ -63,6 +63,16 @@ class TestCallback : public mailcore::Object, public mailcore::OperationCallback } }; +static mailcore::String * temporaryFilenameForTest() +{ + char tempfile[] = "/tmp/mailcore2-test-XXXXXX"; + char * result = mktemp(tempfile); + if (result == NULL) { + return NULL; + } + return mailcore::String::stringWithFileSystemRepresentation(tempfile); +} + static mailcore::Data * testMessageBuilder() { mailcore::Address * address = new mailcore::Address(); @@ -96,7 +106,12 @@ static mailcore::Data * testMessageBuilder() mailcore::Data * data = msg->data(); MCLog("%s", data->bytes()); - + + mailcore::String *filename = temporaryFilenameForTest(); + msg->writeToFile(filename); + mailcore::Data *fileData = mailcore::Data::dataWithContentsOfFile(filename); + MCAssert(data->isEqual(fileData)); + mailcore::MessageBuilder * msg2 = new mailcore::MessageBuilder(msg); mailcore::String *htmlBody = msg->htmlBody(); mailcore::String *htmlBody2 = msg2->htmlBody(); @@ -104,7 +119,8 @@ static mailcore::Data * testMessageBuilder() msg->release(); msg2->release(); - + unlink(filename->fileSystemRepresentation()); + return data; } -- cgit v1.2.3 From e554610cb5b5820eae81217066d594c6f1999089 Mon Sep 17 00:00:00 2001 From: Dmitry Isaikin Date: Tue, 9 Feb 2016 16:12:15 +0300 Subject: Add some tests for sending message from file via SMTP --- tests/test-all.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/tests/test-all.cpp b/tests/test-all.cpp index ba79a3ea..de5c50a6 100644 --- a/tests/test-all.cpp +++ b/tests/test-all.cpp @@ -197,6 +197,49 @@ static void testSMTP(mailcore::Data * data) smtp->release(); } +static void parseAddressesFromRfc822(mailcore::String * filename, mailcore::Array ** pRecipients, mailcore::Address ** pFrom) +{ + mailcore::MessageParser * parser = mailcore::MessageParser::messageParserWithContentsOfFile(filename); + + mailcore::Array * recipients = mailcore::Array::array(); + if (parser->header()->to() != NULL) { + recipients->addObjectsFromArray(parser->header()->to()); + } + if (parser->header()->cc() != NULL) { + recipients->addObjectsFromArray(parser->header()->cc()); + } + if (parser->header()->bcc() != NULL) { + recipients->addObjectsFromArray(parser->header()->bcc()); + } + *pRecipients = recipients; + *pFrom = parser->header()->from(); +} + +static void testSendingMessageFromFileViaSMTP(mailcore::Data * data) +{ + mailcore::SMTPSession * smtp; + mailcore::ErrorCode error; + + mailcore::String * filename = temporaryFilenameForTest(); + data->writeToFile(filename); + + smtp = new mailcore::SMTPSession(); + + smtp->setHostname(MCSTR("smtp.gmail.com")); + smtp->setPort(25); + smtp->setUsername(email); + smtp->setPassword(password); + smtp->setConnectionType(mailcore::ConnectionTypeStartTLS); + + mailcore::Array * recipients; + mailcore::Address * from; + parseAddressesFromRfc822(filename, &recipients, &from); + + smtp->sendMessage(from, recipients, filename, NULL, &error); + + smtp->release(); +} + static void testPOP() { mailcore::POPSession * session; @@ -288,6 +331,36 @@ static void testAsyncSMTP(mailcore::Data * data) //smtp->release(); } +static void testAsyncSendMessageFromFileViaSMTP(mailcore::Data * data) +{ + mailcore::SMTPAsyncSession * smtp; + TestSMTPCallback * callback = new TestSMTPCallback(); + + mailcore::String * filename = temporaryFilenameForTest(); + data->writeToFile(filename); + + mailcore::Array * recipients; + mailcore::Address * from; + parseAddressesFromRfc822(filename, &recipients, &from); + + smtp = new mailcore::SMTPAsyncSession(); + + smtp->setHostname(MCSTR("smtp.gmail.com")); + smtp->setPort(25); + smtp->setUsername(email); + smtp->setPassword(password); + smtp->setConnectionType(mailcore::ConnectionTypeStartTLS); + + mailcore::SMTPOperation * op = smtp->sendMessageOperation(from, recipients, filename); + op->setSmtpCallback(callback); + op->setCallback(callback); + op->start(); + + mainLoop(); + + //smtp->release(); +} + class TestIMAPCallback : public mailcore::Object, public mailcore::OperationCallback, public mailcore::IMAPOperationCallback { virtual void operationFinished(mailcore::Operation * op) { @@ -408,11 +481,13 @@ void testAll() //mailcore::Data * data = testMessageBuilder(); //testMessageParser(data); //testSMTP(data); + //testSendingMessageFromFileViaSMTP(data); //testIMAP(); //testIMAPMove(); //testPOP(); //testNNTP(); //testAsyncSMTP(data); + //testAsyncSendMessageFromFileViaSMTP(data); //testAsyncIMAP(); //testAsyncPOP(); //testAddresses(); -- cgit v1.2.3