diff options
Diffstat (limited to 'src/smtp')
-rw-r--r-- | src/smtp/mimemessage.cpp | 426 | ||||
-rw-r--r-- | src/smtp/mimemultipart.cpp | 51 | ||||
-rw-r--r-- | src/smtp/mimepart.cpp | 155 |
3 files changed, 318 insertions, 314 deletions
diff --git a/src/smtp/mimemessage.cpp b/src/smtp/mimemessage.cpp index cf653e0a..6c058e89 100644 --- a/src/smtp/mimemessage.cpp +++ b/src/smtp/mimemessage.cpp @@ -17,26 +17,26 @@ */ #include "smtp/mimemessage.h" -#include "smtp/quotedprintable.h" #include <QDateTime> #include <QLocale> #include <typeinfo> +#include "smtp/quotedprintable.h" + /* [1] Constructors and Destructors */ MimeMessage::MimeMessage(bool createAutoMimeContent) - : replyTo(nullptr), hEncoding(MimePart::_8Bit) { - if (createAutoMimeContent) - this->content = new MimeMultiPart(); + : replyTo(nullptr), hEncoding(MimePart::_8Bit) { + if (createAutoMimeContent) this->content = new MimeMultiPart(); - autoMimeContentCreated = createAutoMimeContent; + autoMimeContentCreated = createAutoMimeContent; } MimeMessage::~MimeMessage() { - if (this->autoMimeContentCreated) { - this->autoMimeContentCreated = false; - delete (this->content); - } + if (this->autoMimeContentCreated) { + this->autoMimeContentCreated = false; + delete (this->content); + } } /* [1] --- */ @@ -45,34 +45,34 @@ MimeMessage::~MimeMessage() { MimePart &MimeMessage::getContent() { return *content; } void MimeMessage::setContent(MimePart *content) { - if (this->autoMimeContentCreated) { - this->autoMimeContentCreated = false; - delete (this->content); - } - this->content = content; + if (this->autoMimeContentCreated) { + this->autoMimeContentCreated = false; + delete (this->content); + } + this->content = content; } void MimeMessage::setReplyTo(EmailAddress *rto) { replyTo = rto; } void MimeMessage::setSender(EmailAddress *e) { - this->sender = e; - e->setParent(this); + this->sender = e; + e->setParent(this); } void MimeMessage::addRecipient(EmailAddress *rcpt, RecipientType type) { - switch (type) { - case To: - recipientsTo << rcpt; - break; - case Cc: - recipientsCc << rcpt; - break; - case Bcc: - recipientsBcc << rcpt; - break; - } - - rcpt->setParent(this); + switch (type) { + case To: + recipientsTo << rcpt; + break; + case Cc: + recipientsCc << rcpt; + break; + case Bcc: + recipientsBcc << rcpt; + break; + } + + rcpt->setParent(this); } void MimeMessage::addTo(EmailAddress *rcpt) { this->recipientsTo << rcpt; } @@ -82,36 +82,36 @@ void MimeMessage::addCc(EmailAddress *rcpt) { this->recipientsCc << rcpt; } void MimeMessage::addBcc(EmailAddress *rcpt) { this->recipientsBcc << rcpt; } void MimeMessage::setSubject(const QString &subject) { - this->subject = subject; + this->subject = subject; } void MimeMessage::addPart(MimePart *part) { - if (typeid(*content) == typeid(MimeMultiPart)) { - ((MimeMultiPart *) content)->addPart(part); - }; + if (typeid(*content) == typeid(MimeMultiPart)) { + ((MimeMultiPart *)content)->addPart(part); + }; } void MimeMessage::setInReplyTo(const QString &inReplyTo) { - mInReplyTo = inReplyTo; + mInReplyTo = inReplyTo; } void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc) { - this->hEncoding = hEnc; + this->hEncoding = hEnc; } const EmailAddress &MimeMessage::getSender() const { return *sender; } -const QList<EmailAddress *> & -MimeMessage::getRecipients(RecipientType type) const { - switch (type) { - default: - case To: - return recipientsTo; - case Cc: - return recipientsCc; - case Bcc: - return recipientsBcc; - } +const QList<EmailAddress *> &MimeMessage::getRecipients( + RecipientType type) const { + switch (type) { + default: + case To: + return recipientsTo; + case Cc: + return recipientsCc; + case Bcc: + return recipientsBcc; + } } const EmailAddress *MimeMessage::getReplyTo() const { return replyTo; } @@ -119,13 +119,13 @@ const EmailAddress *MimeMessage::getReplyTo() const { return replyTo; } const QString &MimeMessage::getSubject() const { return subject; } const QList<MimePart *> &MimeMessage::getParts() const { - if (typeid(*content) == typeid(MimeMultiPart)) { - return ((MimeMultiPart *) content)->getParts(); - } else { - auto *res = new QList<MimePart *>(); - res->append(content); - return *res; - } + if (typeid(*content) == typeid(MimeMultiPart)) { + return ((MimeMultiPart *)content)->getParts(); + } else { + auto *res = new QList<MimePart *>(); + res->append(content); + return *res; + } } /* [2] --- */ @@ -133,176 +133,180 @@ const QList<MimePart *> &MimeMessage::getParts() const { /* [3] Public Methods */ QString MimeMessage::toString() { - QString mime; - - /* =========== MIME HEADER ============ */ - - /* ---------- Sender / From ----------- */ - mime = "From:"; - if (sender->getName() != "") { - switch (hEncoding) { - case MimePart::Base64: - mime += " =?utf-8?B?" + - QByteArray().append(sender->getName().toUtf8()).toBase64() + "?="; - break; - case MimePart::QuotedPrintable: - mime += " =?utf-8?Q?" + - QuotedPrintable::encode( - QByteArray().append(sender->getName().toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; - default: - mime += " " + sender->getName(); - } + QString mime; + + /* =========== MIME HEADER ============ */ + + /* ---------- Sender / From ----------- */ + mime = "From:"; + if (!sender->getName().isEmpty()) { + switch (hEncoding) { + case MimePart::Base64: + mime += " =?utf-8?B?" + + QByteArray().append(sender->getName().toUtf8()).toBase64() + + "?="; + break; + case MimePart::QuotedPrintable: + mime += " =?utf-8?Q?" + + QuotedPrintable::encode( + QByteArray().append(sender->getName().toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; + default: + mime += " " + sender->getName(); } - mime += " <" + sender->getAddress() + ">\r\n"; - /* ---------------------------------- */ - - /* ------- Recipients / To ---------- */ - mime += "To:"; - QList<EmailAddress *>::iterator it; - int i; - for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i) { - if (i != 0) { - mime += ","; - } - - if ((*it)->getName() != "") { - switch (hEncoding) { - case MimePart::Base64: - mime += " =?utf-8?B?" + - QByteArray().append((*it)->getName().toUtf8()).toBase64() + - "?="; - break; - case MimePart::QuotedPrintable: - mime += " =?utf-8?Q?" + - QuotedPrintable::encode( - QByteArray().append((*it)->getName().toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; - default: - mime += " " + (*it)->getName(); - } - } - mime += " <" + (*it)->getAddress() + ">"; + } + mime += " <" + sender->getAddress() + ">\r\n"; + /* ---------------------------------- */ + + /* ------- Recipients / To ---------- */ + mime += "To:"; + QList<EmailAddress *>::iterator it; + int i; + for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i) { + if (i != 0) { + mime += ","; } - mime += "\r\n"; - /* ---------------------------------- */ - /* ------- Recipients / Cc ---------- */ - if (!recipientsCc.empty()) { - mime += "Cc:"; - } - for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i) { - if (i != 0) { - mime += ","; - } - - if ((*it)->getName() != "") { - switch (hEncoding) { - case MimePart::Base64: - mime += " =?utf-8?B?" + - QByteArray().append((*it)->getName().toUtf8()).toBase64() + - "?="; - break; - case MimePart::QuotedPrintable: - mime += " =?utf-8?Q?" + - QuotedPrintable::encode( - QByteArray().append((*it)->getName().toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; - default: - mime += " " + (*it)->getName(); - } - } - mime += " <" + (*it)->getAddress() + ">"; + if (!(*it)->getName().isEmpty()) { + switch (hEncoding) { + case MimePart::Base64: + mime += " =?utf-8?B?" + + QByteArray().append((*it)->getName().toUtf8()).toBase64() + + "?="; + break; + case MimePart::QuotedPrintable: + mime += " =?utf-8?Q?" + + QuotedPrintable::encode( + QByteArray().append((*it)->getName().toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; + default: + mime += " " + (*it)->getName(); + } } - if (!recipientsCc.empty()) { - mime += "\r\n"; + mime += " <" + (*it)->getAddress() + ">"; + } + mime += "\r\n"; + /* ---------------------------------- */ + + /* ------- Recipients / Cc ---------- */ + if (!recipientsCc.empty()) { + mime += "Cc:"; + } + for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i) { + if (i != 0) { + mime += ","; } - /* ---------------------------------- */ - /* ------------ Subject ------------- */ - mime += "Subject: "; - - switch (hEncoding) { + if ((*it)->getName() != "") { + switch (hEncoding) { case MimePart::Base64: - mime += "=?utf-8?B?" + QByteArray().append(subject.toUtf8()).toBase64() + "?="; - break; + mime += " =?utf-8?B?" + + QByteArray().append((*it)->getName().toUtf8()).toBase64() + + "?="; + break; case MimePart::QuotedPrintable: - mime += "=?utf-8?Q?" + - QuotedPrintable::encode(QByteArray().append(subject.toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; + mime += " =?utf-8?Q?" + + QuotedPrintable::encode( + QByteArray().append((*it)->getName().toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; default: - mime += subject; + mime += " " + (*it)->getName(); + } } + mime += " <" + (*it)->getAddress() + ">"; + } + if (!recipientsCc.empty()) { mime += "\r\n"; - /* ---------------------------------- */ - - /* ---------- Reply-To -------------- */ - if (replyTo) { - mime += "Reply-To: "; - if (replyTo->getName() != "") { - switch (hEncoding) { - case MimePart::Base64: - mime += " =?utf-8?B?" + - QByteArray().append(replyTo->getName().toUtf8()).toBase64() + "?="; - break; - case MimePart::QuotedPrintable: - mime += " =?utf-8?Q?" + - QuotedPrintable::encode(QByteArray().append(replyTo->getName().toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; - default: - mime += " " + replyTo->getName(); - } - } - mime += " <" + replyTo->getAddress() + ">\r\n"; - } - - /* ---------------------------------- */ - - mime += "MIME-Version: 1.0\r\n"; - if (!mInReplyTo.isEmpty()) { - mime += "In-Reply-To: <" + mInReplyTo + ">\r\n"; - mime += "References: <" + mInReplyTo + ">\r\n"; + } + /* ---------------------------------- */ + + /* ------------ Subject ------------- */ + mime += "Subject: "; + + switch (hEncoding) { + case MimePart::Base64: + mime += "=?utf-8?B?" + QByteArray().append(subject.toUtf8()).toBase64() + + "?="; + break; + case MimePart::QuotedPrintable: + mime += "=?utf-8?Q?" + + QuotedPrintable::encode(QByteArray().append(subject.toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; + default: + mime += subject; + } + mime += "\r\n"; + /* ---------------------------------- */ + + /* ---------- Reply-To -------------- */ + if (replyTo) { + mime += "Reply-To: "; + if (!replyTo->getName().isEmpty()) { + switch (hEncoding) { + case MimePart::Base64: + mime += " =?utf-8?B?" + + QByteArray().append(replyTo->getName().toUtf8()).toBase64() + + "?="; + break; + case MimePart::QuotedPrintable: + mime += " =?utf-8?Q?" + + QuotedPrintable::encode( + QByteArray().append(replyTo->getName().toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; + default: + mime += " " + replyTo->getName(); + } } - - QDateTime now = QDateTime::currentDateTime(); -#if QT_VERSION_MAJOR < 5 // Qt4 workaround since RFC2822Date isn't defined - QString shortDayName = - QLocale::c().dayName(now.date().dayOfWeek(), QLocale::ShortFormat); - QString shortMonthName = - QLocale::c().monthName(now.date().month(), QLocale::ShortFormat); - int utcOffset = now.secsTo(QDateTime(now.date(), now.time(), Qt::UTC)) / 60; - char timezoneSign = utcOffset >= 0 ? '+' : '-'; - utcOffset = utcOffset >= 0 ? utcOffset : -utcOffset; - QString timezone = QString("%1%2%3") - .arg(timezoneSign) - .arg(utcOffset / 60, 2, 10, QChar('0')) - .arg(utcOffset % 60, 2, 10, QChar('0')); - mime += QString("Date: %1\r\n") - .arg(now.toString("%1, dd %2 yyyy hh:mm:ss %3") - .arg(shortDayName) - .arg(shortMonthName) - .arg(timezone)); -#else // Qt5 supported - mime += QString("Date: %1\r\n").arg(now.toString(Qt::RFC2822Date)); -#endif // support RFC2822Date - - mime += content->toString(); - return mime; + mime += " <" + replyTo->getAddress() + ">\r\n"; + } + + /* ---------------------------------- */ + + mime += "MIME-Version: 1.0\r\n"; + if (!mInReplyTo.isEmpty()) { + mime += "In-Reply-To: <" + mInReplyTo + ">\r\n"; + mime += "References: <" + mInReplyTo + ">\r\n"; + } + + QDateTime now = QDateTime::currentDateTime(); +#if QT_VERSION_MAJOR < 5 // Qt4 workaround since RFC2822Date isn't defined + QString shortDayName = + QLocale::c().dayName(now.date().dayOfWeek(), QLocale::ShortFormat); + QString shortMonthName = + QLocale::c().monthName(now.date().month(), QLocale::ShortFormat); + int utcOffset = now.secsTo(QDateTime(now.date(), now.time(), Qt::UTC)) / 60; + char timezoneSign = utcOffset >= 0 ? '+' : '-'; + utcOffset = utcOffset >= 0 ? utcOffset : -utcOffset; + QString timezone = QString("%1%2%3") + .arg(timezoneSign) + .arg(utcOffset / 60, 2, 10, QChar('0')) + .arg(utcOffset % 60, 2, 10, QChar('0')); + mime += QString("Date: %1\r\n") + .arg(now.toString("%1, dd %2 yyyy hh:mm:ss %3") + .arg(shortDayName) + .arg(shortMonthName) + .arg(timezone)); +#else // Qt5 supported + mime += QString("Date: %1\r\n").arg(now.toString(Qt::RFC2822Date)); +#endif // support RFC2822Date + + mime += content->toString(); + return mime; } /* [3] --- */ diff --git a/src/smtp/mimemultipart.cpp b/src/smtp/mimemultipart.cpp index 14a813c2..4dd00d1a 100644 --- a/src/smtp/mimemultipart.cpp +++ b/src/smtp/mimemultipart.cpp @@ -17,30 +17,31 @@ */ #include "smtp/mimemultipart.h" + #include <QCryptographicHash> #include <QRandomGenerator> #include <QTime> const QString MULTI_PART_NAMES[] = { - "multipart/mixed", // Mixed - "multipart/digest", // Digest - "multipart/alternative", // Alternative - "multipart/related", // Related - "multipart/report", // Report - "multipart/signed", // Signed - "multipart/encrypted" // Encrypted + "multipart/mixed", // Mixed + "multipart/digest", // Digest + "multipart/alternative", // Alternative + "multipart/related", // Related + "multipart/report", // Report + "multipart/signed", // Signed + "multipart/encrypted" // Encrypted }; MimeMultiPart::MimeMultiPart(MultiPartType type) { - this->type = type; - this->cType = MULTI_PART_NAMES[this->type]; - this->cEncoding = _8Bit; + this->type = type; + this->cType = MULTI_PART_NAMES[this->type]; + this->cEncoding = _8Bit; - QRandomGenerator generator; + QRandomGenerator generator; - QCryptographicHash md5(QCryptographicHash::Md5); - md5.addData(QByteArray().append((char) generator.generate())); - cBoundary = md5.result().toHex(); + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(QByteArray().append((char)generator.generate())); + cBoundary = md5.result().toHex(); } void MimeMultiPart::addPart(MimePart *part) { parts.append(part); } @@ -48,23 +49,23 @@ void MimeMultiPart::addPart(MimePart *part) { parts.append(part); } const QList<MimePart *> &MimeMultiPart::getParts() const { return parts; } void MimeMultiPart::prepare() { - QList<MimePart *>::iterator it; + QList<MimePart *>::iterator it; - content = ""; - for (it = parts.begin(); it != parts.end(); it++) { - content += QString("--" + cBoundary + "\r\n").toUtf8(); - (*it)->prepare(); - content += (*it)->toString().toUtf8(); - }; + content.clear(); + for (it = parts.begin(); it != parts.end(); it++) { + content += QString("--" + cBoundary + "\r\n").toUtf8(); + (*it)->prepare(); + content += (*it)->toString().toUtf8(); + }; - content += QString("--" + cBoundary + "--\r\n").toUtf8(); + content += QString("--" + cBoundary + "--\r\n").toUtf8(); - MimePart::prepare(); + MimePart::prepare(); } void MimeMultiPart::setMimeType(const MultiPartType type) { - this->type = type; - this->cType = MULTI_PART_NAMES[type]; + this->type = type; + this->cType = MULTI_PART_NAMES[type]; } MimeMultiPart::MultiPartType MimeMultiPart::getMimeType() const { return type; } diff --git a/src/smtp/mimepart.cpp b/src/smtp/mimepart.cpp index 5d33884d..10aa6cbc 100644 --- a/src/smtp/mimepart.cpp +++ b/src/smtp/mimepart.cpp @@ -17,14 +17,15 @@ */ #include "smtp/mimepart.h" + #include "smtp/quotedprintable.h" /* [1] Constructors and Destructors */ MimePart::MimePart() { - cEncoding = _7Bit; - prepared = false; - cBoundary = ""; + cEncoding = _7Bit; + prepared = false; + cBoundary.clear(); } /* [1] --- */ @@ -32,13 +33,13 @@ MimePart::MimePart() { /* [2] Getters and Setters */ void MimePart::setContent(const QByteArray &content) { - this->content = content; + this->content = content; } void MimePart::setHeader(const QString &header) { this->header = header; } void MimePart::addHeaderLine(const QString &line) { - this->header += line + "\r\n"; + this->header += line + "\r\n"; } const QString &MimePart::getHeader() const { return header; } @@ -66,7 +67,7 @@ void MimePart::setEncoding(Encoding enc) { this->cEncoding = enc; } MimePart::Encoding MimePart::getEncoding() const { return this->cEncoding; } MimeContentFormatter &MimePart::getContentFormatter() { - return this->formatter; + return this->formatter; } /* [2] --- */ @@ -74,10 +75,9 @@ MimeContentFormatter &MimePart::getContentFormatter() { /* [3] Public methods */ QString MimePart::toString() { - if (!prepared) - prepare(); + if (!prepared) prepare(); - return mimeString; + return mimeString; } /* [3] --- */ @@ -85,75 +85,74 @@ QString MimePart::toString() { /* [4] Protected methods */ void MimePart::prepare() { - mimeString = QString(); - - /* === Header Prepare === */ - - /* Content-Type */ - mimeString.append("Content-Type: ").append(cType); - - if (cName != "") - mimeString.append("; name=\"").append(cName).append("\""); - - if (cCharset != "") - mimeString.append("; charset=").append(cCharset); - - if (cBoundary != "") - mimeString.append("; boundary=").append(cBoundary); - - mimeString.append("\r\n"); - /* ------------ */ - - /* Content-Transfer-Encoding */ - mimeString.append("Content-Transfer-Encoding: "); - switch (cEncoding) { - case _7Bit: - mimeString.append("7bit\r\n"); - break; - case _8Bit: - mimeString.append("8bit\r\n"); - break; - case Base64: - mimeString.append("base64\r\n"); - break; - case QuotedPrintable: - mimeString.append("quoted-printable\r\n"); - break; - } - /* ------------------------ */ - - /* Content-Id */ - if (cId != NULL) - mimeString.append("Content-ID: <").append(cId).append(">\r\n"); - /* ---------- */ - - /* Addition header lines */ - - mimeString.append(header).append("\r\n"); - - /* ------------------------- */ - - /* === End of Header Prepare === */ - - /* === Content === */ - switch (cEncoding) { - case _7Bit: - mimeString.append(QString(content).toLatin1()); - break; - case _8Bit: - mimeString.append(content); - break; - case Base64: - mimeString.append(formatter.format(content.toBase64())); - break; - case QuotedPrintable: - mimeString.append(formatter.format(QuotedPrintable::encode(content), true)); - break; - } - mimeString.append("\r\n"); - /* === End of Content === */ - - prepared = true; + mimeString = QString(); + + /* === Header Prepare === */ + + /* Content-Type */ + mimeString.append("Content-Type: ").append(cType); + + if (!cName.isEmpty()) + mimeString.append("; name=\"").append(cName).append("\""); + + if (!cCharset.isEmpty()) mimeString.append("; charset=").append(cCharset); + + if (!cBoundary.isEmpty()) mimeString.append("; boundary=").append(cBoundary); + + mimeString.append("\r\n"); + /* ------------ */ + + /* Content-Transfer-Encoding */ + mimeString.append("Content-Transfer-Encoding: "); + switch (cEncoding) { + case _7Bit: + mimeString.append("7bit\r\n"); + break; + case _8Bit: + mimeString.append("8bit\r\n"); + break; + case Base64: + mimeString.append("base64\r\n"); + break; + case QuotedPrintable: + mimeString.append("quoted-printable\r\n"); + break; + } + /* ------------------------ */ + + /* Content-Id */ + if (cId != nullptr) + mimeString.append("Content-ID: <").append(cId).append(">\r\n"); + /* ---------- */ + + /* Addition header lines */ + + mimeString.append(header).append("\r\n"); + + /* ------------------------- */ + + /* === End of Header Prepare === */ + + /* === Content === */ + switch (cEncoding) { + case _7Bit: + mimeString.append(QString(content).toLatin1()); + break; + case _8Bit: + mimeString.append(content); + break; + case Base64: + mimeString.append(formatter.format(content.toBase64())); + break; + case QuotedPrintable: + mimeString.append( + formatter.format(QuotedPrintable::encode(content), true)); + break; + } + mimeString.append("\r\n"); + /* === End of Content === */ + + prepared = true; } /* [4] --- */ |