Repair and adjust the SMTP library.
This commit is contained in:
parent
a0b5b56e8f
commit
39acbb05c1
@ -23,27 +23,29 @@
|
|||||||
|
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT EmailAddress : public QObject
|
class SMTP_EXPORT EmailAddress : public QObject {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
EmailAddress();
|
EmailAddress() = default;
|
||||||
EmailAddress(const QString & address, const QString & name="");
|
|
||||||
|
|
||||||
~EmailAddress();
|
explicit EmailAddress(const QString &address, const QString &name = "");
|
||||||
|
|
||||||
|
~EmailAddress() override;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
void setName(const QString & name);
|
void setName(const QString &name);
|
||||||
void setAddress(const QString & address);
|
|
||||||
|
|
||||||
const QString & getName() const;
|
void setAddress(const QString &address);
|
||||||
const QString & getAddress() const;
|
|
||||||
|
[[nodiscard]] const QString &getName() const;
|
||||||
|
|
||||||
|
[[nodiscard]] const QString &getAddress() const;
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
|
@ -25,17 +25,17 @@
|
|||||||
|
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT MimeAttachment : public MimeFile
|
class SMTP_EXPORT MimeAttachment : public MimeFile {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeAttachment(QFile* file);
|
explicit MimeAttachment(QFile *file);
|
||||||
MimeAttachment(const QByteArray& stream, const QString& fileName);
|
|
||||||
|
|
||||||
~MimeAttachment();
|
MimeAttachment(const QByteArray &stream, const QString &fileName);
|
||||||
|
|
||||||
|
~MimeAttachment() override;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ protected:
|
|||||||
|
|
||||||
/* [2] Protected methods */
|
/* [2] Protected methods */
|
||||||
|
|
||||||
virtual void prepare();
|
void prepare() override;
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
};
|
};
|
||||||
|
@ -24,16 +24,16 @@
|
|||||||
|
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT MimeContentFormatter : public QObject
|
class SMTP_EXPORT MimeContentFormatter : public QObject {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
MimeContentFormatter (int max_length = 76);
|
explicit MimeContentFormatter(int max_length = 76);
|
||||||
|
|
||||||
void setMaxLength(int l);
|
void setMaxLength(int l);
|
||||||
int getMaxLength() const;
|
|
||||||
|
|
||||||
QString format(const QString &content, bool quotedPrintable = false) const;
|
[[nodiscard]] int getMaxLength() const;
|
||||||
|
|
||||||
|
[[nodiscard]] QString format(const QString &content, bool quotedPrintable = false) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int max_length;
|
int max_length;
|
||||||
|
@ -24,16 +24,17 @@
|
|||||||
|
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT MimeFile : public MimePart
|
class SMTP_EXPORT MimeFile : public MimePart {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeFile(const QByteArray& stream, const QString& fileName);
|
MimeFile(const QByteArray &stream, const QString &fileName);
|
||||||
MimeFile(QFile *f);
|
|
||||||
~MimeFile();
|
explicit MimeFile(QFile *f);
|
||||||
|
|
||||||
|
~MimeFile() override;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
@ -46,14 +47,14 @@ protected:
|
|||||||
|
|
||||||
/* [3] Protected members */
|
/* [3] Protected members */
|
||||||
|
|
||||||
QFile* file;
|
QFile *file;
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
virtual void prepare();
|
void prepare() override;
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
@ -23,24 +23,24 @@
|
|||||||
|
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT MimeHtml : public MimeText
|
class SMTP_EXPORT MimeHtml : public MimeText {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeHtml(const QString &html = "");
|
explicit MimeHtml(const QString &html = "");
|
||||||
~MimeHtml();
|
|
||||||
|
~MimeHtml() override;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
void setHtml(const QString & html);
|
void setHtml(const QString &html);
|
||||||
|
|
||||||
const QString& getHtml() const;
|
[[nodiscard]] const QString &getHtml() const;
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
virtual void prepare();
|
void prepare() override;
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
};
|
};
|
||||||
|
@ -23,14 +23,14 @@
|
|||||||
|
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT MimeInlineFile : public MimeFile
|
class SMTP_EXPORT MimeInlineFile : public MimeFile {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeInlineFile(QFile *f);
|
explicit MimeInlineFile(QFile *f);
|
||||||
~MimeInlineFile();
|
|
||||||
|
~MimeInlineFile() override;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
virtual void prepare();
|
void prepare() override;
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
};
|
};
|
||||||
|
@ -26,8 +26,7 @@
|
|||||||
|
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT MimeMessage : public QObject
|
class SMTP_EXPORT MimeMessage : public QObject {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum RecipientType {
|
enum RecipientType {
|
||||||
@ -38,34 +37,47 @@ public:
|
|||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeMessage(bool createAutoMimeConent = true);
|
explicit MimeMessage(bool createAutoMimeConent = true);
|
||||||
~MimeMessage();
|
|
||||||
|
~MimeMessage() override;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
void setSender(EmailAddress* e);
|
void setSender(EmailAddress *e);
|
||||||
void addRecipient(EmailAddress* rcpt, RecipientType type = To);
|
|
||||||
void addTo(EmailAddress* rcpt);
|
|
||||||
void addCc(EmailAddress* rcpt);
|
|
||||||
void addBcc(EmailAddress* rcpt);
|
|
||||||
void setSubject(const QString & subject);
|
|
||||||
void addPart(MimePart* part);
|
|
||||||
void setReplyTo(EmailAddress* rto);
|
|
||||||
|
|
||||||
void setInReplyTo(const QString& inReplyTo);
|
void addRecipient(EmailAddress *rcpt, RecipientType type = To);
|
||||||
|
|
||||||
|
void addTo(EmailAddress *rcpt);
|
||||||
|
|
||||||
|
void addCc(EmailAddress *rcpt);
|
||||||
|
|
||||||
|
void addBcc(EmailAddress *rcpt);
|
||||||
|
|
||||||
|
void setSubject(const QString &subject);
|
||||||
|
|
||||||
|
void addPart(MimePart *part);
|
||||||
|
|
||||||
|
void setReplyTo(EmailAddress *rto);
|
||||||
|
|
||||||
|
void setInReplyTo(const QString &inReplyTo);
|
||||||
|
|
||||||
void setHeaderEncoding(MimePart::Encoding);
|
void setHeaderEncoding(MimePart::Encoding);
|
||||||
|
|
||||||
const EmailAddress & getSender() const;
|
[[nodiscard]] const EmailAddress &getSender() const;
|
||||||
const QList<EmailAddress*> & getRecipients(RecipientType type = To) const;
|
|
||||||
const QString & getSubject() const;
|
[[nodiscard]] const QList<EmailAddress *> &getRecipients(RecipientType type = To) const;
|
||||||
const QList<MimePart*> & getParts() const;
|
|
||||||
const EmailAddress* getReplyTo() const;
|
[[nodiscard]] const QString &getSubject() const;
|
||||||
|
|
||||||
|
[[nodiscard]] const QList<MimePart *> &getParts() const;
|
||||||
|
|
||||||
|
[[nodiscard]] const EmailAddress *getReplyTo() const;
|
||||||
|
|
||||||
|
MimePart &getContent();
|
||||||
|
|
||||||
MimePart& getContent();
|
|
||||||
void setContent(MimePart *content);
|
void setContent(MimePart *content);
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
@ -80,9 +92,9 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected members */
|
/* [4] Protected members */
|
||||||
|
|
||||||
EmailAddress* sender;
|
EmailAddress *sender{};
|
||||||
EmailAddress* replyTo;
|
EmailAddress *replyTo;
|
||||||
QList<EmailAddress*> recipientsTo, recipientsCc, recipientsBcc;
|
QList<EmailAddress *> recipientsTo, recipientsCc, recipientsBcc;
|
||||||
QString subject;
|
QString subject;
|
||||||
QString mInReplyTo;
|
QString mInReplyTo;
|
||||||
MimePart *content;
|
MimePart *content;
|
||||||
|
@ -24,49 +24,50 @@
|
|||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT MimeMultiPart : public MimePart {
|
class SMTP_EXPORT MimeMultiPart : public MimePart {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
/* [0] Enums */
|
/* [0] Enums */
|
||||||
enum MultiPartType {
|
enum MultiPartType {
|
||||||
Mixed = 0, // RFC 2046, section 5.1.3
|
Mixed = 0, // RFC 2046, section 5.1.3
|
||||||
Digest = 1, // RFC 2046, section 5.1.5
|
Digest = 1, // RFC 2046, section 5.1.5
|
||||||
Alternative = 2, // RFC 2046, section 5.1.4
|
Alternative = 2, // RFC 2046, section 5.1.4
|
||||||
Related = 3, // RFC 2387
|
Related = 3, // RFC 2387
|
||||||
Report = 4, // RFC 6522
|
Report = 4, // RFC 6522
|
||||||
Signed = 5, // RFC 1847, section 2.1
|
Signed = 5, // RFC 1847, section 2.1
|
||||||
Encrypted = 6 // RFC 1847, section 2.2
|
Encrypted = 6 // RFC 1847, section 2.2
|
||||||
};
|
};
|
||||||
|
|
||||||
/* [0] --- */
|
/* [0] --- */
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
MimeMultiPart(const MultiPartType type = Related);
|
explicit MimeMultiPart(MultiPartType type = Related);
|
||||||
|
|
||||||
~MimeMultiPart();
|
~MimeMultiPart() override;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
void setMimeType(const MultiPartType type);
|
void setMimeType(MultiPartType type);
|
||||||
MultiPartType getMimeType() const;
|
|
||||||
|
|
||||||
const QList<MimePart *> &getParts() const;
|
[[nodiscard]] MultiPartType getMimeType() const;
|
||||||
|
|
||||||
/* [2] --- */
|
[[nodiscard]] const QList<MimePart *> &getParts() const;
|
||||||
|
|
||||||
/* [3] Public methods */
|
/* [2] --- */
|
||||||
|
|
||||||
void addPart(MimePart *part);
|
/* [3] Public methods */
|
||||||
|
|
||||||
virtual void prepare();
|
void addPart(MimePart *part);
|
||||||
|
|
||||||
/* [3] --- */
|
void prepare() override;
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QList<MimePart *> parts;
|
QList<MimePart *> parts;
|
||||||
|
|
||||||
MultiPartType type;
|
MultiPartType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MIMEMULTIPART_H
|
#endif // MIMEMULTIPART_H
|
||||||
|
@ -25,76 +25,86 @@
|
|||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT MimePart : public QObject {
|
class SMTP_EXPORT MimePart : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
/* [0] Enumerations */
|
/* [0] Enumerations */
|
||||||
enum Encoding { _7Bit, _8Bit, Base64, QuotedPrintable };
|
enum Encoding {
|
||||||
|
_7Bit, _8Bit, Base64, QuotedPrintable
|
||||||
|
};
|
||||||
|
|
||||||
/* [0] --- */
|
/* [0] --- */
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimePart();
|
MimePart();
|
||||||
~MimePart();
|
|
||||||
|
|
||||||
/* [1] --- */
|
~MimePart() override;
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [1] --- */
|
||||||
|
|
||||||
const QString &getHeader() const;
|
/* [2] Getters and Setters */
|
||||||
const QByteArray &getContent() const;
|
|
||||||
|
|
||||||
void setContent(const QByteArray &content);
|
[[nodiscard]] const QString &getHeader() const;
|
||||||
void setHeader(const QString &header);
|
|
||||||
|
|
||||||
void addHeaderLine(const QString &line);
|
[[nodiscard]] const QByteArray &getContent() const;
|
||||||
|
|
||||||
void setContentId(const QString &cId);
|
void setContent(const QByteArray &content);
|
||||||
const QString &getContentId() const;
|
|
||||||
|
|
||||||
void setContentName(const QString &cName);
|
void setHeader(const QString &header);
|
||||||
const QString &getContentName() const;
|
|
||||||
|
|
||||||
void setContentType(const QString &cType);
|
void addHeaderLine(const QString &line);
|
||||||
const QString &getContentType() const;
|
|
||||||
|
|
||||||
void setCharset(const QString &charset);
|
void setContentId(const QString &cId);
|
||||||
const QString &getCharset() const;
|
|
||||||
|
|
||||||
void setEncoding(Encoding enc);
|
[[nodiscard]] const QString &getContentId() const;
|
||||||
Encoding getEncoding() const;
|
|
||||||
|
|
||||||
MimeContentFormatter &getContentFormatter();
|
void setContentName(const QString &cName);
|
||||||
|
|
||||||
/* [2] --- */
|
[[nodiscard]] const QString &getContentName() const;
|
||||||
|
|
||||||
/* [3] Public methods */
|
void setContentType(const QString &cType);
|
||||||
|
|
||||||
virtual QString toString();
|
[[nodiscard]] const QString &getContentType() const;
|
||||||
|
|
||||||
virtual void prepare();
|
void setCharset(const QString &charset);
|
||||||
|
|
||||||
/* [3] --- */
|
[[nodiscard]] const QString &getCharset() const;
|
||||||
|
|
||||||
|
void setEncoding(Encoding enc);
|
||||||
|
|
||||||
|
[[nodiscard]] Encoding getEncoding() const;
|
||||||
|
|
||||||
|
MimeContentFormatter &getContentFormatter();
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
/* [3] Public methods */
|
||||||
|
|
||||||
|
virtual QString toString();
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* [4] Protected members */
|
/* [4] Protected members */
|
||||||
|
|
||||||
QString header;
|
QString header;
|
||||||
QByteArray content;
|
QByteArray content;
|
||||||
|
|
||||||
QString cId;
|
QString cId;
|
||||||
QString cName;
|
QString cName;
|
||||||
QString cType;
|
QString cType;
|
||||||
QString cCharset;
|
QString cCharset;
|
||||||
QString cBoundary;
|
QString cBoundary;
|
||||||
Encoding cEncoding;
|
Encoding cEncoding;
|
||||||
|
|
||||||
QString mimeString;
|
QString mimeString;
|
||||||
bool prepared;
|
bool prepared;
|
||||||
|
|
||||||
MimeContentFormatter formatter;
|
MimeContentFormatter formatter;
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MIMEPART_H
|
#endif // MIMEPART_H
|
||||||
|
@ -23,23 +23,23 @@
|
|||||||
|
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT MimeText : public MimePart
|
class SMTP_EXPORT MimeText : public MimePart {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeText(const QString &text = "");
|
explicit MimeText(const QString &text = "");
|
||||||
~MimeText();
|
|
||||||
|
~MimeText() override;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [2] Getters and Setters*/
|
/* [2] Getters and Setters*/
|
||||||
|
|
||||||
void setText(const QString & text);
|
void setText(const QString &text);
|
||||||
|
|
||||||
const QString & getText() const;
|
[[nodiscard]] const QString &getText() const;
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
void prepare();
|
void prepare() override;
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
@ -24,12 +24,12 @@
|
|||||||
|
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT QuotedPrintable : public QObject
|
class SMTP_EXPORT QuotedPrintable : public QObject {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static QString encode(const QByteArray &input);
|
static QString encode(const QByteArray &input);
|
||||||
|
|
||||||
static QByteArray decode(const QString &input);
|
static QByteArray decode(const QString &input);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -25,21 +25,18 @@
|
|||||||
#include "mimemessage.h"
|
#include "mimemessage.h"
|
||||||
#include "smtpexports.h"
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_EXPORT SmtpClient : public QObject
|
class SMTP_EXPORT SmtpClient : public QObject {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [0] Enumerations */
|
/* [0] Enumerations */
|
||||||
|
|
||||||
enum AuthMethod
|
enum AuthMethod {
|
||||||
{
|
|
||||||
AuthPlain,
|
AuthPlain,
|
||||||
AuthLogin
|
AuthLogin
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SmtpError
|
enum SmtpError {
|
||||||
{
|
|
||||||
ConnectionTimeoutError,
|
ConnectionTimeoutError,
|
||||||
ResponseTimeoutError,
|
ResponseTimeoutError,
|
||||||
SendDataTimeoutError,
|
SendDataTimeoutError,
|
||||||
@ -48,8 +45,7 @@ public:
|
|||||||
ClientError // 5xx smtp error
|
ClientError // 5xx smtp error
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ConnectionType
|
enum ConnectionType {
|
||||||
{
|
|
||||||
TcpConnection,
|
TcpConnection,
|
||||||
SslConnection,
|
SslConnection,
|
||||||
TlsConnection // STARTTLS
|
TlsConnection // STARTTLS
|
||||||
@ -60,49 +56,60 @@ public:
|
|||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
SmtpClient(const QString & host = "localhost", int port = 25, ConnectionType ct = TcpConnection);
|
explicit SmtpClient(const QString &host = "localhost", int port = 25, ConnectionType ct = TcpConnection);
|
||||||
|
|
||||||
~SmtpClient();
|
~SmtpClient() override;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
const QString& getHost() const;
|
[[nodiscard]] const QString &getHost() const;
|
||||||
|
|
||||||
void setHost(const QString &host);
|
void setHost(const QString &host);
|
||||||
|
|
||||||
int getPort() const;
|
[[nodiscard]] int getPort() const;
|
||||||
|
|
||||||
void setPort(int port);
|
void setPort(int port);
|
||||||
|
|
||||||
const QString& getName() const;
|
[[nodiscard]] const QString &getName() const;
|
||||||
|
|
||||||
void setName(const QString &name);
|
void setName(const QString &name);
|
||||||
|
|
||||||
ConnectionType getConnectionType() const;
|
[[nodiscard]] ConnectionType getConnectionType() const;
|
||||||
|
|
||||||
void setConnectionType(ConnectionType ct);
|
void setConnectionType(ConnectionType ct);
|
||||||
|
|
||||||
const QString & getUser() const;
|
[[nodiscard]] const QString &getUser() const;
|
||||||
|
|
||||||
void setUser(const QString &user);
|
void setUser(const QString &user);
|
||||||
|
|
||||||
const QString & getPassword() const;
|
[[nodiscard]] const QString &getPassword() const;
|
||||||
|
|
||||||
void setPassword(const QString &password);
|
void setPassword(const QString &password);
|
||||||
|
|
||||||
SmtpClient::AuthMethod getAuthMethod() const;
|
[[nodiscard]] SmtpClient::AuthMethod getAuthMethod() const;
|
||||||
|
|
||||||
void setAuthMethod(AuthMethod method);
|
void setAuthMethod(AuthMethod method);
|
||||||
|
|
||||||
const QString & getResponseText() const;
|
[[nodiscard]] const QString &getResponseText() const;
|
||||||
int getResponseCode() const;
|
|
||||||
|
[[nodiscard]] int getResponseCode() const;
|
||||||
|
|
||||||
|
[[nodiscard]] int getConnectionTimeout() const;
|
||||||
|
|
||||||
int getConnectionTimeout() const;
|
|
||||||
void setConnectionTimeout(int msec);
|
void setConnectionTimeout(int msec);
|
||||||
|
|
||||||
int getResponseTimeout() const;
|
[[nodiscard]] int getResponseTimeout() const;
|
||||||
|
|
||||||
void setResponseTimeout(int msec);
|
void setResponseTimeout(int msec);
|
||||||
|
|
||||||
int getSendMessageTimeout() const;
|
[[nodiscard]] int getSendMessageTimeout() const;
|
||||||
|
|
||||||
void setSendMessageTimeout(int msec);
|
void setSendMessageTimeout(int msec);
|
||||||
|
|
||||||
QTcpSocket* getSocket();
|
QTcpSocket *getSocket();
|
||||||
|
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
@ -113,9 +120,10 @@ public:
|
|||||||
bool connectToHost();
|
bool connectToHost();
|
||||||
|
|
||||||
bool login();
|
bool login();
|
||||||
|
|
||||||
bool login(const QString &user, const QString &password, AuthMethod method = AuthLogin);
|
bool login(const QString &user, const QString &password, AuthMethod method = AuthLogin);
|
||||||
|
|
||||||
bool sendMail(MimeMessage& email);
|
bool sendMail(MimeMessage &email);
|
||||||
|
|
||||||
void quit();
|
void quit();
|
||||||
|
|
||||||
@ -140,14 +148,17 @@ protected:
|
|||||||
int connectionTimeout;
|
int connectionTimeout;
|
||||||
int responseTimeout;
|
int responseTimeout;
|
||||||
int sendMessageTimeout;
|
int sendMessageTimeout;
|
||||||
|
|
||||||
|
|
||||||
QString responseText;
|
QString responseText;
|
||||||
int responseCode;
|
int responseCode;
|
||||||
|
|
||||||
|
|
||||||
class ResponseTimeoutException {};
|
class ResponseTimeoutException : public std::exception {
|
||||||
class SendMessageTimeoutException {};
|
};
|
||||||
|
|
||||||
|
class SendMessageTimeoutException : public std::exception {
|
||||||
|
};
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
@ -165,7 +176,9 @@ protected slots:
|
|||||||
/* [6] Protected slots */
|
/* [6] Protected slots */
|
||||||
|
|
||||||
void socketStateChanged(QAbstractSocket::SocketState state);
|
void socketStateChanged(QAbstractSocket::SocketState state);
|
||||||
|
|
||||||
void socketError(QAbstractSocket::SocketError error);
|
void socketError(QAbstractSocket::SocketError error);
|
||||||
|
|
||||||
void socketReadyRead();
|
void socketReadyRead();
|
||||||
|
|
||||||
/* [6] --- */
|
/* [6] --- */
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
#define SMTPEXPORTS_H
|
#define SMTPEXPORTS_H
|
||||||
|
|
||||||
#ifdef SMTP_BUILD
|
#ifdef SMTP_BUILD
|
||||||
#define SMTP_EXPORT Q_DECL_EXPORT
|
#define SMTP_EXPORT
|
||||||
#else
|
#else
|
||||||
#define SMTP_EXPORT Q_DECL_IMPORT
|
#define SMTP_EXPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // SMTPEXPORTS_H
|
#endif // SMTPEXPORTS_H
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
EmailAddress::EmailAddress(const QString &address, const QString &name) {
|
EmailAddress::EmailAddress(const QString &address, const QString &name) {
|
||||||
this->address = address;
|
this->address = address;
|
||||||
this->name = name;
|
this->name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmailAddress::~EmailAddress() {}
|
EmailAddress::~EmailAddress() {}
|
||||||
@ -34,7 +34,7 @@ EmailAddress::~EmailAddress() {}
|
|||||||
void EmailAddress::setName(const QString &name) { this->name = name; }
|
void EmailAddress::setName(const QString &name) { this->name = name; }
|
||||||
|
|
||||||
void EmailAddress::setAddress(const QString &address) {
|
void EmailAddress::setAddress(const QString &address) {
|
||||||
this->address = address;
|
this->address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &EmailAddress::getName() const { return name; }
|
const QString &EmailAddress::getName() const { return name; }
|
||||||
|
@ -22,21 +22,22 @@
|
|||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeAttachment::MimeAttachment(QFile *file) : MimeFile(file) {}
|
MimeAttachment::MimeAttachment(QFile *file) : MimeFile(file) {}
|
||||||
|
|
||||||
MimeAttachment::MimeAttachment(const QByteArray &stream,
|
MimeAttachment::MimeAttachment(const QByteArray &stream,
|
||||||
const QString &fileName)
|
const QString &fileName)
|
||||||
: MimeFile(stream, fileName) {}
|
: MimeFile(stream, fileName) {}
|
||||||
|
|
||||||
MimeAttachment::~MimeAttachment() {}
|
MimeAttachment::~MimeAttachment() = default;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
/* [2] Protected methods */
|
/* [2] Protected methods */
|
||||||
|
|
||||||
void MimeAttachment::prepare() {
|
void MimeAttachment::prepare() {
|
||||||
this->header += "Content-disposition: attachment\r\n";
|
this->header += "Content-disposition: attachment\r\n";
|
||||||
|
|
||||||
/* !!! IMPORTANT !!! */
|
/* !!! IMPORTANT !!! */
|
||||||
MimeFile::prepare();
|
MimeFile::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
@ -19,39 +19,39 @@
|
|||||||
#include "smtp/mimecontentformatter.h"
|
#include "smtp/mimecontentformatter.h"
|
||||||
|
|
||||||
MimeContentFormatter::MimeContentFormatter(int max_length)
|
MimeContentFormatter::MimeContentFormatter(int max_length)
|
||||||
: max_length(max_length) {}
|
: max_length(max_length) {}
|
||||||
|
|
||||||
QString MimeContentFormatter::format(const QString &content,
|
QString MimeContentFormatter::format(const QString &content,
|
||||||
bool quotedPrintable) const {
|
bool quotedPrintable) const {
|
||||||
|
|
||||||
QString out;
|
QString out;
|
||||||
|
|
||||||
int chars = 0;
|
int chars = 0;
|
||||||
for (int i = 0; i < content.length(); ++i) {
|
for (auto i : content) {
|
||||||
chars++;
|
chars++;
|
||||||
if (!quotedPrintable) {
|
if (!quotedPrintable) {
|
||||||
if (chars > max_length) {
|
if (chars > max_length) {
|
||||||
out.append("\r\n");
|
out.append("\r\n");
|
||||||
chars = 1;
|
chars = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (content[i] == '\n') { // new line
|
if (i == '\n') { // new line
|
||||||
out.append(content[i]);
|
out.append(i);
|
||||||
chars = 0;
|
chars = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((chars > max_length - 1) ||
|
if ((chars > max_length - 1) ||
|
||||||
((content[i] == '=') && (chars > max_length - 3))) {
|
((i == '=') && (chars > max_length - 3))) {
|
||||||
out.append('=');
|
out.append('=');
|
||||||
out.append("\r\n");
|
out.append("\r\n");
|
||||||
chars = 1;
|
chars = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
out.append(i);
|
||||||
}
|
}
|
||||||
out.append(content[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeContentFormatter::setMaxLength(int l) { max_length = l; }
|
void MimeContentFormatter::setMaxLength(int l) { max_length = l; }
|
||||||
|
@ -22,22 +22,21 @@
|
|||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeFile::MimeFile(QFile *file) {
|
MimeFile::MimeFile(QFile *file) {
|
||||||
this->file = file;
|
this->file = file;
|
||||||
this->cType = "application/octet-stream";
|
this->cType = "application/octet-stream";
|
||||||
this->cName = QFileInfo(*file).fileName();
|
this->cName = QFileInfo(*file).fileName();
|
||||||
this->cEncoding = Base64;
|
this->cEncoding = Base64;
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeFile::MimeFile(const QByteArray &stream, const QString &fileName) {
|
MimeFile::MimeFile(const QByteArray &stream, const QString &fileName) {
|
||||||
this->cEncoding = Base64;
|
this->cEncoding = Base64;
|
||||||
this->cType = "application/octet-stream";
|
this->cType = "application/octet-stream";
|
||||||
this->file = 0;
|
this->file = nullptr;
|
||||||
this->cName = fileName;
|
this->cName = fileName;
|
||||||
this->content = stream;
|
this->content = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeFile::~MimeFile() {
|
MimeFile::~MimeFile() {
|
||||||
if (file)
|
|
||||||
delete file;
|
delete file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,13 +49,13 @@ MimeFile::~MimeFile() {
|
|||||||
/* [3] Protected methods */
|
/* [3] Protected methods */
|
||||||
|
|
||||||
void MimeFile::prepare() {
|
void MimeFile::prepare() {
|
||||||
if (this->file) {
|
if (this->file) {
|
||||||
file->open(QIODevice::ReadOnly);
|
file->open(QIODevice::ReadOnly);
|
||||||
this->content = file->readAll();
|
this->content = file->readAll();
|
||||||
file->close();
|
file->close();
|
||||||
}
|
}
|
||||||
/* !!! IMPORTANT !!!! */
|
/* !!! IMPORTANT !!!! */
|
||||||
MimePart::prepare();
|
MimePart::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeHtml::MimeHtml(const QString &html) : MimeText(html) {
|
MimeHtml::MimeHtml(const QString &html) : MimeText(html) {
|
||||||
this->cType = "text/html";
|
this->cType = "text/html";
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeHtml::~MimeHtml() {}
|
MimeHtml::~MimeHtml() = default;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
@ -39,8 +39,8 @@ const QString &MimeHtml::getHtml() const { return text; }
|
|||||||
/* [3] Protected methods */
|
/* [3] Protected methods */
|
||||||
|
|
||||||
void MimeHtml::prepare() {
|
void MimeHtml::prepare() {
|
||||||
/* !!! IMPORTANT !!! */
|
/* !!! IMPORTANT !!! */
|
||||||
MimeText::prepare();
|
MimeText::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
MimeInlineFile::MimeInlineFile(QFile *f) : MimeFile(f) {}
|
MimeInlineFile::MimeInlineFile(QFile *f) : MimeFile(f) {}
|
||||||
|
|
||||||
MimeInlineFile::~MimeInlineFile() {}
|
MimeInlineFile::~MimeInlineFile() = default;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
@ -33,10 +33,10 @@ MimeInlineFile::~MimeInlineFile() {}
|
|||||||
/* [3] Protected methods */
|
/* [3] Protected methods */
|
||||||
|
|
||||||
void MimeInlineFile::prepare() {
|
void MimeInlineFile::prepare() {
|
||||||
this->header += "Content-Disposition: inline\r\n";
|
this->header += "Content-Disposition: inline\r\n";
|
||||||
|
|
||||||
/* !!! IMPORTANT !!! */
|
/* !!! IMPORTANT !!! */
|
||||||
MimeFile::prepare();
|
MimeFile::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -25,18 +25,18 @@
|
|||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
MimeMessage::MimeMessage(bool createAutoMimeContent)
|
MimeMessage::MimeMessage(bool createAutoMimeContent)
|
||||||
: replyTo(nullptr), hEncoding(MimePart::_8Bit) {
|
: replyTo(nullptr), hEncoding(MimePart::_8Bit) {
|
||||||
if (createAutoMimeContent)
|
if (createAutoMimeContent)
|
||||||
this->content = new MimeMultiPart();
|
this->content = new MimeMultiPart();
|
||||||
|
|
||||||
autoMimeContentCreated = createAutoMimeContent;
|
autoMimeContentCreated = createAutoMimeContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeMessage::~MimeMessage() {
|
MimeMessage::~MimeMessage() {
|
||||||
if (this->autoMimeContentCreated) {
|
if (this->autoMimeContentCreated) {
|
||||||
this->autoMimeContentCreated = false;
|
this->autoMimeContentCreated = false;
|
||||||
delete (this->content);
|
delete (this->content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
@ -45,34 +45,34 @@ MimeMessage::~MimeMessage() {
|
|||||||
MimePart &MimeMessage::getContent() { return *content; }
|
MimePart &MimeMessage::getContent() { return *content; }
|
||||||
|
|
||||||
void MimeMessage::setContent(MimePart *content) {
|
void MimeMessage::setContent(MimePart *content) {
|
||||||
if (this->autoMimeContentCreated) {
|
if (this->autoMimeContentCreated) {
|
||||||
this->autoMimeContentCreated = false;
|
this->autoMimeContentCreated = false;
|
||||||
delete (this->content);
|
delete (this->content);
|
||||||
}
|
}
|
||||||
this->content = content;
|
this->content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::setReplyTo(EmailAddress *rto) { replyTo = rto; }
|
void MimeMessage::setReplyTo(EmailAddress *rto) { replyTo = rto; }
|
||||||
|
|
||||||
void MimeMessage::setSender(EmailAddress *e) {
|
void MimeMessage::setSender(EmailAddress *e) {
|
||||||
this->sender = e;
|
this->sender = e;
|
||||||
e->setParent(this);
|
e->setParent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::addRecipient(EmailAddress *rcpt, RecipientType type) {
|
void MimeMessage::addRecipient(EmailAddress *rcpt, RecipientType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case To:
|
case To:
|
||||||
recipientsTo << rcpt;
|
recipientsTo << rcpt;
|
||||||
break;
|
break;
|
||||||
case Cc:
|
case Cc:
|
||||||
recipientsCc << rcpt;
|
recipientsCc << rcpt;
|
||||||
break;
|
break;
|
||||||
case Bcc:
|
case Bcc:
|
||||||
recipientsBcc << rcpt;
|
recipientsBcc << rcpt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcpt->setParent(this);
|
rcpt->setParent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::addTo(EmailAddress *rcpt) { this->recipientsTo << rcpt; }
|
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::addBcc(EmailAddress *rcpt) { this->recipientsBcc << rcpt; }
|
||||||
|
|
||||||
void MimeMessage::setSubject(const QString &subject) {
|
void MimeMessage::setSubject(const QString &subject) {
|
||||||
this->subject = subject;
|
this->subject = subject;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::addPart(MimePart *part) {
|
void MimeMessage::addPart(MimePart *part) {
|
||||||
if (typeid(*content) == typeid(MimeMultiPart)) {
|
if (typeid(*content) == typeid(MimeMultiPart)) {
|
||||||
((MimeMultiPart *)content)->addPart(part);
|
((MimeMultiPart *) content)->addPart(part);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::setInReplyTo(const QString &inReplyTo) {
|
void MimeMessage::setInReplyTo(const QString &inReplyTo) {
|
||||||
mInReplyTo = inReplyTo;
|
mInReplyTo = inReplyTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc) {
|
void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc) {
|
||||||
this->hEncoding = hEnc;
|
this->hEncoding = hEnc;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EmailAddress &MimeMessage::getSender() const { return *sender; }
|
const EmailAddress &MimeMessage::getSender() const { return *sender; }
|
||||||
|
|
||||||
const QList<EmailAddress *> &
|
const QList<EmailAddress *> &
|
||||||
MimeMessage::getRecipients(RecipientType type) const {
|
MimeMessage::getRecipients(RecipientType type) const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
default:
|
default:
|
||||||
case To:
|
case To:
|
||||||
return recipientsTo;
|
return recipientsTo;
|
||||||
case Cc:
|
case Cc:
|
||||||
return recipientsCc;
|
return recipientsCc;
|
||||||
case Bcc:
|
case Bcc:
|
||||||
return recipientsBcc;
|
return recipientsBcc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const EmailAddress *MimeMessage::getReplyTo() const { return replyTo; }
|
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 QString &MimeMessage::getSubject() const { return subject; }
|
||||||
|
|
||||||
const QList<MimePart *> &MimeMessage::getParts() const {
|
const QList<MimePart *> &MimeMessage::getParts() const {
|
||||||
if (typeid(*content) == typeid(MimeMultiPart)) {
|
if (typeid(*content) == typeid(MimeMultiPart)) {
|
||||||
return ((MimeMultiPart *)content)->getParts();
|
return ((MimeMultiPart *) content)->getParts();
|
||||||
} else {
|
} else {
|
||||||
QList<MimePart *> *res = new QList<MimePart *>();
|
auto *res = new QList<MimePart *>();
|
||||||
res->append(content);
|
res->append(content);
|
||||||
return *res;
|
return *res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
@ -133,176 +133,176 @@ const QList<MimePart *> &MimeMessage::getParts() const {
|
|||||||
/* [3] Public Methods */
|
/* [3] Public Methods */
|
||||||
|
|
||||||
QString MimeMessage::toString() {
|
QString MimeMessage::toString() {
|
||||||
QString mime;
|
QString mime;
|
||||||
|
|
||||||
/* =========== MIME HEADER ============ */
|
/* =========== MIME HEADER ============ */
|
||||||
|
|
||||||
/* ---------- Sender / From ----------- */
|
/* ---------- Sender / From ----------- */
|
||||||
mime = "From:";
|
mime = "From:";
|
||||||
if (sender->getName() != "") {
|
if (sender->getName() != "") {
|
||||||
switch (hEncoding) {
|
switch (hEncoding) {
|
||||||
case MimePart::Base64:
|
case MimePart::Base64:
|
||||||
mime += " =?utf-8?B?" +
|
mime += " =?utf-8?B?" +
|
||||||
QByteArray().append(sender->getName().toUtf8()).toBase64() + "?=";
|
QByteArray().append(sender->getName().toUtf8()).toBase64() + "?=";
|
||||||
break;
|
break;
|
||||||
case MimePart::QuotedPrintable:
|
case MimePart::QuotedPrintable:
|
||||||
mime += " =?utf-8?Q?" +
|
mime += " =?utf-8?Q?" +
|
||||||
QuotedPrintable::encode(
|
QuotedPrintable::encode(
|
||||||
QByteArray().append(sender->getName().toUtf8()))
|
QByteArray().append(sender->getName().toUtf8()))
|
||||||
.replace(' ', "_")
|
.replace(' ', "_")
|
||||||
.replace(':', "=3A") +
|
.replace(':', "=3A") +
|
||||||
"?=";
|
"?=";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mime += " " + sender->getName();
|
mime += " " + sender->getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
mime += " <" + sender->getAddress() + ">\r\n";
|
||||||
mime += " <" + sender->getAddress() + ">\r\n";
|
/* ---------------------------------- */
|
||||||
/* ---------------------------------- */
|
|
||||||
|
|
||||||
/* ------- Recipients / To ---------- */
|
/* ------- Recipients / To ---------- */
|
||||||
mime += "To:";
|
mime += "To:";
|
||||||
QList<EmailAddress *>::iterator it;
|
QList<EmailAddress *>::iterator it;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i) {
|
for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
mime += ",";
|
mime += ",";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*it)->getName() != "") {
|
if ((*it)->getName() != "") {
|
||||||
switch (hEncoding) {
|
switch (hEncoding) {
|
||||||
case MimePart::Base64:
|
case MimePart::Base64:
|
||||||
mime += " =?utf-8?B?" +
|
mime += " =?utf-8?B?" +
|
||||||
QByteArray().append((*it)->getName().toUtf8()).toBase64() +
|
QByteArray().append((*it)->getName().toUtf8()).toBase64() +
|
||||||
"?=";
|
"?=";
|
||||||
break;
|
break;
|
||||||
case MimePart::QuotedPrintable:
|
case MimePart::QuotedPrintable:
|
||||||
mime += " =?utf-8?Q?" +
|
mime += " =?utf-8?Q?" +
|
||||||
QuotedPrintable::encode(
|
QuotedPrintable::encode(
|
||||||
QByteArray().append((*it)->getName().toUtf8()))
|
QByteArray().append((*it)->getName().toUtf8()))
|
||||||
.replace(' ', "_")
|
.replace(' ', "_")
|
||||||
.replace(':', "=3A") +
|
.replace(':', "=3A") +
|
||||||
"?=";
|
"?=";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mime += " " + (*it)->getName();
|
mime += " " + (*it)->getName();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
mime += " <" + (*it)->getAddress() + ">";
|
||||||
}
|
}
|
||||||
mime += " <" + (*it)->getAddress() + ">";
|
|
||||||
}
|
|
||||||
mime += "\r\n";
|
|
||||||
/* ---------------------------------- */
|
|
||||||
|
|
||||||
/* ------- Recipients / Cc ---------- */
|
|
||||||
if (recipientsCc.size() != 0) {
|
|
||||||
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 (recipientsCc.size() != 0) {
|
|
||||||
mime += "\r\n";
|
mime += "\r\n";
|
||||||
}
|
/* ---------------------------------- */
|
||||||
/* ---------------------------------- */
|
|
||||||
|
|
||||||
/* ------------ Subject ------------- */
|
/* ------- Recipients / Cc ---------- */
|
||||||
mime += "Subject: ";
|
if (!recipientsCc.empty()) {
|
||||||
|
mime += "Cc:";
|
||||||
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() != "") {
|
|
||||||
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";
|
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 (!recipientsCc.empty()) {
|
||||||
|
mime += "\r\n";
|
||||||
|
}
|
||||||
|
/* ---------------------------------- */
|
||||||
|
|
||||||
mime += "MIME-Version: 1.0\r\n";
|
/* ------------ Subject ------------- */
|
||||||
if (!mInReplyTo.isEmpty()) {
|
mime += "Subject: ";
|
||||||
mime += "In-Reply-To: <" + mInReplyTo + ">\r\n";
|
|
||||||
mime += "References: <" + mInReplyTo + ">\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
QDateTime now = QDateTime::currentDateTime();
|
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() != "") {
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
#if QT_VERSION_MAJOR < 5 // Qt4 workaround since RFC2822Date isn't defined
|
#if QT_VERSION_MAJOR < 5 // Qt4 workaround since RFC2822Date isn't defined
|
||||||
QString shortDayName =
|
QString shortDayName =
|
||||||
QLocale::c().dayName(now.date().dayOfWeek(), QLocale::ShortFormat);
|
QLocale::c().dayName(now.date().dayOfWeek(), QLocale::ShortFormat);
|
||||||
QString shortMonthName =
|
QString shortMonthName =
|
||||||
QLocale::c().monthName(now.date().month(), QLocale::ShortFormat);
|
QLocale::c().monthName(now.date().month(), QLocale::ShortFormat);
|
||||||
int utcOffset = now.secsTo(QDateTime(now.date(), now.time(), Qt::UTC)) / 60;
|
int utcOffset = now.secsTo(QDateTime(now.date(), now.time(), Qt::UTC)) / 60;
|
||||||
char timezoneSign = utcOffset >= 0 ? '+' : '-';
|
char timezoneSign = utcOffset >= 0 ? '+' : '-';
|
||||||
utcOffset = utcOffset >= 0 ? utcOffset : -utcOffset;
|
utcOffset = utcOffset >= 0 ? utcOffset : -utcOffset;
|
||||||
QString timezone = QString("%1%2%3")
|
QString timezone = QString("%1%2%3")
|
||||||
.arg(timezoneSign)
|
.arg(timezoneSign)
|
||||||
.arg(utcOffset / 60, 2, 10, QChar('0'))
|
.arg(utcOffset / 60, 2, 10, QChar('0'))
|
||||||
.arg(utcOffset % 60, 2, 10, QChar('0'));
|
.arg(utcOffset % 60, 2, 10, QChar('0'));
|
||||||
mime += QString("Date: %1\r\n")
|
mime += QString("Date: %1\r\n")
|
||||||
.arg(now.toString("%1, dd %2 yyyy hh:mm:ss %3")
|
.arg(now.toString("%1, dd %2 yyyy hh:mm:ss %3")
|
||||||
.arg(shortDayName)
|
.arg(shortDayName)
|
||||||
.arg(shortMonthName)
|
.arg(shortMonthName)
|
||||||
.arg(timezone));
|
.arg(timezone));
|
||||||
#else // Qt5 supported
|
#else // Qt5 supported
|
||||||
mime += QString("Date: %1\r\n").arg(now.toString(Qt::RFC2822Date));
|
mime += QString("Date: %1\r\n").arg(now.toString(Qt::RFC2822Date));
|
||||||
#endif // support RFC2822Date
|
#endif // support RFC2822Date
|
||||||
|
|
||||||
mime += content->toString();
|
mime += content->toString();
|
||||||
return mime;
|
return mime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -22,51 +22,51 @@
|
|||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
const QString MULTI_PART_NAMES[] = {
|
const QString MULTI_PART_NAMES[] = {
|
||||||
"multipart/mixed", // Mixed
|
"multipart/mixed", // Mixed
|
||||||
"multipart/digest", // Digest
|
"multipart/digest", // Digest
|
||||||
"multipart/alternative", // Alternative
|
"multipart/alternative", // Alternative
|
||||||
"multipart/related", // Related
|
"multipart/related", // Related
|
||||||
"multipart/report", // Report
|
"multipart/report", // Report
|
||||||
"multipart/signed", // Signed
|
"multipart/signed", // Signed
|
||||||
"multipart/encrypted" // Encrypted
|
"multipart/encrypted" // Encrypted
|
||||||
};
|
};
|
||||||
|
|
||||||
MimeMultiPart::MimeMultiPart(MultiPartType type) {
|
MimeMultiPart::MimeMultiPart(MultiPartType type) {
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->cType = MULTI_PART_NAMES[this->type];
|
this->cType = MULTI_PART_NAMES[this->type];
|
||||||
this->cEncoding = _8Bit;
|
this->cEncoding = _8Bit;
|
||||||
|
|
||||||
QRandomGenerator generator;
|
QRandomGenerator generator;
|
||||||
|
|
||||||
QCryptographicHash md5(QCryptographicHash::Md5);
|
QCryptographicHash md5(QCryptographicHash::Md5);
|
||||||
md5.addData(QByteArray().append(generator.generate()));
|
md5.addData(QByteArray().append((char) generator.generate()));
|
||||||
cBoundary = md5.result().toHex();
|
cBoundary = md5.result().toHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeMultiPart::~MimeMultiPart() {}
|
MimeMultiPart::~MimeMultiPart() = default;
|
||||||
|
|
||||||
void MimeMultiPart::addPart(MimePart *part) { parts.append(part); }
|
void MimeMultiPart::addPart(MimePart *part) { parts.append(part); }
|
||||||
|
|
||||||
const QList<MimePart *> &MimeMultiPart::getParts() const { return parts; }
|
const QList<MimePart *> &MimeMultiPart::getParts() const { return parts; }
|
||||||
|
|
||||||
void MimeMultiPart::prepare() {
|
void MimeMultiPart::prepare() {
|
||||||
QList<MimePart *>::iterator it;
|
QList<MimePart *>::iterator it;
|
||||||
|
|
||||||
content = "";
|
content = "";
|
||||||
for (it = parts.begin(); it != parts.end(); it++) {
|
for (it = parts.begin(); it != parts.end(); it++) {
|
||||||
content += QString("--" + cBoundary + "\r\n").toUtf8();
|
content += QString("--" + cBoundary + "\r\n").toUtf8();
|
||||||
(*it)->prepare();
|
(*it)->prepare();
|
||||||
content += (*it)->toString().toUtf8();
|
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) {
|
void MimeMultiPart::setMimeType(const MultiPartType type) {
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->cType = MULTI_PART_NAMES[type];
|
this->cType = MULTI_PART_NAMES[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeMultiPart::MultiPartType MimeMultiPart::getMimeType() const { return type; }
|
MimeMultiPart::MultiPartType MimeMultiPart::getMimeType() const { return type; }
|
||||||
|
@ -22,25 +22,25 @@
|
|||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimePart::MimePart() {
|
MimePart::MimePart() {
|
||||||
cEncoding = _7Bit;
|
cEncoding = _7Bit;
|
||||||
prepared = false;
|
prepared = false;
|
||||||
cBoundary = "";
|
cBoundary = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
MimePart::~MimePart() { return; }
|
MimePart::~MimePart() = default;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
void MimePart::setContent(const QByteArray &content) {
|
void MimePart::setContent(const QByteArray &content) {
|
||||||
this->content = content;
|
this->content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimePart::setHeader(const QString &header) { this->header = header; }
|
void MimePart::setHeader(const QString &header) { this->header = header; }
|
||||||
|
|
||||||
void MimePart::addHeaderLine(const QString &line) {
|
void MimePart::addHeaderLine(const QString &line) {
|
||||||
this->header += line + "\r\n";
|
this->header += line + "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &MimePart::getHeader() const { return header; }
|
const QString &MimePart::getHeader() const { return header; }
|
||||||
@ -68,7 +68,7 @@ void MimePart::setEncoding(Encoding enc) { this->cEncoding = enc; }
|
|||||||
MimePart::Encoding MimePart::getEncoding() const { return this->cEncoding; }
|
MimePart::Encoding MimePart::getEncoding() const { return this->cEncoding; }
|
||||||
|
|
||||||
MimeContentFormatter &MimePart::getContentFormatter() {
|
MimeContentFormatter &MimePart::getContentFormatter() {
|
||||||
return this->formatter;
|
return this->formatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
@ -76,10 +76,10 @@ MimeContentFormatter &MimePart::getContentFormatter() {
|
|||||||
/* [3] Public methods */
|
/* [3] Public methods */
|
||||||
|
|
||||||
QString MimePart::toString() {
|
QString MimePart::toString() {
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
return mimeString;
|
return mimeString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
@ -87,75 +87,75 @@ QString MimePart::toString() {
|
|||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
void MimePart::prepare() {
|
void MimePart::prepare() {
|
||||||
mimeString = QString();
|
mimeString = QString();
|
||||||
|
|
||||||
/* === Header Prepare === */
|
/* === Header Prepare === */
|
||||||
|
|
||||||
/* Content-Type */
|
/* Content-Type */
|
||||||
mimeString.append("Content-Type: ").append(cType);
|
mimeString.append("Content-Type: ").append(cType);
|
||||||
|
|
||||||
if (cName != "")
|
if (cName != "")
|
||||||
mimeString.append("; name=\"").append(cName).append("\"");
|
mimeString.append("; name=\"").append(cName).append("\"");
|
||||||
|
|
||||||
if (cCharset != "")
|
if (cCharset != "")
|
||||||
mimeString.append("; charset=").append(cCharset);
|
mimeString.append("; charset=").append(cCharset);
|
||||||
|
|
||||||
if (cBoundary != "")
|
if (cBoundary != "")
|
||||||
mimeString.append("; boundary=").append(cBoundary);
|
mimeString.append("; boundary=").append(cBoundary);
|
||||||
|
|
||||||
mimeString.append("\r\n");
|
mimeString.append("\r\n");
|
||||||
/* ------------ */
|
/* ------------ */
|
||||||
|
|
||||||
/* Content-Transfer-Encoding */
|
/* Content-Transfer-Encoding */
|
||||||
mimeString.append("Content-Transfer-Encoding: ");
|
mimeString.append("Content-Transfer-Encoding: ");
|
||||||
switch (cEncoding) {
|
switch (cEncoding) {
|
||||||
case _7Bit:
|
case _7Bit:
|
||||||
mimeString.append("7bit\r\n");
|
mimeString.append("7bit\r\n");
|
||||||
break;
|
break;
|
||||||
case _8Bit:
|
case _8Bit:
|
||||||
mimeString.append("8bit\r\n");
|
mimeString.append("8bit\r\n");
|
||||||
break;
|
break;
|
||||||
case Base64:
|
case Base64:
|
||||||
mimeString.append("base64\r\n");
|
mimeString.append("base64\r\n");
|
||||||
break;
|
break;
|
||||||
case QuotedPrintable:
|
case QuotedPrintable:
|
||||||
mimeString.append("quoted-printable\r\n");
|
mimeString.append("quoted-printable\r\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* ------------------------ */
|
/* ------------------------ */
|
||||||
|
|
||||||
/* Content-Id */
|
/* Content-Id */
|
||||||
if (cId != NULL)
|
if (cId != NULL)
|
||||||
mimeString.append("Content-ID: <").append(cId).append(">\r\n");
|
mimeString.append("Content-ID: <").append(cId).append(">\r\n");
|
||||||
/* ---------- */
|
/* ---------- */
|
||||||
|
|
||||||
/* Addition header lines */
|
/* Addition header lines */
|
||||||
|
|
||||||
mimeString.append(header).append("\r\n");
|
mimeString.append(header).append("\r\n");
|
||||||
|
|
||||||
/* ------------------------- */
|
/* ------------------------- */
|
||||||
|
|
||||||
/* === End of Header Prepare === */
|
/* === End of Header Prepare === */
|
||||||
|
|
||||||
/* === Content === */
|
/* === Content === */
|
||||||
switch (cEncoding) {
|
switch (cEncoding) {
|
||||||
case _7Bit:
|
case _7Bit:
|
||||||
mimeString.append(QString(content).toLatin1());
|
mimeString.append(QString(content).toLatin1());
|
||||||
break;
|
break;
|
||||||
case _8Bit:
|
case _8Bit:
|
||||||
mimeString.append(content);
|
mimeString.append(content);
|
||||||
break;
|
break;
|
||||||
case Base64:
|
case Base64:
|
||||||
mimeString.append(formatter.format(content.toBase64()));
|
mimeString.append(formatter.format(content.toBase64()));
|
||||||
break;
|
break;
|
||||||
case QuotedPrintable:
|
case QuotedPrintable:
|
||||||
mimeString.append(formatter.format(QuotedPrintable::encode(content), true));
|
mimeString.append(formatter.format(QuotedPrintable::encode(content), true));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mimeString.append("\r\n");
|
mimeString.append("\r\n");
|
||||||
/* === End of Content === */
|
/* === End of Content === */
|
||||||
|
|
||||||
prepared = true;
|
prepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeText::MimeText(const QString &txt) {
|
MimeText::MimeText(const QString &txt) {
|
||||||
this->text = txt;
|
this->text = txt;
|
||||||
this->cType = "text/plain";
|
this->cType = "text/plain";
|
||||||
this->cCharset = "utf-8";
|
this->cCharset = "utf-8";
|
||||||
this->cEncoding = _8Bit;
|
this->cEncoding = _8Bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeText::~MimeText() {}
|
MimeText::~MimeText() = default;
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
@ -42,11 +42,11 @@ const QString &MimeText::getText() const { return text; }
|
|||||||
/* [3] Protected Methods */
|
/* [3] Protected Methods */
|
||||||
|
|
||||||
void MimeText::prepare() {
|
void MimeText::prepare() {
|
||||||
this->content.clear();
|
this->content.clear();
|
||||||
this->content.append(text.toUtf8());
|
this->content.append(text.toUtf8());
|
||||||
|
|
||||||
/* !!! IMPORTANT !!! */
|
/* !!! IMPORTANT !!! */
|
||||||
MimePart::prepare();
|
MimePart::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -19,44 +19,44 @@
|
|||||||
#include "smtp/quotedprintable.h"
|
#include "smtp/quotedprintable.h"
|
||||||
|
|
||||||
QString QuotedPrintable::encode(const QByteArray &input) {
|
QString QuotedPrintable::encode(const QByteArray &input) {
|
||||||
QString output;
|
QString output;
|
||||||
|
|
||||||
char byte;
|
char byte;
|
||||||
const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
|
||||||
for (int i = 0; i < input.length(); ++i) {
|
for (char i : input) {
|
||||||
byte = input[i];
|
byte = i;
|
||||||
|
|
||||||
if ((byte == 0x20) || ((byte >= 33) && (byte <= 126) && (byte != 61))) {
|
if ((byte == 0x20) || ((byte >= 33) && (byte <= 126) && (byte != 61))) {
|
||||||
output.append(byte);
|
output.append(byte);
|
||||||
} else {
|
} else {
|
||||||
output.append('=');
|
output.append('=');
|
||||||
output.append(hex[((byte >> 4) & 0x0F)]);
|
output.append(hex[((byte >> 4) & 0x0F)]);
|
||||||
output.append(hex[(byte & 0x0F)]);
|
output.append(hex[(byte & 0x0F)]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray QuotedPrintable::decode(const QString &input) {
|
QByteArray QuotedPrintable::decode(const QString &input) {
|
||||||
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B
|
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B
|
||||||
// C D E F
|
// C D E F
|
||||||
const int hexVal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0,
|
const int hexVal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0,
|
||||||
0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
|
0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
|
||||||
|
|
||||||
QByteArray output;
|
QByteArray output;
|
||||||
|
|
||||||
for (int i = 0; i < input.length(); ++i) {
|
for (int i = 0; i < input.length(); ++i) {
|
||||||
if (input.at(i).toLatin1() == '=') {
|
if (input.at(i).toLatin1() == '=') {
|
||||||
output.append((hexVal[input.at(i + 1).toLatin1() - '0'] << 4) +
|
output.append((hexVal[input.at(i + 1).toLatin1() - '0'] << 4) +
|
||||||
hexVal[input.at(i + 2).toLatin1() - '0']);
|
hexVal[input.at(i + 2).toLatin1() - '0']);
|
||||||
i += 2;
|
i += 2;
|
||||||
} else {
|
} else {
|
||||||
output.append(input.at(i).toLatin1());
|
output.append(input.at(i).toLatin1());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -25,24 +25,24 @@
|
|||||||
|
|
||||||
SmtpClient::SmtpClient(const QString &host, int port,
|
SmtpClient::SmtpClient(const QString &host, int port,
|
||||||
ConnectionType connectionType)
|
ConnectionType connectionType)
|
||||||
: socket(NULL), name("localhost"), authMethod(AuthPlain),
|
: socket(NULL), name("localhost"), authMethod(AuthPlain),
|
||||||
connectionTimeout(5000), responseTimeout(5000),
|
connectionTimeout(5000), responseTimeout(5000),
|
||||||
sendMessageTimeout(60000) {
|
sendMessageTimeout(60000) {
|
||||||
setConnectionType(connectionType);
|
setConnectionType(connectionType);
|
||||||
|
|
||||||
this->host = host;
|
this->host = host;
|
||||||
this->port = port;
|
this->port = port;
|
||||||
|
|
||||||
connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,
|
connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,
|
||||||
SLOT(socketStateChanged(QAbstractSocket::SocketState)));
|
SLOT(socketStateChanged(QAbstractSocket::SocketState)));
|
||||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
|
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
|
||||||
SLOT(socketError(QAbstractSocket::SocketError)));
|
SLOT(socketError(QAbstractSocket::SocketError)));
|
||||||
connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
|
connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SmtpClient::~SmtpClient() {
|
SmtpClient::~SmtpClient() {
|
||||||
if (socket)
|
if (socket)
|
||||||
delete socket;
|
delete socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
@ -52,7 +52,7 @@ SmtpClient::~SmtpClient() {
|
|||||||
void SmtpClient::setUser(const QString &user) { this->user = user; }
|
void SmtpClient::setUser(const QString &user) { this->user = user; }
|
||||||
|
|
||||||
void SmtpClient::setPassword(const QString &password) {
|
void SmtpClient::setPassword(const QString &password) {
|
||||||
this->password = password;
|
this->password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmtpClient::setAuthMethod(AuthMethod method) { this->authMethod = method; }
|
void SmtpClient::setAuthMethod(AuthMethod method) { this->authMethod = method; }
|
||||||
@ -62,19 +62,19 @@ void SmtpClient::setHost(const QString &host) { this->host = host; }
|
|||||||
void SmtpClient::setPort(int port) { this->port = port; }
|
void SmtpClient::setPort(int port) { this->port = port; }
|
||||||
|
|
||||||
void SmtpClient::setConnectionType(ConnectionType ct) {
|
void SmtpClient::setConnectionType(ConnectionType ct) {
|
||||||
this->connectionType = ct;
|
this->connectionType = ct;
|
||||||
|
|
||||||
if (socket)
|
if (socket)
|
||||||
delete socket;
|
delete socket;
|
||||||
|
|
||||||
switch (connectionType) {
|
switch (connectionType) {
|
||||||
case TcpConnection:
|
case TcpConnection:
|
||||||
socket = new QTcpSocket(this);
|
socket = new QTcpSocket(this);
|
||||||
break;
|
break;
|
||||||
case SslConnection:
|
case SslConnection:
|
||||||
case TlsConnection:
|
case TlsConnection:
|
||||||
socket = new QSslSocket(this);
|
socket = new QSslSocket(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &SmtpClient::getHost() const { return this->host; }
|
const QString &SmtpClient::getHost() const { return this->host; }
|
||||||
@ -84,13 +84,13 @@ const QString &SmtpClient::getUser() const { return this->user; }
|
|||||||
const QString &SmtpClient::getPassword() const { return this->password; }
|
const QString &SmtpClient::getPassword() const { return this->password; }
|
||||||
|
|
||||||
SmtpClient::AuthMethod SmtpClient::getAuthMethod() const {
|
SmtpClient::AuthMethod SmtpClient::getAuthMethod() const {
|
||||||
return this->authMethod;
|
return this->authMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SmtpClient::getPort() const { return this->port; }
|
int SmtpClient::getPort() const { return this->port; }
|
||||||
|
|
||||||
SmtpClient::ConnectionType SmtpClient::getConnectionType() const {
|
SmtpClient::ConnectionType SmtpClient::getConnectionType() const {
|
||||||
return connectionType;
|
return connectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &SmtpClient::getName() const { return this->name; }
|
const QString &SmtpClient::getName() const { return this->name; }
|
||||||
@ -110,7 +110,9 @@ void SmtpClient::setConnectionTimeout(int msec) { connectionTimeout = msec; }
|
|||||||
int SmtpClient::getResponseTimeout() const { return responseTimeout; }
|
int SmtpClient::getResponseTimeout() const { return responseTimeout; }
|
||||||
|
|
||||||
void SmtpClient::setResponseTimeout(int msec) { responseTimeout = msec; }
|
void SmtpClient::setResponseTimeout(int msec) { responseTimeout = msec; }
|
||||||
|
|
||||||
int SmtpClient::getSendMessageTimeout() const { return sendMessageTimeout; }
|
int SmtpClient::getSendMessageTimeout() const { return sendMessageTimeout; }
|
||||||
|
|
||||||
void SmtpClient::setSendMessageTimeout(int msec) { sendMessageTimeout = msec; }
|
void SmtpClient::setSendMessageTimeout(int msec) { sendMessageTimeout = msec; }
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
@ -118,239 +120,239 @@ void SmtpClient::setSendMessageTimeout(int msec) { sendMessageTimeout = msec; }
|
|||||||
/* [3] Public methods */
|
/* [3] Public methods */
|
||||||
|
|
||||||
bool SmtpClient::connectToHost() {
|
bool SmtpClient::connectToHost() {
|
||||||
switch (connectionType) {
|
switch (connectionType) {
|
||||||
case TlsConnection:
|
case TlsConnection:
|
||||||
case TcpConnection:
|
case TcpConnection:
|
||||||
socket->connectToHost(host, port);
|
socket->connectToHost(host, port);
|
||||||
break;
|
break;
|
||||||
case SslConnection:
|
case SslConnection:
|
||||||
((QSslSocket *)socket)->connectToHostEncrypted(host, port);
|
((QSslSocket *) socket)->connectToHostEncrypted(host, port);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
// Tries to connect to server
|
|
||||||
if (!socket->waitForConnected(connectionTimeout)) {
|
|
||||||
emit smtpError(ConnectionTimeoutError);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Wait for the server's response
|
|
||||||
waitForResponse();
|
|
||||||
|
|
||||||
// If the response code is not 220 (Service ready)
|
|
||||||
// means that is something wrong with the server
|
|
||||||
if (responseCode != 220) {
|
|
||||||
emit smtpError(ServerError);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a EHLO/HELO message to the server
|
// Tries to connect to server
|
||||||
// The client's first command must be EHLO/HELO
|
if (!socket->waitForConnected(connectionTimeout)) {
|
||||||
sendMessage("EHLO " + name);
|
|
||||||
|
|
||||||
// Wait for the server's response
|
|
||||||
waitForResponse();
|
|
||||||
|
|
||||||
// The response code needs to be 250.
|
|
||||||
if (responseCode != 250) {
|
|
||||||
emit smtpError(ServerError);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectionType == TlsConnection) {
|
|
||||||
// send a request to start TLS handshake
|
|
||||||
sendMessage("STARTTLS");
|
|
||||||
|
|
||||||
// Wait for the server's response
|
|
||||||
waitForResponse();
|
|
||||||
|
|
||||||
// The response code needs to be 220.
|
|
||||||
if (responseCode != 220) {
|
|
||||||
emit smtpError(ServerError);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
((QSslSocket *)socket)->startClientEncryption();
|
|
||||||
|
|
||||||
if (!((QSslSocket *)socket)->waitForEncrypted(connectionTimeout)) {
|
|
||||||
qDebug() << ((QSslSocket *)socket)->errorString();
|
|
||||||
emit smtpError(ConnectionTimeoutError);
|
emit smtpError(ConnectionTimeoutError);
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Send ELHO one more time
|
|
||||||
sendMessage("EHLO " + name);
|
|
||||||
|
|
||||||
// Wait for the server's response
|
|
||||||
waitForResponse();
|
|
||||||
|
|
||||||
// The response code needs to be 250.
|
|
||||||
if (responseCode != 250) {
|
|
||||||
emit smtpError(ServerError);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (ResponseTimeoutException) {
|
|
||||||
return false;
|
|
||||||
} catch (SendMessageTimeoutException) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no errors occured the function returns true.
|
try {
|
||||||
return true;
|
// Wait for the server's response
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// If the response code is not 220 (Service ready)
|
||||||
|
// means that is something wrong with the server
|
||||||
|
if (responseCode != 220) {
|
||||||
|
emit smtpError(ServerError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a EHLO/HELO message to the server
|
||||||
|
// The client's first command must be EHLO/HELO
|
||||||
|
sendMessage("EHLO " + name);
|
||||||
|
|
||||||
|
// Wait for the server's response
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// The response code needs to be 250.
|
||||||
|
if (responseCode != 250) {
|
||||||
|
emit smtpError(ServerError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectionType == TlsConnection) {
|
||||||
|
// send a request to start TLS handshake
|
||||||
|
sendMessage("STARTTLS");
|
||||||
|
|
||||||
|
// Wait for the server's response
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// The response code needs to be 220.
|
||||||
|
if (responseCode != 220) {
|
||||||
|
emit smtpError(ServerError);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
((QSslSocket *) socket)->startClientEncryption();
|
||||||
|
|
||||||
|
if (!((QSslSocket *) socket)->waitForEncrypted(connectionTimeout)) {
|
||||||
|
qDebug() << ((QSslSocket *) socket)->errorString();
|
||||||
|
emit smtpError(ConnectionTimeoutError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send ELHO one more time
|
||||||
|
sendMessage("EHLO " + name);
|
||||||
|
|
||||||
|
// Wait for the server's response
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// The response code needs to be 250.
|
||||||
|
if (responseCode != 250) {
|
||||||
|
emit smtpError(ServerError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ResponseTimeoutException) {
|
||||||
|
return false;
|
||||||
|
} catch (SendMessageTimeoutException) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no errors occured the function returns true.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SmtpClient::login() { return login(user, password, authMethod); }
|
bool SmtpClient::login() { return login(user, password, authMethod); }
|
||||||
|
|
||||||
bool SmtpClient::login(const QString &user, const QString &password,
|
bool SmtpClient::login(const QString &user, const QString &password,
|
||||||
AuthMethod method) {
|
AuthMethod method) {
|
||||||
try {
|
try {
|
||||||
if (method == AuthPlain) {
|
if (method == AuthPlain) {
|
||||||
// Sending command: AUTH PLAIN base64('\0' + username + '\0' + password)
|
// Sending command: AUTH PLAIN base64('\0' + username + '\0' + password)
|
||||||
sendMessage("AUTH PLAIN " + QByteArray()
|
sendMessage("AUTH PLAIN " + QByteArray()
|
||||||
.append((char)0)
|
.append((char) 0)
|
||||||
.append(user.toUtf8())
|
.append(user.toUtf8())
|
||||||
.append((char)0)
|
.append((char) 0)
|
||||||
.append(password.toUtf8())
|
.append(password.toUtf8())
|
||||||
.toBase64());
|
.toBase64());
|
||||||
|
|
||||||
// Wait for the server's response
|
// Wait for the server's response
|
||||||
waitForResponse();
|
waitForResponse();
|
||||||
|
|
||||||
// If the response is not 235 then the authentication was faild
|
// If the response is not 235 then the authentication was faild
|
||||||
if (responseCode != 235) {
|
if (responseCode != 235) {
|
||||||
|
emit smtpError(AuthenticationFailedError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (method == AuthLogin) {
|
||||||
|
// Sending command: AUTH LOGIN
|
||||||
|
sendMessage("AUTH LOGIN");
|
||||||
|
|
||||||
|
// Wait for 334 response code
|
||||||
|
waitForResponse();
|
||||||
|
if (responseCode != 334) {
|
||||||
|
emit smtpError(AuthenticationFailedError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the username in base64
|
||||||
|
sendMessage(QByteArray().append(user.toUtf8()).toBase64());
|
||||||
|
|
||||||
|
// Wait for 334
|
||||||
|
waitForResponse();
|
||||||
|
if (responseCode != 334) {
|
||||||
|
emit smtpError(AuthenticationFailedError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the password in base64
|
||||||
|
sendMessage(QByteArray().append(password.toUtf8()).toBase64());
|
||||||
|
|
||||||
|
// Wait for the server's responce
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// If the response is not 235 then the authentication was faild
|
||||||
|
if (responseCode != 235) {
|
||||||
|
emit smtpError(AuthenticationFailedError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ResponseTimeoutException) {
|
||||||
|
// Responce Timeout exceeded
|
||||||
emit smtpError(AuthenticationFailedError);
|
emit smtpError(AuthenticationFailedError);
|
||||||
return false;
|
return false;
|
||||||
}
|
} catch (SendMessageTimeoutException) {
|
||||||
} else if (method == AuthLogin) {
|
// Send Timeout exceeded
|
||||||
// Sending command: AUTH LOGIN
|
|
||||||
sendMessage("AUTH LOGIN");
|
|
||||||
|
|
||||||
// Wait for 334 response code
|
|
||||||
waitForResponse();
|
|
||||||
if (responseCode != 334) {
|
|
||||||
emit smtpError(AuthenticationFailedError);
|
emit smtpError(AuthenticationFailedError);
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Send the username in base64
|
|
||||||
sendMessage(QByteArray().append(user.toUtf8()).toBase64());
|
|
||||||
|
|
||||||
// Wait for 334
|
|
||||||
waitForResponse();
|
|
||||||
if (responseCode != 334) {
|
|
||||||
emit smtpError(AuthenticationFailedError);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the password in base64
|
|
||||||
sendMessage(QByteArray().append(password.toUtf8()).toBase64());
|
|
||||||
|
|
||||||
// Wait for the server's responce
|
|
||||||
waitForResponse();
|
|
||||||
|
|
||||||
// If the response is not 235 then the authentication was faild
|
|
||||||
if (responseCode != 235) {
|
|
||||||
emit smtpError(AuthenticationFailedError);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (ResponseTimeoutException) {
|
|
||||||
// Responce Timeout exceeded
|
|
||||||
emit smtpError(AuthenticationFailedError);
|
|
||||||
return false;
|
|
||||||
} catch (SendMessageTimeoutException) {
|
|
||||||
// Send Timeout exceeded
|
|
||||||
emit smtpError(AuthenticationFailedError);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SmtpClient::sendMail(MimeMessage &email) {
|
bool SmtpClient::sendMail(MimeMessage &email) {
|
||||||
try {
|
try {
|
||||||
// Send the MAIL command with the sender
|
// Send the MAIL command with the sender
|
||||||
sendMessage("MAIL FROM:<" + email.getSender().getAddress() + ">");
|
sendMessage("MAIL FROM:<" + email.getSender().getAddress() + ">");
|
||||||
|
|
||||||
waitForResponse();
|
waitForResponse();
|
||||||
|
|
||||||
if (responseCode != 250)
|
if (responseCode != 250)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Send RCPT command for each recipient
|
// Send RCPT command for each recipient
|
||||||
QList<EmailAddress *>::const_iterator it, itEnd;
|
QList<EmailAddress *>::const_iterator it, itEnd;
|
||||||
// To (primary recipients)
|
// To (primary recipients)
|
||||||
for (it = email.getRecipients().begin(),
|
for (it = email.getRecipients().begin(),
|
||||||
itEnd = email.getRecipients().end();
|
itEnd = email.getRecipients().end();
|
||||||
it != itEnd; ++it) {
|
it != itEnd; ++it) {
|
||||||
|
|
||||||
sendMessage("RCPT TO:<" + (*it)->getAddress() + ">");
|
sendMessage("RCPT TO:<" + (*it)->getAddress() + ">");
|
||||||
waitForResponse();
|
waitForResponse();
|
||||||
|
|
||||||
if (responseCode != 250)
|
if (responseCode != 250)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cc (carbon copy)
|
||||||
|
for (it = email.getRecipients(MimeMessage::Cc).begin(),
|
||||||
|
itEnd = email.getRecipients(MimeMessage::Cc).end();
|
||||||
|
it != itEnd; ++it) {
|
||||||
|
sendMessage("RCPT TO:<" + (*it)->getAddress() + ">");
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 250)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bcc (blind carbon copy)
|
||||||
|
for (it = email.getRecipients(MimeMessage::Bcc).begin(),
|
||||||
|
itEnd = email.getRecipients(MimeMessage::Bcc).end();
|
||||||
|
it != itEnd; ++it) {
|
||||||
|
sendMessage("RCPT TO:<" + (*it)->getAddress() + ">");
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 250)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send DATA command
|
||||||
|
sendMessage("DATA");
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 354)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sendMessage(email.toString());
|
||||||
|
|
||||||
|
// Send \r\n.\r\n to end the mail data
|
||||||
|
sendMessage(".");
|
||||||
|
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 250)
|
||||||
|
return false;
|
||||||
|
} catch (ResponseTimeoutException) {
|
||||||
|
return false;
|
||||||
|
} catch (SendMessageTimeoutException) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cc (carbon copy)
|
return true;
|
||||||
for (it = email.getRecipients(MimeMessage::Cc).begin(),
|
|
||||||
itEnd = email.getRecipients(MimeMessage::Cc).end();
|
|
||||||
it != itEnd; ++it) {
|
|
||||||
sendMessage("RCPT TO:<" + (*it)->getAddress() + ">");
|
|
||||||
waitForResponse();
|
|
||||||
|
|
||||||
if (responseCode != 250)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bcc (blind carbon copy)
|
|
||||||
for (it = email.getRecipients(MimeMessage::Bcc).begin(),
|
|
||||||
itEnd = email.getRecipients(MimeMessage::Bcc).end();
|
|
||||||
it != itEnd; ++it) {
|
|
||||||
sendMessage("RCPT TO:<" + (*it)->getAddress() + ">");
|
|
||||||
waitForResponse();
|
|
||||||
|
|
||||||
if (responseCode != 250)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send DATA command
|
|
||||||
sendMessage("DATA");
|
|
||||||
waitForResponse();
|
|
||||||
|
|
||||||
if (responseCode != 354)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
sendMessage(email.toString());
|
|
||||||
|
|
||||||
// Send \r\n.\r\n to end the mail data
|
|
||||||
sendMessage(".");
|
|
||||||
|
|
||||||
waitForResponse();
|
|
||||||
|
|
||||||
if (responseCode != 250)
|
|
||||||
return false;
|
|
||||||
} catch (ResponseTimeoutException) {
|
|
||||||
return false;
|
|
||||||
} catch (SendMessageTimeoutException) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmtpClient::quit() {
|
void SmtpClient::quit() {
|
||||||
try {
|
try {
|
||||||
sendMessage("QUIT");
|
sendMessage("QUIT");
|
||||||
} catch (SmtpClient::SendMessageTimeoutException) {
|
} catch (SmtpClient::SendMessageTimeoutException) {
|
||||||
// Manually close the connection to the smtp server if message "QUIT" wasn't
|
// Manually close the connection to the smtp server if message "QUIT" wasn't
|
||||||
// received by the smtp server
|
// received by the smtp server
|
||||||
if (socket->state() == QAbstractSocket::ConnectedState ||
|
if (socket->state() == QAbstractSocket::ConnectedState ||
|
||||||
socket->state() == QAbstractSocket::ConnectingState ||
|
socket->state() == QAbstractSocket::ConnectingState ||
|
||||||
socket->state() == QAbstractSocket::HostLookupState)
|
socket->state() == QAbstractSocket::HostLookupState)
|
||||||
socket->disconnectFromHost();
|
socket->disconnectFromHost();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
@ -358,38 +360,38 @@ void SmtpClient::quit() {
|
|||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
void SmtpClient::waitForResponse() {
|
void SmtpClient::waitForResponse() {
|
||||||
do {
|
do {
|
||||||
if (!socket->waitForReadyRead(responseTimeout)) {
|
if (!socket->waitForReadyRead(responseTimeout)) {
|
||||||
emit smtpError(ResponseTimeoutError);
|
emit smtpError(ResponseTimeoutError);
|
||||||
throw ResponseTimeoutException();
|
throw ResponseTimeoutException();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (socket->canReadLine()) {
|
while (socket->canReadLine()) {
|
||||||
// Save the server's response
|
// Save the server's response
|
||||||
responseText = socket->readLine();
|
responseText = socket->readLine();
|
||||||
|
|
||||||
// Extract the respose code from the server's responce (first 3 digits)
|
// Extract the respose code from the server's responce (first 3 digits)
|
||||||
responseCode = responseText.left(3).toInt();
|
responseCode = responseText.leftRef(3).toInt();
|
||||||
|
|
||||||
if (responseCode / 100 == 4)
|
if (responseCode / 100 == 4)
|
||||||
emit smtpError(ServerError);
|
emit smtpError(ServerError);
|
||||||
|
|
||||||
if (responseCode / 100 == 5)
|
if (responseCode / 100 == 5)
|
||||||
emit smtpError(ClientError);
|
emit smtpError(ClientError);
|
||||||
|
|
||||||
if (responseText[3] == ' ') {
|
if (responseText[3] == ' ') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmtpClient::sendMessage(const QString &text) {
|
void SmtpClient::sendMessage(const QString &text) {
|
||||||
socket->write(text.toUtf8() + "\r\n");
|
socket->write(text.toUtf8() + "\r\n");
|
||||||
if (!socket->waitForBytesWritten(sendMessageTimeout)) {
|
if (!socket->waitForBytesWritten(sendMessageTimeout)) {
|
||||||
emit smtpError(SendDataTimeoutError);
|
emit smtpError(SendDataTimeoutError);
|
||||||
throw SendMessageTimeoutException();
|
throw SendMessageTimeoutException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user