aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/async/imap/MCIMAPAppendMessageOperation.cpp19
-rw-r--r--src/async/imap/MCIMAPAppendMessageOperation.h6
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.cpp12
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.h3
-rw-r--r--src/async/smtp/MCSMTPAsyncSession.cpp11
-rw-r--r--src/async/smtp/MCSMTPAsyncSession.h2
-rw-r--r--src/async/smtp/MCSMTPSendWithDataOperation.cpp16
-rw-r--r--src/async/smtp/MCSMTPSendWithDataOperation.h7
-rwxr-xr-xsrc/core/imap/MCIMAPSession.cpp12
-rwxr-xr-xsrc/core/imap/MCIMAPSession.h4
-rw-r--r--src/core/rfc822/MCMessageBuilder.cpp25
-rw-r--r--src/core/rfc822/MCMessageBuilder.h5
-rw-r--r--src/core/smtp/MCSMTPSession.cpp51
-rw-r--r--src/core/smtp/MCSMTPSession.h4
-rwxr-xr-xsrc/objc/imap/MCOIMAPSession.h18
-rwxr-xr-xsrc/objc/imap/MCOIMAPSession.mm12
-rw-r--r--src/objc/rfc822/MCOMessageBuilder.h3
-rw-r--r--src/objc/rfc822/MCOMessageBuilder.mm9
-rw-r--r--src/objc/smtp/MCOSMTPSession.h18
-rw-r--r--src/objc/smtp/MCOSMTPSession.mm13
-rw-r--r--tests/test-all.cpp95
21 files changed, 323 insertions, 22 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 96d34b73..4e92e97f 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/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/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
@@ -305,6 +305,24 @@
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.
MCOIMAPCopyMessagesOperation * op = [session copyMessagesOperationWithFolder:@"INBOX"
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/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 <MCOHTMLRendererDelegate>)delegate
{
MCOAbstractMessageRendererCallback * htmlRenderCallback = new MCOAbstractMessageRendererCallback(self, delegate, NULL);
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));
diff --git a/tests/test-all.cpp b/tests/test-all.cpp
index 02a4081c..c3e25ada 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;
}
@@ -200,6 +216,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;
@@ -291,6 +350,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)
{
@@ -411,12 +500,14 @@ void testAll()
//mailcore::Data * data = testMessageBuilder();
//testMessageParser(data);
//testSMTP(data);
+ //testSendingMessageFromFileViaSMTP(data);
//testIMAP();
//testIMAPMove();
//testIMAPCapability();
//testPOP();
//testNNTP();
//testAsyncSMTP(data);
+ //testAsyncSendMessageFromFileViaSMTP(data);
//testAsyncIMAP();
//testAsyncPOP();
//testAddresses();