diff options
author | Dmitry Isaikin <isaikin@corp.mail.ru> | 2016-02-02 19:23:58 +0300 |
---|---|---|
committer | Dmitry Isaikin <isaikin@corp.mail.ru> | 2016-02-09 15:53:40 +0300 |
commit | f9cdd2e6193cddfa405723eb70dda9261b26848d (patch) | |
tree | 0448dfc39864b9d52b55d5ad7a91d16d15bb2c71 /src/core | |
parent | 908b7d4b8fdd7be43687450a36d56a6fb905ca25 (diff) |
Add file-based interface for sending messages via SMTP (reduce memory usage)
Diffstat (limited to 'src/core')
-rwxr-xr-x | src/core/imap/MCIMAPSession.cpp | 12 | ||||
-rwxr-xr-x | src/core/imap/MCIMAPSession.h | 4 | ||||
-rw-r--r-- | src/core/smtp/MCSMTPSession.cpp | 51 | ||||
-rw-r--r-- | src/core/smtp/MCSMTPSession.h | 4 |
4 files changed, 57 insertions, 14 deletions
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(); |