Compare commits
44 Commits
Author | SHA1 | Date | |
---|---|---|---|
39d6f35ca7 | |||
|
3fa4a0fe57 | ||
|
152a3e7572 | ||
|
f715bb9916 | ||
|
67c73c7c96 | ||
|
1f4f2e208b | ||
|
5bdfa6a5dd | ||
|
3d87c6306e | ||
|
81c652dc73 | ||
|
ca43f9d642 | ||
|
12c810ada9 | ||
|
7633337dd6 | ||
|
5fc59c0863 | ||
|
6b676827fe | ||
|
cb04e35bed | ||
|
96452106d8 | ||
|
8623093e9b | ||
|
800ff9cf69 | ||
|
ff2eb297c4 | ||
|
ef6194fb26 | ||
|
78bf2dac42 | ||
|
c2a734791a | ||
|
48c080b9ee | ||
|
6de3493c92 | ||
|
9afc349942 | ||
|
c12f70b721 | ||
|
6877ac8148 | ||
|
f8db82bae5 | ||
|
7f8d11db2f | ||
|
06db4130d9 | ||
|
235a350a34 | ||
|
75f4bf385a | ||
|
a4f4235139 | ||
|
649ea30336 | ||
|
076034a612 | ||
|
b1c640c39d | ||
|
4f028793e1 | ||
|
f3da3b391c | ||
|
93873f8b1c | ||
|
dac7a04d6f | ||
|
8f6a67664f | ||
|
3d3f9136af | ||
|
81e561c91b | ||
|
32b11e2351 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,6 +0,0 @@
|
|||||||
*.o
|
|
||||||
*.so
|
|
||||||
*.so.*
|
|
||||||
Makefile
|
|
||||||
moc_*.cpp
|
|
||||||
*.pro.user*
|
|
13
.travis.yml
13
.travis.yml
@ -1,13 +0,0 @@
|
|||||||
sudo: required
|
|
||||||
dist: trusty
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa
|
|
||||||
- sudo apt-get update -qq
|
|
||||||
- sudo apt-get install qtbase5-dev qtdeclarative5-dev libqt5webkit5-dev libsqlite3-dev
|
|
||||||
- sudo apt-get install qt5-default qttools5-dev-tools
|
|
||||||
|
|
||||||
script:
|
|
||||||
- qmake -project
|
|
||||||
- qmake src/SMTPEmail.pro
|
|
||||||
- make
|
|
23
README.md
23
README.md
@ -1,18 +1,9 @@
|
|||||||
SMTP Client for Qt (C++) - Version 2.0 [![Build Status](https://travis-ci.org/bluetiger9/SmtpClient-for-Qt.svg?branch=dev)](https://travis-ci.org/bluetiger9/SmtpClient-for-Qt)
|
SMTP Client for Qt (C++) - Version 1.1
|
||||||
=============================================
|
=============================================
|
||||||
|
|
||||||
The SmtpClient for Qt is small library writen for Qt 4 (C++ version) that allows application to send complex emails (plain text, html, attachments, inline files, etc.) using the Simple Mail Transfer Protocol (SMTP).
|
The SmtpClient for Qt is small library writen for Qt 4 (C++ version) that allows application to send complex emails (plain text, html, attachments, inline files, etc.) using the Simple Mail Transfer Protocol (SMTP).
|
||||||
|
|
||||||
##New in version 2.0:
|
## New in version 1.1:
|
||||||
- Asynchronous & Synchronous working mode
|
|
||||||
|
|
||||||
- Qt5 compatibility
|
|
||||||
|
|
||||||
- Building as a shared library
|
|
||||||
|
|
||||||
- code of SmtpClient refactored and partially rewrited
|
|
||||||
|
|
||||||
##New in version 1.1:
|
|
||||||
|
|
||||||
- TLS (STARTTLS) connection is now supported
|
- TLS (STARTTLS) connection is now supported
|
||||||
|
|
||||||
@ -23,7 +14,7 @@ The SmtpClient for Qt is small library writen for Qt 4 (C++ version) that allows
|
|||||||
- output compilant with RFC2045
|
- output compilant with RFC2045
|
||||||
|
|
||||||
|
|
||||||
## SMTP Client for Qt supports
|
## SMPT Client for Qt supports
|
||||||
|
|
||||||
- TCP and SSL connections to SMTP servers
|
- TCP and SSL connections to SMTP servers
|
||||||
|
|
||||||
@ -86,14 +77,8 @@ int main(int argc, char *argv[])
|
|||||||
// Now we can send the mail
|
// Now we can send the mail
|
||||||
|
|
||||||
smtp.connectToHost();
|
smtp.connectToHost();
|
||||||
smtp.waitForReadyConnected();
|
|
||||||
|
|
||||||
smtp.login();
|
smtp.login();
|
||||||
smtp.waitForAuthenticated();
|
|
||||||
|
|
||||||
smtp.sendMail(message);
|
smtp.sendMail(message);
|
||||||
smtp.waitForMailSent();
|
|
||||||
|
|
||||||
smtp.quit();
|
smtp.quit();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -106,4 +91,4 @@ For more examples see the [Wiki/Examples](https://github.com/bluetiger9/SmtpClie
|
|||||||
This project (all files including the demos/examples) is licensed under the GNU LGPL, version 2.1.
|
This project (all files including the demos/examples) is licensed under the GNU LGPL, version 2.1.
|
||||||
|
|
||||||
|
|
||||||
**Copyright (c) 2014 - Tőkés Attila**
|
**Copyright (c) 2011 - Tőkés Attila**
|
||||||
|
53
SMTPEmail.pro
Normal file
53
SMTPEmail.pro
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2011-08-11T20:59:25
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += core network
|
||||||
|
|
||||||
|
TARGET = SMTPEmail
|
||||||
|
|
||||||
|
# Build as an application
|
||||||
|
#TEMPLATE = app
|
||||||
|
|
||||||
|
# Build as a library
|
||||||
|
TEMPLATE = lib
|
||||||
|
DEFINES += SMTP_BUILD
|
||||||
|
win32:CONFIG += dll
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
src/emailaddress.cpp \
|
||||||
|
src/mimeattachment.cpp \
|
||||||
|
src/mimefile.cpp \
|
||||||
|
src/mimehtml.cpp \
|
||||||
|
src/mimeinlinefile.cpp \
|
||||||
|
src/mimemessage.cpp \
|
||||||
|
src/mimepart.cpp \
|
||||||
|
src/mimetext.cpp \
|
||||||
|
src/smtpclient.cpp \
|
||||||
|
src/quotedprintable.cpp \
|
||||||
|
src/mimemultipart.cpp \
|
||||||
|
src/mimecontentformatter.cpp \
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
src/emailaddress.h \
|
||||||
|
src/mimeattachment.h \
|
||||||
|
src/mimefile.h \
|
||||||
|
src/mimehtml.h \
|
||||||
|
src/mimeinlinefile.h \
|
||||||
|
src/mimemessage.h \
|
||||||
|
src/mimepart.h \
|
||||||
|
src/mimetext.h \
|
||||||
|
src/smtpclient.h \
|
||||||
|
src/SmtpMime \
|
||||||
|
src/quotedprintable.h \
|
||||||
|
src/mimemultipart.h \
|
||||||
|
src/mimecontentformatter.h \
|
||||||
|
src/smtpexports.h
|
||||||
|
|
||||||
|
OTHER_FILES += \
|
||||||
|
LICENSE \
|
||||||
|
README.md
|
||||||
|
|
||||||
|
FORMS +=
|
@ -8,15 +8,27 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// This is a first demo application of the SmtpClient for Qt project
|
// This is a first demo application of the SmtpClient for Qt project
|
||||||
|
|
||||||
|
|
||||||
|
// First we need to create an SmtpClient object
|
||||||
|
// We will use the Gmail's smtp server (smtp.gmail.com, port 465, ssl)
|
||||||
|
|
||||||
|
SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);
|
||||||
|
|
||||||
|
// We need to set the username (your email address) and password
|
||||||
|
// for smtp authentification.
|
||||||
|
|
||||||
|
smtp.setUser("your_email_address@host.com");
|
||||||
|
smtp.setPassword("your_password");
|
||||||
|
|
||||||
// Now we create a MimeMessage object. This is the email.
|
// Now we create a MimeMessage object. This is the email.
|
||||||
|
|
||||||
MimeMessage message;
|
MimeMessage message;
|
||||||
|
|
||||||
EmailAddress sender("your_email_address@host.com", "Your Name");
|
EmailAddress sender("your_email_address@host.com", "Your Name");
|
||||||
message.setSender(sender);
|
message.setSender(&sender);
|
||||||
|
|
||||||
EmailAddress to("recipient@host.com", "Recipient's Name");
|
EmailAddress to("recipient@host.com", "Recipient's Name");
|
||||||
message.addRecipient(to);
|
message.addRecipient(&to);
|
||||||
|
|
||||||
message.setSubject("SmtpClient for Qt - Demo");
|
message.setSubject("SmtpClient for Qt - Demo");
|
||||||
|
|
||||||
@ -32,22 +44,18 @@ int main(int argc, char *argv[])
|
|||||||
message.addPart(&text);
|
message.addPart(&text);
|
||||||
|
|
||||||
// Now we can send the mail
|
// Now we can send the mail
|
||||||
SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);
|
|
||||||
|
|
||||||
smtp.connectToHost();
|
if (!smtp.connectToHost()) {
|
||||||
if (!smtp.waitForReadyConnected()) {
|
|
||||||
qDebug() << "Failed to connect to host!" << endl;
|
qDebug() << "Failed to connect to host!" << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
smtp.login("your_email_address@host.com", "your_password");
|
if (!smtp.login()) {
|
||||||
if (!smtp.waitForAuthenticated()) {
|
|
||||||
qDebug() << "Failed to login!" << endl;
|
qDebug() << "Failed to login!" << endl;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
smtp.sendMail(message);
|
if (!smtp.sendMail(message)) {
|
||||||
if (!smtp.waitForMailSent()) {
|
|
||||||
qDebug() << "Failed to send mail!" << endl;
|
qDebug() << "Failed to send mail!" << endl;
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@ SOURCES += \
|
|||||||
# Location of SMTP Library
|
# Location of SMTP Library
|
||||||
SMTP_LIBRARY_LOCATION = $$PWD/../../../build/SMTPEmail-Desktop-Debug
|
SMTP_LIBRARY_LOCATION = $$PWD/../../../build/SMTPEmail-Desktop-Debug
|
||||||
|
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/release/ -lSMTPMime
|
win32:CONFIG(release, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/release/ -lSMTPEmail
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/debug/ -lSMTPMime
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/debug/ -lSMTPEmail
|
||||||
else:unix: LIBS += -L$$SMTP_LIBRARY_LOCATION -lSmtpMime
|
else:unix: LIBS += -L$$SMTP_LIBRARY_LOCATION -lSMTPEmail
|
||||||
|
|
||||||
INCLUDEPATH += $$SMTP_LIBRARY_LOCATION
|
INCLUDEPATH += $$SMTP_LIBRARY_LOCATION
|
||||||
DEPENDPATH += $$SMTP_LIBRARY_LOCATION
|
DEPENDPATH += $$SMTP_LIBRARY_LOCATION
|
||||||
|
@ -18,9 +18,9 @@ SOURCES += \
|
|||||||
# Location of SMTP Library
|
# Location of SMTP Library
|
||||||
SMTP_LIBRARY_LOCATION = $$PWD/../../../build/SMTPEmail-Desktop-Debug
|
SMTP_LIBRARY_LOCATION = $$PWD/../../../build/SMTPEmail-Desktop-Debug
|
||||||
|
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/release/ -lSMTPMime
|
win32:CONFIG(release, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/release/ -lSMTPEmail
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/debug/ -lSMTPMime
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/debug/ -lSMTPEmail
|
||||||
else:unix: LIBS += -L$$SMTP_LIBRARY_LOCATION -lSmtpMime
|
else:unix: LIBS += -L$$SMTP_LIBRARY_LOCATION -lSMTPEmail
|
||||||
|
|
||||||
INCLUDEPATH += $$SMTP_LIBRARY_LOCATION
|
INCLUDEPATH += $$SMTP_LIBRARY_LOCATION
|
||||||
DEPENDPATH += $$SMTP_LIBRARY_LOCATION
|
DEPENDPATH += $$SMTP_LIBRARY_LOCATION
|
||||||
|
@ -37,7 +37,7 @@ SendEmail::~SendEmail()
|
|||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmailAddress SendEmail::stringToEmail(const QString &str)
|
EmailAddress* SendEmail::stringToEmail(const QString &str)
|
||||||
{
|
{
|
||||||
int p1 = str.indexOf("<");
|
int p1 = str.indexOf("<");
|
||||||
int p2 = str.indexOf(">");
|
int p2 = str.indexOf(">");
|
||||||
@ -45,11 +45,11 @@ EmailAddress SendEmail::stringToEmail(const QString &str)
|
|||||||
if (p1 == -1)
|
if (p1 == -1)
|
||||||
{
|
{
|
||||||
// no name, only email address
|
// no name, only email address
|
||||||
return EmailAddress(str);
|
return new EmailAddress(str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return EmailAddress(str.mid(p1 + 1, p2 - p1 - 1), str.left(p1));
|
return new EmailAddress(str.mid(p1 + 1, p2 - p1 - 1), str.left(p1));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -59,8 +59,11 @@ void SendEmail::on_addAttachment_clicked()
|
|||||||
QFileDialog dialog(this);
|
QFileDialog dialog(this);
|
||||||
dialog.setFileMode(QFileDialog::ExistingFiles);
|
dialog.setFileMode(QFileDialog::ExistingFiles);
|
||||||
|
|
||||||
|
|
||||||
if (dialog.exec())
|
if (dialog.exec())
|
||||||
ui->attachments->addItems(dialog.selectedFiles());
|
ui->attachments->addItems(dialog.selectedFiles());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendEmail::on_sendEmail_clicked()
|
void SendEmail::on_sendEmail_clicked()
|
||||||
@ -72,7 +75,7 @@ void SendEmail::on_sendEmail_clicked()
|
|||||||
QString user = ui->username->text();
|
QString user = ui->username->text();
|
||||||
QString password = ui->password->text();
|
QString password = ui->password->text();
|
||||||
|
|
||||||
EmailAddress sender = stringToEmail(ui->sender->text());
|
EmailAddress *sender = stringToEmail(ui->sender->text());
|
||||||
|
|
||||||
QStringList rcptStringList = ui->recipients->text().split(';');
|
QStringList rcptStringList = ui->recipients->text().split(';');
|
||||||
|
|
||||||
@ -99,25 +102,20 @@ void SendEmail::on_sendEmail_clicked()
|
|||||||
message.addPart(new MimeAttachment(new QFile(ui->attachments->item(i)->text())));
|
message.addPart(new MimeAttachment(new QFile(ui->attachments->item(i)->text())));
|
||||||
}
|
}
|
||||||
|
|
||||||
smtp.connectToHost();
|
if (!smtp.connectToHost())
|
||||||
if (!smtp.waitForReadyConnected())
|
|
||||||
{
|
{
|
||||||
errorMessage("Connection Failed");
|
errorMessage("Connection Failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auth)
|
if (auth)
|
||||||
{
|
if (!smtp.login(user, password))
|
||||||
smtp.login(user, password);
|
|
||||||
if (!smtp.waitForAuthenticated())
|
|
||||||
{
|
{
|
||||||
errorMessage("Authentification Failed");
|
errorMessage("Authentification Failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
smtp.sendMail(message);
|
if (!smtp.sendMail(message))
|
||||||
if (!smtp.waitForMailSent())
|
|
||||||
{
|
{
|
||||||
errorMessage("Mail sending failed");
|
errorMessage("Mail sending failed");
|
||||||
return;
|
return;
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include "../../src/SmtpMime"
|
#include "../../src/SmtpMime"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class SendEmail;
|
class SendEmail;
|
||||||
}
|
}
|
||||||
@ -33,7 +35,7 @@ public:
|
|||||||
explicit SendEmail(QWidget *parent = 0);
|
explicit SendEmail(QWidget *parent = 0);
|
||||||
~SendEmail();
|
~SendEmail();
|
||||||
|
|
||||||
static EmailAddress stringToEmail(const QString & str);
|
static EmailAddress * stringToEmail(const QString & str);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_addAttachment_clicked();
|
void on_addAttachment_clicked();
|
||||||
|
@ -22,14 +22,22 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
QCoreApplication a(argc, argv);
|
QCoreApplication a(argc, argv);
|
||||||
|
|
||||||
|
// First create the SmtpClient object and set the user and the password.
|
||||||
|
|
||||||
|
SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);
|
||||||
|
|
||||||
|
smtp.setUser("your_email@host.com");
|
||||||
|
smtp.setPassword("your_password");
|
||||||
|
|
||||||
// Create a MimeMessage
|
// Create a MimeMessage
|
||||||
|
|
||||||
MimeMessage message;
|
MimeMessage message;
|
||||||
|
|
||||||
EmailAddress sender("your_email_address@host.com", "Your Name");
|
EmailAddress sender("your_email_address@host.com", "Your Name");
|
||||||
message.setSender(sender);
|
message.setSender(&sender);
|
||||||
|
|
||||||
EmailAddress to("recipient@host.com", "Recipient's Name");
|
EmailAddress to("recipient@host.com", "Recipient's Name");
|
||||||
message.addRecipient(to);
|
message.addRecipient(&to);
|
||||||
|
|
||||||
message.setSubject("SmtpClient for Qt - Demo");
|
message.setSubject("SmtpClient for Qt - Demo");
|
||||||
|
|
||||||
@ -52,22 +60,18 @@ int main(int argc, char *argv[])
|
|||||||
message.addPart(&document);
|
message.addPart(&document);
|
||||||
|
|
||||||
// Now we can send the mail
|
// Now we can send the mail
|
||||||
SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);
|
|
||||||
|
|
||||||
smtp.connectToHost();
|
if (!smtp.connectToHost()) {
|
||||||
if (!smtp.waitForReadyConnected()) {
|
|
||||||
qDebug() << "Failed to connect to host!" << endl;
|
qDebug() << "Failed to connect to host!" << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
smtp.login("your_email_address@host.com", "your_password");
|
if (!smtp.login()) {
|
||||||
if (!smtp.waitForAuthenticated()) {
|
|
||||||
qDebug() << "Failed to login!" << endl;
|
qDebug() << "Failed to login!" << endl;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
smtp.sendMail(message);
|
if (!smtp.sendMail(message)) {
|
||||||
if (!smtp.waitForMailSent()) {
|
|
||||||
qDebug() << "Failed to send mail!" << endl;
|
qDebug() << "Failed to send mail!" << endl;
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ SOURCES += \
|
|||||||
# Location of SMTP Library
|
# Location of SMTP Library
|
||||||
SMTP_LIBRARY_LOCATION = $$PWD/../../../build/SMTPEmail-Desktop-Debug
|
SMTP_LIBRARY_LOCATION = $$PWD/../../../build/SMTPEmail-Desktop-Debug
|
||||||
|
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/release/ -lSMTPMime
|
win32:CONFIG(release, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/release/ -lSMTPEmail
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/debug/ -lSMTPMime
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/debug/ -lSMTPEmail
|
||||||
else:unix: LIBS += -L$$SMTP_LIBRARY_LOCATION -lSmtpMime
|
else:unix: LIBS += -L$$SMTP_LIBRARY_LOCATION -lSMTPEmail
|
||||||
|
|
||||||
INCLUDEPATH += $$SMTP_LIBRARY_LOCATION
|
INCLUDEPATH += $$SMTP_LIBRARY_LOCATION
|
||||||
DEPENDPATH += $$SMTP_LIBRARY_LOCATION
|
DEPENDPATH += $$SMTP_LIBRARY_LOCATION
|
||||||
|
@ -22,15 +22,22 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
QCoreApplication a(argc, argv);
|
QCoreApplication a(argc, argv);
|
||||||
|
|
||||||
|
// First create the SmtpClient object and set the user and the password.
|
||||||
|
|
||||||
|
SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);
|
||||||
|
|
||||||
|
smtp.setUser("your_email@host.com");
|
||||||
|
smtp.setPassword("your_password");
|
||||||
|
|
||||||
// Create a MimeMessage
|
// Create a MimeMessage
|
||||||
|
|
||||||
MimeMessage message;
|
MimeMessage message;
|
||||||
|
|
||||||
EmailAddress sender("your_email_address@host.com", "Your Name");
|
EmailAddress sender("your_email_address@host.com", "Your Name");
|
||||||
message.setSender(sender);
|
message.setSender(&sender);
|
||||||
|
|
||||||
EmailAddress to("recipient@host.com", "Recipient's Name");
|
EmailAddress to("recipient@host.com", "Recipient's Name");
|
||||||
message.addRecipient(to);
|
message.addRecipient(&to);
|
||||||
|
|
||||||
message.setSubject("SmtpClient for Qt - Example 3 - Html email with images");
|
message.setSubject("SmtpClient for Qt - Example 3 - Html email with images");
|
||||||
|
|
||||||
@ -59,26 +66,22 @@ int main(int argc, char *argv[])
|
|||||||
message.addPart(&image1);
|
message.addPart(&image1);
|
||||||
message.addPart(&image2);
|
message.addPart(&image2);
|
||||||
|
|
||||||
// Now we can send the mail
|
// Now the email can be sended
|
||||||
SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);
|
if (!smtp.connectToHost()) {
|
||||||
|
|
||||||
smtp.connectToHost();
|
|
||||||
if (!smtp.waitForReadyConnected()) {
|
|
||||||
qDebug() << "Failed to connect to host!" << endl;
|
qDebug() << "Failed to connect to host!" << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
smtp.login("your_email_address@host.com", "your_password");
|
if (!smtp.login()) {
|
||||||
if (!smtp.waitForAuthenticated()) {
|
|
||||||
qDebug() << "Failed to login!" << endl;
|
qDebug() << "Failed to login!" << endl;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
smtp.sendMail(message);
|
if (!smtp.sendMail(message)) {
|
||||||
if (!smtp.waitForMailSent()) {
|
|
||||||
qDebug() << "Failed to send mail!" << endl;
|
qDebug() << "Failed to send mail!" << endl;
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
smtp.quit();
|
smtp.quit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ SOURCES += \
|
|||||||
# Location of SMTP Library
|
# Location of SMTP Library
|
||||||
SMTP_LIBRARY_LOCATION = $$PWD/../../../build/SMTPEmail-Desktop-Debug
|
SMTP_LIBRARY_LOCATION = $$PWD/../../../build/SMTPEmail-Desktop-Debug
|
||||||
|
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/release/ -lSMTPMime
|
win32:CONFIG(release, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/release/ -lSMTPEmail
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/debug/ -lSMTPMime
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$SMTP_LIBRARY_LOCATION/debug/ -lSMTPEmail
|
||||||
else:unix: LIBS += -L$$SMTP_LIBRARY_LOCATION -lSmtpMime
|
else:unix: LIBS += -L$$SMTP_LIBRARY_LOCATION -lSMTPEmail
|
||||||
|
|
||||||
INCLUDEPATH += $$SMTP_LIBRARY_LOCATION
|
INCLUDEPATH += $$SMTP_LIBRARY_LOCATION
|
||||||
DEPENDPATH += $$SMTP_LIBRARY_LOCATION
|
DEPENDPATH += $$SMTP_LIBRARY_LOCATION
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
#-------------------------------------------------
|
|
||||||
#
|
|
||||||
# Project created by QtCreator 2011-08-11T20:59:25
|
|
||||||
#
|
|
||||||
#-------------------------------------------------
|
|
||||||
|
|
||||||
QT = core network
|
|
||||||
|
|
||||||
TARGET = SmtpMime
|
|
||||||
TEMPLATE = lib
|
|
||||||
|
|
||||||
DEFINES += SMTP_MIME_LIBRARY
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
emailaddress.cpp \
|
|
||||||
mimeattachment.cpp \
|
|
||||||
mimefile.cpp \
|
|
||||||
mimehtml.cpp \
|
|
||||||
mimeinlinefile.cpp \
|
|
||||||
mimemessage.cpp \
|
|
||||||
mimepart.cpp \
|
|
||||||
mimetext.cpp \
|
|
||||||
smtpclient.cpp \
|
|
||||||
quotedprintable.cpp \
|
|
||||||
mimemultipart.cpp \
|
|
||||||
mimecontentencoder.cpp \
|
|
||||||
mimebase64encoder.cpp \
|
|
||||||
mimeqpencoder.cpp \
|
|
||||||
mimeqpformatter.cpp \
|
|
||||||
mimebase64formatter.cpp \
|
|
||||||
mimecontentformatter.cpp
|
|
||||||
|
|
||||||
HEADERS += \
|
|
||||||
emailaddress.h \
|
|
||||||
mimeattachment.h \
|
|
||||||
mimefile.h \
|
|
||||||
mimehtml.h \
|
|
||||||
mimeinlinefile.h \
|
|
||||||
mimemessage.h \
|
|
||||||
mimepart.h \
|
|
||||||
mimetext.h \
|
|
||||||
smtpclient.h \
|
|
||||||
SmtpMime \
|
|
||||||
quotedprintable.h \
|
|
||||||
mimemultipart.h \
|
|
||||||
smtpmime_global.h \
|
|
||||||
mimecontentencoder.h \
|
|
||||||
mimebase64encoder.h \
|
|
||||||
mimeqpencoder.h \
|
|
||||||
mimeqpformatter.h \
|
|
||||||
mimebase64formatter.h \
|
|
||||||
mimecontentformatter.h
|
|
||||||
|
|
||||||
OTHER_FILES += \
|
|
||||||
LICENSE \
|
|
||||||
README.md
|
|
||||||
|
|
||||||
FORMS +=
|
|
@ -27,6 +27,5 @@
|
|||||||
#include "mimetext.h"
|
#include "mimetext.h"
|
||||||
#include "mimeinlinefile.h"
|
#include "mimeinlinefile.h"
|
||||||
#include "mimefile.h"
|
#include "mimefile.h"
|
||||||
#include "mimebytearrayattachment.h"
|
|
||||||
|
|
||||||
#endif // SMTPMIME_H
|
#endif // SMTPMIME_H
|
||||||
|
@ -21,13 +21,9 @@
|
|||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
EmailAddress::EmailAddress(const QString & address, const QString & name)
|
EmailAddress::EmailAddress(const QString & address, const QString & name)
|
||||||
: address(address), name(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
EmailAddress::EmailAddress(const EmailAddress &other)
|
|
||||||
: address(other.address), name(other.name)
|
|
||||||
{
|
{
|
||||||
|
this->address = address;
|
||||||
|
this->name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmailAddress::~EmailAddress()
|
EmailAddress::~EmailAddress()
|
||||||
@ -39,13 +35,23 @@ EmailAddress::~EmailAddress()
|
|||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
void EmailAddress::setName(const QString & name)
|
||||||
|
{
|
||||||
|
this->name = name;
|
||||||
|
|
||||||
QString EmailAddress::getName() const
|
}
|
||||||
|
|
||||||
|
void EmailAddress::setAddress(const QString & address)
|
||||||
|
{
|
||||||
|
this->address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & EmailAddress::getName() const
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString EmailAddress::getAddress() const
|
const QString & EmailAddress::getAddress() const
|
||||||
{
|
{
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
@ -19,17 +19,19 @@
|
|||||||
#ifndef EMAILADDRESS_H
|
#ifndef EMAILADDRESS_H
|
||||||
#define EMAILADDRESS_H
|
#define EMAILADDRESS_H
|
||||||
|
|
||||||
#include "smtpmime_global.h"
|
#include <QObject>
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT EmailAddress
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT EmailAddress : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
EmailAddress(const QString & address = "", const QString & name = "");
|
EmailAddress();
|
||||||
EmailAddress(const EmailAddress &other);
|
EmailAddress(const QString & address, const QString & name="");
|
||||||
|
|
||||||
~EmailAddress();
|
~EmailAddress();
|
||||||
|
|
||||||
@ -37,9 +39,11 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
void setName(const QString & name);
|
||||||
|
void setAddress(const QString & address);
|
||||||
|
|
||||||
QString getAddress() const;
|
const QString & getName() const;
|
||||||
QString getName() const;
|
const QString & getAddress() const;
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
@ -48,8 +52,8 @@ private:
|
|||||||
|
|
||||||
/* [3] Private members */
|
/* [3] Private members */
|
||||||
|
|
||||||
QString address;
|
|
||||||
QString name;
|
QString name;
|
||||||
|
QString address;
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,10 @@
|
|||||||
MimeAttachment::MimeAttachment(QFile *file)
|
MimeAttachment::MimeAttachment(QFile *file)
|
||||||
: MimeFile(file)
|
: MimeFile(file)
|
||||||
{
|
{
|
||||||
this->headerLines += "Content-disposition: attachment\r\n";
|
}
|
||||||
|
MimeAttachment::MimeAttachment(const QByteArray& stream, const QString& fileName): MimeFile(stream, fileName)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeAttachment::~MimeAttachment()
|
MimeAttachment::~MimeAttachment()
|
||||||
@ -36,4 +39,12 @@ MimeAttachment::~MimeAttachment()
|
|||||||
|
|
||||||
/* [2] Protected methods */
|
/* [2] Protected methods */
|
||||||
|
|
||||||
|
void MimeAttachment::prepare()
|
||||||
|
{
|
||||||
|
this->header += "Content-disposition: attachment\r\n";
|
||||||
|
|
||||||
|
/* !!! IMPORTANT !!! */
|
||||||
|
MimeFile::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
@ -19,18 +19,22 @@
|
|||||||
#ifndef MIMEATTACHMENT_H
|
#ifndef MIMEATTACHMENT_H
|
||||||
#define MIMEATTACHMENT_H
|
#define MIMEATTACHMENT_H
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
#include "smtpmime_global.h"
|
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
#include "mimefile.h"
|
#include "mimefile.h"
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT MimeAttachment : public MimeFile
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeAttachment : public MimeFile
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeAttachment(QFile* file);
|
MimeAttachment(QFile* file);
|
||||||
|
MimeAttachment(const QByteArray& stream, const QString& fileName);
|
||||||
|
|
||||||
~MimeAttachment();
|
~MimeAttachment();
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
@ -38,6 +42,9 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* [2] Protected methods */
|
/* [2] Protected methods */
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#include "mimebase64encoder.h"
|
|
||||||
|
|
||||||
MimeBase64Encoder::MimeBase64Encoder() {}
|
|
||||||
|
|
||||||
QByteArray MimeBase64Encoder::encode(const QByteArray &data) {
|
|
||||||
return data.toBase64();
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
#ifndef MIMEBASE64ENCODER_H
|
|
||||||
#define MIMEBASE64ENCODER_H
|
|
||||||
|
|
||||||
#include "mimecontentencoder.h"
|
|
||||||
|
|
||||||
class MimeBase64Encoder : public MimeContentEncoder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MimeBase64Encoder();
|
|
||||||
|
|
||||||
QByteArray encode(const QByteArray &data);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MIMEBASE64ENCODER_H
|
|
@ -1,16 +0,0 @@
|
|||||||
#include "mimebase64formatter.h"
|
|
||||||
|
|
||||||
MimeBase64Formatter::MimeBase64Formatter(QIODevice *out) :
|
|
||||||
MimeContentFormatter(out) {}
|
|
||||||
|
|
||||||
qint64 MimeBase64Formatter::writeData(const char *data, qint64 maxLength) {
|
|
||||||
int lines = (maxLength - 1) / lineLength + 1;
|
|
||||||
for (int i = 1; i < lines; ++i) {
|
|
||||||
output->write(data, lineLength);
|
|
||||||
output->write("\r\n");
|
|
||||||
data += lineLength;
|
|
||||||
}
|
|
||||||
output->write(data, maxLength - (lines - 1) * lineLength);
|
|
||||||
output->write("\r\n");
|
|
||||||
return maxLength;
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
#ifndef MIMEBASE64FORMATTER_H
|
|
||||||
#define MIMEBASE64FORMATTER_H
|
|
||||||
|
|
||||||
#include "mimecontentformatter.h"
|
|
||||||
|
|
||||||
class MimeBase64Formatter : public MimeContentFormatter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MimeBase64Formatter(QIODevice*);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual qint64 writeData(const char *data, qint64 len);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MIMEBASE64FORMATTER_H
|
|
@ -1,13 +0,0 @@
|
|||||||
#include "mimebytearrayattachment.h"
|
|
||||||
|
|
||||||
MimeByteArrayAttachment::MimeByteArrayAttachment(const QString& name, const QByteArray &content) :
|
|
||||||
MimePart()
|
|
||||||
{
|
|
||||||
this->cType = "application/octet-stream";
|
|
||||||
this->cEncoding = Base64;
|
|
||||||
this->cName = name,
|
|
||||||
this->content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
MimeByteArrayAttachment::~MimeByteArrayAttachment() {}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
|||||||
#ifndef MIMEBYTEARRAYATTACHMENT_H
|
|
||||||
#define MIMEBYTEARRAYATTACHMENT_H
|
|
||||||
|
|
||||||
#include "smtpmime_global.h"
|
|
||||||
#include "mimepart.h"
|
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT MimeByteArrayAttachment : public MimePart
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/* [1] Constructors and Destructors */
|
|
||||||
|
|
||||||
MimeByteArrayAttachment(const QString& name, const QByteArray &content);
|
|
||||||
~MimeByteArrayAttachment();
|
|
||||||
|
|
||||||
/* [1] --- */
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MIMEBYTEARRAYATTACHMENT_H
|
|
@ -1,3 +0,0 @@
|
|||||||
#include "mimecontentencoder.h"
|
|
||||||
|
|
||||||
MimeContentEncoder::MimeContentEncoder() {}
|
|
@ -1,16 +0,0 @@
|
|||||||
#ifndef MIMEENCODER_H
|
|
||||||
#define MIMEENCODER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QByteArray>
|
|
||||||
|
|
||||||
class MimeContentEncoder : public QObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual QByteArray encode(const QByteArray &data) =0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
MimeContentEncoder();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MIMEENCODER_H
|
|
@ -1,20 +1,66 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mimecontentformatter.h"
|
#include "mimecontentformatter.h"
|
||||||
|
|
||||||
MimeContentFormatter::MimeContentFormatter(QIODevice *out, int length) :
|
MimeContentFormatter::MimeContentFormatter(int max_length) :
|
||||||
output(out),
|
max_length(max_length)
|
||||||
lineLength(length)
|
{}
|
||||||
{
|
|
||||||
QIODevice::open(WriteOnly);
|
QString MimeContentFormatter::format(const QString &content, bool quotedPrintable) const {
|
||||||
|
|
||||||
|
QString out;
|
||||||
|
|
||||||
|
int chars = 0;
|
||||||
|
for (int i = 0; i < content.length() ; ++i) {
|
||||||
|
chars++;
|
||||||
|
if (!quotedPrintable) {
|
||||||
|
if (chars > max_length) {
|
||||||
|
out.append("\r\n");
|
||||||
|
chars = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (content[i] == '\n') { // new line
|
||||||
|
out.append(content[i]);
|
||||||
|
chars = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((chars > max_length - 1)
|
||||||
|
|| ((content[i] == '=') && (chars > max_length - 3) )) {
|
||||||
|
out.append('=');
|
||||||
|
out.append("\r\n");
|
||||||
|
chars = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
out.append(content[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int MimeContentFormatter::getLineLength() const {
|
void MimeContentFormatter::setMaxLength(int l) {
|
||||||
return lineLength;
|
max_length = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeContentFormatter::setLineLength(int l) {
|
int MimeContentFormatter::getMaxLength() const {
|
||||||
lineLength = l;
|
return max_length;
|
||||||
}
|
|
||||||
|
|
||||||
qint64 MimeContentFormatter::readData(char*, qint64) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,43 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef MIMECONTENTFORMATTER_H
|
#ifndef MIMECONTENTFORMATTER_H
|
||||||
#define MIMECONTENTFORMATTER_H
|
#define MIMECONTENTFORMATTER_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QIODevice>
|
#include <QByteArray>
|
||||||
|
|
||||||
class MimeContentFormatter : public QIODevice
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeContentFormatter : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MimeContentFormatter(QIODevice *device, int lineLength = 76);
|
MimeContentFormatter (int max_length = 76);
|
||||||
|
|
||||||
int getLineLength() const;
|
void setMaxLength(int l);
|
||||||
void setLineLength(int l);
|
int getMaxLength() const;
|
||||||
|
|
||||||
|
QString format(const QString &content, bool quotedPrintable = false) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
qint64 readData(char *data, qint64 maxlen);
|
int max_length;
|
||||||
qint64 writeData(const char *data, qint64 len) = 0;
|
|
||||||
|
|
||||||
QIODevice *output;
|
|
||||||
int lineLength;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MIMECONTENTFORMATTER_H
|
#endif // MIMECONTENTFORMATTER_H
|
||||||
|
@ -29,8 +29,18 @@ MimeFile::MimeFile(QFile *file)
|
|||||||
this->cEncoding = Base64;
|
this->cEncoding = Base64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MimeFile::MimeFile(const QByteArray& stream, const QString& fileName)
|
||||||
|
{
|
||||||
|
this->cEncoding = Base64;
|
||||||
|
this->cType = "application/octet-stream";
|
||||||
|
this->file = 0;
|
||||||
|
this->cName = fileName;
|
||||||
|
this->content = stream;
|
||||||
|
}
|
||||||
|
|
||||||
MimeFile::~MimeFile()
|
MimeFile::~MimeFile()
|
||||||
{
|
{
|
||||||
|
if (file)
|
||||||
delete file;
|
delete file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,13 +54,16 @@ MimeFile::~MimeFile()
|
|||||||
|
|
||||||
/* [3] Protected methods */
|
/* [3] Protected methods */
|
||||||
|
|
||||||
|
void MimeFile::prepare()
|
||||||
void MimeFile::writeContent(QIODevice &device) const {
|
{
|
||||||
file->open(QIODevice::ReadOnly);
|
if (this->file)
|
||||||
const QByteArray &fileContent = file->readAll();
|
{
|
||||||
|
file->open(QIODevice::ReadOnly);
|
||||||
|
this->content = file->readAll();
|
||||||
file->close();
|
file->close();
|
||||||
|
}
|
||||||
MimePart::writeContent(device, fileContent);
|
/* !!! IMPORTANT !!!! */
|
||||||
|
MimePart::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -20,16 +20,18 @@
|
|||||||
#define MIMEFILE_H
|
#define MIMEFILE_H
|
||||||
|
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
#include "smtpmime_global.h"
|
#include <QFile>
|
||||||
|
|
||||||
class QFile;
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT MimeFile : public MimePart
|
class SMTP_EXPORT MimeFile : public MimePart
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeFile(const QByteArray& stream, const QString& fileName);
|
||||||
MimeFile(QFile *f);
|
MimeFile(QFile *f);
|
||||||
~MimeFile();
|
~MimeFile();
|
||||||
|
|
||||||
@ -51,8 +53,7 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
void writeContent(QIODevice &device) const;
|
virtual void prepare();
|
||||||
|
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ void MimeHtml::setHtml(const QString & html)
|
|||||||
this->text = html;
|
this->text = html;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MimeHtml::getHtml() const
|
const QString & MimeHtml::getHtml() const
|
||||||
{
|
{
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
@ -48,4 +48,10 @@ QString MimeHtml::getHtml() const
|
|||||||
|
|
||||||
/* [3] Protected methods */
|
/* [3] Protected methods */
|
||||||
|
|
||||||
|
void MimeHtml::prepare()
|
||||||
|
{
|
||||||
|
/* !!! IMPORTANT !!! */
|
||||||
|
MimeText::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -19,11 +19,13 @@
|
|||||||
#ifndef MIMEHTML_H
|
#ifndef MIMEHTML_H
|
||||||
#define MIMEHTML_H
|
#define MIMEHTML_H
|
||||||
|
|
||||||
#include "smtpmime_global.h"
|
|
||||||
#include "mimetext.h"
|
#include "mimetext.h"
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT MimeHtml : public MimeText
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeHtml : public MimeText
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
@ -38,7 +40,7 @@ public:
|
|||||||
|
|
||||||
void setHtml(const QString & html);
|
void setHtml(const QString & html);
|
||||||
|
|
||||||
QString getHtml() const;
|
const QString& getHtml() const;
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
@ -51,6 +53,8 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
MimeInlineFile::MimeInlineFile(QFile *f)
|
MimeInlineFile::MimeInlineFile(QFile *f)
|
||||||
: MimeFile(f)
|
: MimeFile(f)
|
||||||
{
|
{
|
||||||
addHeaderLine("Content-Disposition: inline");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeInlineFile::~MimeInlineFile()
|
MimeInlineFile::~MimeInlineFile()
|
||||||
@ -39,6 +38,14 @@ MimeInlineFile::~MimeInlineFile()
|
|||||||
|
|
||||||
/* [3] Protected methods */
|
/* [3] Protected methods */
|
||||||
|
|
||||||
|
void MimeInlineFile::prepare()
|
||||||
|
{
|
||||||
|
this->header += "Content-Disposition: inline\r\n";
|
||||||
|
|
||||||
|
/* !!! IMPORTANT !!! */
|
||||||
|
MimeFile::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,10 +19,11 @@
|
|||||||
#ifndef MIMEINLINEFILE_H
|
#ifndef MIMEINLINEFILE_H
|
||||||
#define MIMEINLINEFILE_H
|
#define MIMEINLINEFILE_H
|
||||||
|
|
||||||
#include "smtpmime_global.h"
|
|
||||||
#include "mimefile.h"
|
#include "mimefile.h"
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT MimeInlineFile : public MimeFile
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeInlineFile : public MimeFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -47,6 +48,8 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,23 +18,29 @@
|
|||||||
|
|
||||||
#include "mimemessage.h"
|
#include "mimemessage.h"
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QBuffer>
|
#include <QLocale>
|
||||||
#include "quotedprintable.h"
|
#include "quotedprintable.h"
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeMessage::MimeMessage(bool createAutoMimeContent) :
|
MimeMessage::MimeMessage(bool createAutoMimeContent) :
|
||||||
|
replyTo(nullptr),
|
||||||
hEncoding(MimePart::_8Bit)
|
hEncoding(MimePart::_8Bit)
|
||||||
{
|
{
|
||||||
if (createAutoMimeContent)
|
if (createAutoMimeContent)
|
||||||
this->content = new MimeMultiPart();
|
this->content = new MimeMultiPart();
|
||||||
|
|
||||||
|
autoMimeContentCreated = createAutoMimeContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeMessage::~MimeMessage()
|
MimeMessage::~MimeMessage()
|
||||||
{
|
{
|
||||||
|
if (this->autoMimeContentCreated)
|
||||||
|
{
|
||||||
|
this->autoMimeContentCreated = false;
|
||||||
|
delete (this->content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
@ -46,15 +52,25 @@ MimePart& MimeMessage::getContent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::setContent(MimePart *content) {
|
void MimeMessage::setContent(MimePart *content) {
|
||||||
|
if (this->autoMimeContentCreated)
|
||||||
|
{
|
||||||
|
this->autoMimeContentCreated = false;
|
||||||
|
delete (this->content);
|
||||||
|
}
|
||||||
this->content = content;
|
this->content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::setSender(const EmailAddress &sender)
|
void MimeMessage::setReplyTo(EmailAddress* rto) {
|
||||||
{
|
replyTo = rto;
|
||||||
this->sender = sender;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::addRecipient(const EmailAddress &rcpt, RecipientType type)
|
void MimeMessage::setSender(EmailAddress* e)
|
||||||
|
{
|
||||||
|
this->sender = e;
|
||||||
|
e->setParent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::addRecipient(EmailAddress* rcpt, RecipientType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -68,25 +84,22 @@ void MimeMessage::addRecipient(const EmailAddress &rcpt, RecipientType type)
|
|||||||
recipientsBcc << rcpt;
|
recipientsBcc << rcpt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rcpt->setParent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::addTo(const EmailAddress &rcpt) {
|
void MimeMessage::addTo(EmailAddress* rcpt) {
|
||||||
this->recipientsTo << rcpt;
|
this->recipientsTo << rcpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::addCc(const EmailAddress &rcpt) {
|
void MimeMessage::addCc(EmailAddress* rcpt) {
|
||||||
this->recipientsCc << rcpt;
|
this->recipientsCc << rcpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::addBcc(const EmailAddress &rcpt) {
|
void MimeMessage::addBcc(EmailAddress* rcpt) {
|
||||||
this->recipientsBcc << rcpt;
|
this->recipientsBcc << rcpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::addCustomHeader(const QString &header)
|
|
||||||
{
|
|
||||||
this->customHeaders << header;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MimeMessage::setSubject(const QString & subject)
|
void MimeMessage::setSubject(const QString & subject)
|
||||||
{
|
{
|
||||||
this->subject = subject;
|
this->subject = subject;
|
||||||
@ -99,17 +112,22 @@ void MimeMessage::addPart(MimePart *part)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MimeMessage::setInReplyTo(const QString& inReplyTo)
|
||||||
|
{
|
||||||
|
mInReplyTo = inReplyTo;
|
||||||
|
}
|
||||||
|
|
||||||
void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc)
|
void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc)
|
||||||
{
|
{
|
||||||
this->hEncoding = hEnc;
|
this->hEncoding = hEnc;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmailAddress MimeMessage::getSender() const
|
const EmailAddress & MimeMessage::getSender() const
|
||||||
{
|
{
|
||||||
return sender;
|
return *sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<EmailAddress> & MimeMessage::getRecipients(RecipientType type) const
|
const QList<EmailAddress*> & MimeMessage::getRecipients(RecipientType type) const
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -123,7 +141,11 @@ const QList<EmailAddress> & MimeMessage::getRecipients(RecipientType type) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MimeMessage::getSubject() const
|
const EmailAddress* MimeMessage::getReplyTo() const {
|
||||||
|
return replyTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & MimeMessage::getSubject() const
|
||||||
{
|
{
|
||||||
return subject;
|
return subject;
|
||||||
}
|
}
|
||||||
@ -145,88 +167,149 @@ const QList<MimePart*> & MimeMessage::getParts() const
|
|||||||
|
|
||||||
/* [3] Public Methods */
|
/* [3] Public Methods */
|
||||||
|
|
||||||
QString MimeMessage::toString() const
|
QString MimeMessage::toString()
|
||||||
{
|
{
|
||||||
QBuffer out;
|
QString mime;
|
||||||
out.open(QIODevice::WriteOnly);
|
|
||||||
writeToDevice(out);
|
|
||||||
return QString(out.buffer());
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray MimeMessage::formatAddress(const EmailAddress &address, MimePart::Encoding encoding) {
|
|
||||||
QByteArray result;
|
|
||||||
result.append(format(address.getName(), encoding));
|
|
||||||
result.append(" <" + address.getAddress() + ">");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray MimeMessage::format(const QString &text, MimePart::Encoding encoding)
|
|
||||||
{
|
|
||||||
QByteArray result;
|
|
||||||
if (!text.isEmpty())
|
|
||||||
{
|
|
||||||
switch (encoding)
|
|
||||||
{
|
|
||||||
case MimePart::Base64:
|
|
||||||
result.append(" =?utf-8?B?" + text.toUtf8().toBase64() + "?=");
|
|
||||||
break;
|
|
||||||
case MimePart::QuotedPrintable:
|
|
||||||
result.append(" =?utf-8?Q?" + QuotedPrintable::encode(text.toUtf8()).toLocal8Bit().replace(' ', "_").replace(':',"=3A") + "?=");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result.append(" ").append(text.toLocal8Bit());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MimeMessage::writeToDevice(QIODevice &out) const {
|
|
||||||
/* =========== MIME HEADER ============ */
|
/* =========== MIME HEADER ============ */
|
||||||
|
|
||||||
/* ---------- Sender / From ----------- */
|
/* ---------- Sender / From ----------- */
|
||||||
QByteArray header;
|
mime = "From:";
|
||||||
header.append("From:" + formatAddress(sender, hEncoding) + "\r\n");
|
if (sender->getName() != "")
|
||||||
|
{
|
||||||
|
switch (hEncoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
mime += " =?utf-8?B?" + QByteArray().append(sender->getName()).toBase64() + "?=";
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(sender->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mime += " " + sender->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mime += " <" + sender->getAddress() + ">\r\n";
|
||||||
/* ---------------------------------- */
|
/* ---------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
/* ------- Recipients / To ---------- */
|
/* ------- Recipients / To ---------- */
|
||||||
header.append("To:");
|
mime += "To:";
|
||||||
for (int i = 0; i<recipientsTo.size(); ++i)
|
QList<EmailAddress*>::iterator it; int i;
|
||||||
|
for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i)
|
||||||
{
|
{
|
||||||
if (i != 0) { header.append(","); }
|
if (i != 0) { mime += ","; }
|
||||||
header.append(formatAddress(recipientsTo.at(i), hEncoding));
|
|
||||||
|
if ((*it)->getName() != "")
|
||||||
|
{
|
||||||
|
switch (hEncoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
mime += " =?utf-8?B?" + QByteArray().append((*it)->getName()).toBase64() + "?=";
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append((*it)->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mime += " " + (*it)->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mime += " <" + (*it)->getAddress() + ">";
|
||||||
}
|
}
|
||||||
header.append("\r\n");
|
mime += "\r\n";
|
||||||
/* ---------------------------------- */
|
/* ---------------------------------- */
|
||||||
|
|
||||||
/* ------- Recipients / Cc ---------- */
|
/* ------- Recipients / Cc ---------- */
|
||||||
if (recipientsCc.size() != 0) {
|
if (recipientsCc.size() != 0) {
|
||||||
header.append("Cc:");
|
mime += "Cc:";
|
||||||
}
|
}
|
||||||
for (int i = 0; i<recipientsCc.size(); ++i)
|
for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i)
|
||||||
{
|
{
|
||||||
if (i != 0) { header.append(","); }
|
if (i != 0) { mime += ","; }
|
||||||
header.append(formatAddress(recipientsCc.at(i), hEncoding));
|
|
||||||
|
if ((*it)->getName() != "")
|
||||||
|
{
|
||||||
|
switch (hEncoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
mime += " =?utf-8?B?" + QByteArray().append((*it)->getName()).toBase64() + "?=";
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append((*it)->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mime += " " + (*it)->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mime += " <" + (*it)->getAddress() + ">";
|
||||||
}
|
}
|
||||||
if (recipientsCc.size() != 0) {
|
if (recipientsCc.size() != 0) {
|
||||||
header.append("\r\n");
|
mime += "\r\n";
|
||||||
}
|
}
|
||||||
/* ---------------------------------- */
|
/* ---------------------------------- */
|
||||||
|
|
||||||
/* ------------ Subject ------------- */
|
/* ------------ Subject ------------- */
|
||||||
header.append("Subject: ");
|
mime += "Subject: ";
|
||||||
header.append(format(subject, hEncoding));
|
|
||||||
header.append("\r\n");
|
|
||||||
|
switch (hEncoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
mime += "=?utf-8?B?" + QByteArray().append(subject).toBase64() + "?=";
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
mime += "=?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(subject)).replace(' ', "_").replace(':',"=3A") + "?=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mime += subject;
|
||||||
|
}
|
||||||
|
mime += "\r\n";
|
||||||
/* ---------------------------------- */
|
/* ---------------------------------- */
|
||||||
|
|
||||||
foreach (QString hdr, customHeaders) {
|
/* ---------- Reply-To -------------- */
|
||||||
header.append(hdr.toLocal8Bit());
|
if (replyTo) {
|
||||||
header.append("\r\n");
|
mime += "Reply-To: ";
|
||||||
|
if (replyTo->getName() != "")
|
||||||
|
{
|
||||||
|
switch (hEncoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
mime += " =?utf-8?B?" + QByteArray().append(replyTo->getName()).toBase64() + "?=";
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(replyTo->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mime += " " + replyTo->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mime += " <" + replyTo->getAddress() + ">\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
header.append("MIME-Version: 1.0\r\n");
|
/* ---------------------------------- */
|
||||||
|
|
||||||
out.write(header);
|
mime += "MIME-Version: 1.0\r\n";
|
||||||
content->writeToDevice(out);
|
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] --- */
|
/* [3] --- */
|
||||||
|
@ -19,15 +19,14 @@
|
|||||||
#ifndef MIMEMESSAGE_H
|
#ifndef MIMEMESSAGE_H
|
||||||
#define MIMEMESSAGE_H
|
#define MIMEMESSAGE_H
|
||||||
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QTextStream>
|
|
||||||
|
|
||||||
#include "smtpmime_global.h"
|
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
#include "mimemultipart.h"
|
#include "mimemultipart.h"
|
||||||
#include "emailaddress.h"
|
#include "emailaddress.h"
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT MimeMessage : public QObject
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeMessage : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -39,7 +38,7 @@ public:
|
|||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimeMessage(bool createAutoMimeContent = true);
|
MimeMessage(bool createAutoMimeConent = true);
|
||||||
~MimeMessage();
|
~MimeMessage();
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
@ -47,22 +46,24 @@ public:
|
|||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
void setSender(const EmailAddress &sndr);
|
void setSender(EmailAddress* e);
|
||||||
void addRecipient(const EmailAddress &rcpt, RecipientType type = To);
|
void addRecipient(EmailAddress* rcpt, RecipientType type = To);
|
||||||
void addTo(const EmailAddress &rcpt);
|
void addTo(EmailAddress* rcpt);
|
||||||
void addCc(const EmailAddress &rcpt);
|
void addCc(EmailAddress* rcpt);
|
||||||
void addBcc(const EmailAddress &rcpt);
|
void addBcc(EmailAddress* rcpt);
|
||||||
void addCustomHeader(const QString &hdr);
|
void setSubject(const QString & subject);
|
||||||
void setSubject(const QString &subject);
|
|
||||||
void addPart(MimePart* part);
|
void addPart(MimePart* part);
|
||||||
|
void setReplyTo(EmailAddress* rto);
|
||||||
|
|
||||||
|
void setInReplyTo(const QString& inReplyTo);
|
||||||
|
|
||||||
void setHeaderEncoding(MimePart::Encoding);
|
void setHeaderEncoding(MimePart::Encoding);
|
||||||
|
|
||||||
EmailAddress getSender() const;
|
const EmailAddress & getSender() const;
|
||||||
const QList<EmailAddress> &getRecipients(RecipientType type = To) const;
|
const QList<EmailAddress*> & getRecipients(RecipientType type = To) const;
|
||||||
QString getSubject() const;
|
const QString & getSubject() const;
|
||||||
const QStringList &getCustomHeaders() const;
|
|
||||||
const QList<MimePart*> & getParts() const;
|
const QList<MimePart*> & getParts() const;
|
||||||
|
const EmailAddress* getReplyTo() const;
|
||||||
|
|
||||||
MimePart& getContent();
|
MimePart& getContent();
|
||||||
void setContent(MimePart *content);
|
void setContent(MimePart *content);
|
||||||
@ -71,8 +72,7 @@ public:
|
|||||||
|
|
||||||
/* [3] Public methods */
|
/* [3] Public methods */
|
||||||
|
|
||||||
virtual QString toString() const;
|
virtual QString toString();
|
||||||
void writeToDevice(QIODevice &device) const;
|
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
@ -80,17 +80,16 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected members */
|
/* [4] Protected members */
|
||||||
|
|
||||||
EmailAddress sender;
|
EmailAddress* sender;
|
||||||
QList<EmailAddress> recipientsTo, recipientsCc, recipientsBcc;
|
EmailAddress* replyTo;
|
||||||
|
QList<EmailAddress*> recipientsTo, recipientsCc, recipientsBcc;
|
||||||
QString subject;
|
QString subject;
|
||||||
QStringList customHeaders;
|
QString mInReplyTo;
|
||||||
MimePart *content;
|
MimePart *content;
|
||||||
|
bool autoMimeContentCreated;
|
||||||
|
|
||||||
MimePart::Encoding hEncoding;
|
MimePart::Encoding hEncoding;
|
||||||
|
|
||||||
static QByteArray format(const QString &text, MimePart::Encoding encoding);
|
|
||||||
static QByteArray formatAddress(const EmailAddress &address, MimePart::Encoding encoding);
|
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mimemultipart.h"
|
#include "mimemultipart.h"
|
||||||
#include <QIODevice>
|
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
@ -43,9 +42,7 @@ MimeMultiPart::MimeMultiPart(MultiPartType type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MimeMultiPart::~MimeMultiPart() {
|
MimeMultiPart::~MimeMultiPart() {
|
||||||
foreach (MimePart *part, parts) {
|
|
||||||
delete part;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMultiPart::addPart(MimePart *part) {
|
void MimeMultiPart::addPart(MimePart *part) {
|
||||||
@ -56,21 +53,20 @@ const QList<MimePart*> & MimeMultiPart::getParts() const {
|
|||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMultiPart::writeContent(QIODevice &device) const {
|
void MimeMultiPart::prepare() {
|
||||||
QList<MimePart*>::const_iterator it;
|
QList<MimePart*>::iterator it;
|
||||||
|
|
||||||
for (it = parts.constBegin(); it != parts.constEnd(); it++) {
|
content = "";
|
||||||
device.write("--" );
|
for (it = parts.begin(); it != parts.end(); it++) {
|
||||||
device.write(cBoundary.toLatin1());
|
content += "--" + cBoundary + "\r\n";
|
||||||
device.write("\r\n");
|
(*it)->prepare();
|
||||||
(*it)->writeToDevice(device);
|
content += (*it)->toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
device.write("--");
|
content += "--" + cBoundary + "--\r\n";
|
||||||
device.write(cBoundary.toLatin1());
|
|
||||||
device.write("--\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
MimePart::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
void MimeMultiPart::setMimeType(const MultiPartType type) {
|
void MimeMultiPart::setMimeType(const MultiPartType type) {
|
||||||
this->type = type;
|
this->type = type;
|
||||||
|
@ -19,12 +19,13 @@
|
|||||||
#ifndef MIMEMULTIPART_H
|
#ifndef MIMEMULTIPART_H
|
||||||
#define MIMEMULTIPART_H
|
#define MIMEMULTIPART_H
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include "smtpmime_global.h"
|
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT MimeMultiPart : public MimePart
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeMultiPart : public MimePart
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [0] Enums */
|
/* [0] Enums */
|
||||||
@ -60,7 +61,7 @@ public:
|
|||||||
|
|
||||||
void addPart(MimePart *part);
|
void addPart(MimePart *part);
|
||||||
|
|
||||||
void writeContent(QIODevice &device) const;
|
virtual void prepare();
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
|
171
src/mimepart.cpp
171
src/mimepart.cpp
@ -16,13 +16,8 @@
|
|||||||
See the LICENSE file for more details.
|
See the LICENSE file for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QBuffer>
|
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
#include "quotedprintable.h"
|
#include "quotedprintable.h"
|
||||||
#include "mimebase64formatter.h"
|
|
||||||
#include "mimeqpformatter.h"
|
|
||||||
#include "mimebase64encoder.h"
|
|
||||||
#include "mimeqpencoder.h"
|
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
@ -50,20 +45,20 @@ void MimePart::setContent(const QByteArray & content)
|
|||||||
|
|
||||||
void MimePart::setHeader(const QString & header)
|
void MimePart::setHeader(const QString & header)
|
||||||
{
|
{
|
||||||
this->headerLines = header;
|
this->header = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimePart::addHeaderLine(const QString & line)
|
void MimePart::addHeaderLine(const QString & line)
|
||||||
{
|
{
|
||||||
this->headerLines += line + "\r\n";
|
this->header += line + "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MimePart::getHeader() const
|
const QString& MimePart::getHeader() const
|
||||||
{
|
{
|
||||||
return headerLines;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray MimePart::getContent() const
|
const QByteArray& MimePart::getContent() const
|
||||||
{
|
{
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -73,7 +68,7 @@ void MimePart::setContentId(const QString & cId)
|
|||||||
this->cId = cId;
|
this->cId = cId;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MimePart::getContentId() const
|
const QString & MimePart::getContentId() const
|
||||||
{
|
{
|
||||||
return this->cId;
|
return this->cId;
|
||||||
}
|
}
|
||||||
@ -83,7 +78,7 @@ void MimePart::setContentName(const QString & cName)
|
|||||||
this->cName = cName;
|
this->cName = cName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MimePart::getContentName() const
|
const QString & MimePart::getContentName() const
|
||||||
{
|
{
|
||||||
return this->cName;
|
return this->cName;
|
||||||
}
|
}
|
||||||
@ -93,7 +88,7 @@ void MimePart::setContentType(const QString & cType)
|
|||||||
this->cType = cType;
|
this->cType = cType;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MimePart::getContentType() const
|
const QString & MimePart::getContentType() const
|
||||||
{
|
{
|
||||||
return this->cType;
|
return this->cType;
|
||||||
}
|
}
|
||||||
@ -103,7 +98,7 @@ void MimePart::setCharset(const QString & charset)
|
|||||||
this->cCharset = charset;
|
this->cCharset = charset;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MimePart::getCharset() const
|
const QString & MimePart::getCharset() const
|
||||||
{
|
{
|
||||||
return this->cCharset;
|
return this->cCharset;
|
||||||
}
|
}
|
||||||
@ -118,12 +113,9 @@ MimePart::Encoding MimePart::getEncoding() const
|
|||||||
return this->cEncoding;
|
return this->cEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimePart::setMaxLineLength(const int length) {
|
MimeContentFormatter& MimePart::getContentFormatter()
|
||||||
maxLineLength = length;
|
{
|
||||||
}
|
return this->formatter;
|
||||||
|
|
||||||
int MimePart::getMaxLineLength() const {
|
|
||||||
return maxLineLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
@ -131,97 +123,92 @@ int MimePart::getMaxLineLength() const {
|
|||||||
|
|
||||||
/* [3] Public methods */
|
/* [3] Public methods */
|
||||||
|
|
||||||
QString MimePart::toString() const
|
QString MimePart::toString()
|
||||||
{
|
{
|
||||||
QBuffer out;
|
if (!prepared)
|
||||||
out.open(QIODevice::WriteOnly);
|
prepare();
|
||||||
writeToDevice(out);
|
|
||||||
return QString(out.buffer());
|
return mimeString;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimePart::writeToDevice(QIODevice &device) const {
|
|
||||||
QString header;
|
|
||||||
|
|
||||||
/* === Header Prepare === */
|
|
||||||
|
|
||||||
/* Content-Type */
|
|
||||||
header.append("Content-Type: ").append(cType);
|
|
||||||
|
|
||||||
if (cName != "")
|
|
||||||
header.append("; name=\"").append(cName).append("\"");
|
|
||||||
|
|
||||||
if (cCharset != "")
|
|
||||||
header.append("; charset=").append(cCharset);
|
|
||||||
|
|
||||||
if (cBoundary != "")
|
|
||||||
header.append("; boundary=").append(cBoundary);
|
|
||||||
|
|
||||||
header.append("\r\n");
|
|
||||||
/* ------------ */
|
|
||||||
|
|
||||||
/* Content-Transfer-Encoding */
|
|
||||||
header.append("Content-Transfer-Encoding: ");
|
|
||||||
switch (cEncoding)
|
|
||||||
{
|
|
||||||
case _7Bit:
|
|
||||||
header.append("7bit\r\n");
|
|
||||||
break;
|
|
||||||
case _8Bit:
|
|
||||||
header.append("8bit\r\n");
|
|
||||||
break;
|
|
||||||
case Base64:
|
|
||||||
header.append("base64\r\n");
|
|
||||||
break;
|
|
||||||
case QuotedPrintable:
|
|
||||||
header.append("quoted-printable\r\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* ------------------------ */
|
|
||||||
|
|
||||||
/* Content-Id */
|
|
||||||
if (cId != NULL)
|
|
||||||
header.append("Content-ID: <").append(cId).append(">\r\n");
|
|
||||||
/* ---------- */
|
|
||||||
|
|
||||||
/* Additional header lines */
|
|
||||||
|
|
||||||
header.append(headerLines).append("\r\n");
|
|
||||||
|
|
||||||
/* ------------------------- */
|
|
||||||
|
|
||||||
/* === End of Header Prepare === */
|
|
||||||
|
|
||||||
device.write(header.toLatin1());
|
|
||||||
|
|
||||||
writeContent(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
void MimePart::writeContent(QIODevice &device) const {
|
void MimePart::prepare()
|
||||||
this->writeContent(device, content);
|
{
|
||||||
}
|
mimeString = QString();
|
||||||
|
|
||||||
void MimePart::writeContent(QIODevice &device, const QByteArray &content) const {
|
/* === 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)
|
switch (cEncoding)
|
||||||
{
|
{
|
||||||
case _7Bit:
|
case _7Bit:
|
||||||
|
mimeString.append("7bit\r\n");
|
||||||
|
break;
|
||||||
case _8Bit:
|
case _8Bit:
|
||||||
device.write(content);
|
mimeString.append("8bit\r\n");
|
||||||
break;
|
break;
|
||||||
case Base64:
|
case Base64:
|
||||||
MimeBase64Formatter(&device).write(MimeBase64Encoder().encode(content));
|
mimeString.append("base64\r\n");
|
||||||
break;
|
break;
|
||||||
case QuotedPrintable:
|
case QuotedPrintable:
|
||||||
MimeQPFormatter(&device).write(MimeQpEncoder().encode(content));
|
mimeString.append("quoted-printable\r\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
device.write("\r\n");
|
/* ------------------------ */
|
||||||
|
|
||||||
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
@ -19,14 +19,14 @@
|
|||||||
#ifndef MIMEPART_H
|
#ifndef MIMEPART_H
|
||||||
#define MIMEPART_H
|
#define MIMEPART_H
|
||||||
|
|
||||||
#include "smtpmime_global.h"
|
#include <QObject>
|
||||||
#include <QByteArray>
|
#include "mimecontentformatter.h"
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
class QIODevice;
|
#include "smtpexports.h"
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT MimePart
|
class SMTP_EXPORT MimePart : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [0] Enumerations */
|
/* [0] Enumerations */
|
||||||
@ -44,54 +44,56 @@ public:
|
|||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
MimePart();
|
MimePart();
|
||||||
virtual ~MimePart();
|
~MimePart();
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
void setContent(const QByteArray & content);
|
const QString& getHeader() const;
|
||||||
QByteArray getContent() const;
|
const QByteArray& getContent() const;
|
||||||
|
|
||||||
void setHeader(const QString & headerLines);
|
void setContent(const QByteArray & content);
|
||||||
QString getHeader() const;
|
void setHeader(const QString & header);
|
||||||
|
|
||||||
void addHeaderLine(const QString & line);
|
void addHeaderLine(const QString & line);
|
||||||
|
|
||||||
void setContentId(const QString & cId);
|
void setContentId(const QString & cId);
|
||||||
QString getContentId() const;
|
const QString & getContentId() const;
|
||||||
|
|
||||||
void setContentName(const QString & cName);
|
void setContentName(const QString & cName);
|
||||||
QString getContentName() const;
|
const QString & getContentName() const;
|
||||||
|
|
||||||
void setContentType(const QString & cType);
|
void setContentType(const QString & cType);
|
||||||
QString getContentType() const;
|
const QString & getContentType() const;
|
||||||
|
|
||||||
void setCharset(const QString & charset);
|
void setCharset(const QString & charset);
|
||||||
QString getCharset() const;
|
const QString & getCharset() const;
|
||||||
|
|
||||||
void setEncoding(Encoding enc);
|
void setEncoding(Encoding enc);
|
||||||
Encoding getEncoding() const;
|
Encoding getEncoding() const;
|
||||||
|
|
||||||
void setMaxLineLength(const int length);
|
MimeContentFormatter& getContentFormatter();
|
||||||
int getMaxLineLength() const;
|
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [3] Public methods */
|
/* [3] Public methods */
|
||||||
|
|
||||||
virtual QString toString() const;
|
virtual QString toString();
|
||||||
void writeToDevice(QIODevice &device) const;
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* [4] Protected members */
|
/* [4] Protected members */
|
||||||
|
|
||||||
QString headerLines;
|
QString header;
|
||||||
QByteArray content;
|
QByteArray content;
|
||||||
|
|
||||||
QString cId;
|
QString cId;
|
||||||
@ -101,15 +103,12 @@ protected:
|
|||||||
QString cBoundary;
|
QString cBoundary;
|
||||||
Encoding cEncoding;
|
Encoding cEncoding;
|
||||||
|
|
||||||
int maxLineLength;
|
|
||||||
|
|
||||||
QString mimeString;
|
QString mimeString;
|
||||||
bool prepared;
|
bool prepared;
|
||||||
|
|
||||||
/* [4] --- */
|
MimeContentFormatter formatter;
|
||||||
|
|
||||||
virtual void writeContent(QIODevice &device) const;
|
/* [4] --- */
|
||||||
void writeContent(QIODevice &device, const QByteArray &content) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MIMEPART_H
|
#endif // MIMEPART_H
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
#include "mimeqpencoder.h"
|
|
||||||
#include "quotedprintable.h"
|
|
||||||
|
|
||||||
MimeQpEncoder::MimeQpEncoder() {}
|
|
||||||
|
|
||||||
QByteArray MimeQpEncoder::encode(const QByteArray &data) {
|
|
||||||
return QuotedPrintable::encode(data).toLatin1();
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
#ifndef MIMEQPENCODER_H
|
|
||||||
#define MIMEQPENCODER_H
|
|
||||||
|
|
||||||
#include "mimecontentencoder.h"
|
|
||||||
|
|
||||||
class MimeQpEncoder : public MimeContentEncoder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MimeQpEncoder();
|
|
||||||
|
|
||||||
QByteArray encode(const QByteArray &data);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MIMEQPENCODER_H
|
|
@ -1,29 +0,0 @@
|
|||||||
#include "mimeqpformatter.h"
|
|
||||||
|
|
||||||
MimeQPFormatter::MimeQPFormatter(QIODevice *output) :
|
|
||||||
MimeContentFormatter(output) {}
|
|
||||||
|
|
||||||
qint64 MimeQPFormatter::writeData(const char *data, qint64 maxLength) {
|
|
||||||
int chars = 0;
|
|
||||||
const char *start = data;
|
|
||||||
for (int i = 0; i < maxLength; ++i) {
|
|
||||||
chars++;
|
|
||||||
if (data[i] == '\n') {
|
|
||||||
output->write(start, chars);
|
|
||||||
start += chars;
|
|
||||||
chars = 0;
|
|
||||||
} else if ((chars > lineLength - 3) && (data[i] == '=')) {
|
|
||||||
output->write(start, chars - 1);
|
|
||||||
output->write("=\r\n=");
|
|
||||||
start += chars;
|
|
||||||
chars = 0;
|
|
||||||
} else if (chars == lineLength - 1) {
|
|
||||||
output->write(start, chars);
|
|
||||||
output->write("=\r\n");
|
|
||||||
start += chars;
|
|
||||||
chars = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output->write(start, chars);
|
|
||||||
return maxLength;
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
#ifndef MIMEQPFORMATTER_H
|
|
||||||
#define MIMEQPFORMATTER_H
|
|
||||||
|
|
||||||
#include "mimecontentformatter.h"
|
|
||||||
|
|
||||||
class MimeQPFormatter : public MimeContentFormatter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MimeQPFormatter(QIODevice*);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual qint64 writeData(const char *data, qint64 len);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MIMEQPFORMATTER_H
|
|
@ -50,8 +50,13 @@ const QString & MimeText::getText() const
|
|||||||
|
|
||||||
/* [3] Protected Methods */
|
/* [3] Protected Methods */
|
||||||
|
|
||||||
void MimeText::writeContent(QIODevice &device) const {
|
void MimeText::prepare()
|
||||||
MimePart::writeContent(device, text.toLocal8Bit());
|
{
|
||||||
|
this->content.clear();
|
||||||
|
this->content.append(text);
|
||||||
|
|
||||||
|
/* !!! IMPORTANT !!! */
|
||||||
|
MimePart::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -19,10 +19,11 @@
|
|||||||
#ifndef MIMETEXT_H
|
#ifndef MIMETEXT_H
|
||||||
#define MIMETEXT_H
|
#define MIMETEXT_H
|
||||||
|
|
||||||
#include "smtpmime_global.h"
|
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
|
|
||||||
class SMTP_MIME_EXPORT MimeText : public MimePart
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeText : public MimePart
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
void writeContent(QIODevice &device) const;
|
void prepare();
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
@ -20,19 +20,24 @@
|
|||||||
|
|
||||||
QString QuotedPrintable::encode(const QByteArray &input)
|
QString QuotedPrintable::encode(const QByteArray &input)
|
||||||
{
|
{
|
||||||
static const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
|
||||||
|
|
||||||
QString output;
|
QString output;
|
||||||
|
|
||||||
|
char byte;
|
||||||
|
const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
|
||||||
for (int i = 0; i < input.length() ; ++i)
|
for (int i = 0; i < input.length() ; ++i)
|
||||||
{
|
{
|
||||||
const char byte = input[i];
|
byte = input[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('=').append(hex[((byte >> 4) & 0x0F)]).append(hex[(byte & 0x0F)]);
|
{
|
||||||
|
output.append('=');
|
||||||
|
output.append(hex[((byte >> 4) & 0x0F)]);
|
||||||
|
output.append(hex[(byte & 0x0F)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,26 +47,16 @@ QString QuotedPrintable::encode(const QByteArray &input)
|
|||||||
|
|
||||||
QByteArray QuotedPrintable::decode(const QString &input)
|
QByteArray QuotedPrintable::decode(const QString &input)
|
||||||
{
|
{
|
||||||
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F
|
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F
|
||||||
static 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};
|
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};
|
||||||
|
|
||||||
QByteArray output;
|
QByteArray output;
|
||||||
|
|
||||||
int len = input.length();
|
for (int i = 0; i < input.length(); ++i)
|
||||||
int i;
|
|
||||||
for (i = 0; i < len-2; ++i)
|
|
||||||
{
|
{
|
||||||
if (input.at(i).toLatin1() == '=')
|
if (input.at(i).toLatin1() == '=')
|
||||||
{
|
{
|
||||||
int x = input.at(i+1).toLatin1() - '0';
|
output.append((hexVal[input.at(i + 1).toLatin1() - '0'] << 4) + hexVal[input.at(i + 2).toLatin1() - '0']);
|
||||||
int y = input.at(i+2).toLatin1() - '0';
|
|
||||||
if (x >= 0 && y >= 0 && x < 23 && y < 23) {
|
|
||||||
output.append(char((hexVal[x] << 4) + hexVal[y]));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
output.append('=').append(char(x + '0')).append(char(y + '0'));
|
|
||||||
}
|
|
||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -70,10 +65,5 @@ QByteArray QuotedPrintable::decode(const QString &input)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i<len) {
|
|
||||||
output.append(input.at(i).toLatin1());
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -19,13 +19,21 @@
|
|||||||
#ifndef QUOTEDPRINTABLE_H
|
#ifndef QUOTEDPRINTABLE_H
|
||||||
#define QUOTEDPRINTABLE_H
|
#define QUOTEDPRINTABLE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QString>
|
|
||||||
#include "smtpmime_global.h"
|
|
||||||
|
|
||||||
namespace QuotedPrintable {
|
#include "smtpexports.h"
|
||||||
SMTP_MIME_EXPORT QString encode(const QByteArray &input);
|
|
||||||
SMTP_MIME_EXPORT QByteArray decode(const QString &input);
|
class SMTP_EXPORT QuotedPrintable : public QObject
|
||||||
}
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
static QString encode(const QByteArray &input);
|
||||||
|
static QByteArray decode(const QString &input);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QuotedPrintable();
|
||||||
|
};
|
||||||
|
|
||||||
#endif // QUOTEDPRINTABLE_H
|
#endif // QUOTEDPRINTABLE_H
|
||||||
|
@ -20,24 +20,23 @@
|
|||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QTimer>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QMetaEnum>
|
|
||||||
|
|
||||||
/* [1] Constructors and destructors */
|
/* [1] Constructors and destructors */
|
||||||
|
|
||||||
SmtpClient::SmtpClient(const QString & host, int port, ConnectionType connectionType) :
|
SmtpClient::SmtpClient(const QString & host, int port, ConnectionType connectionType) :
|
||||||
state(UnconnectedState),
|
socket(NULL),
|
||||||
host(host),
|
|
||||||
port(port),
|
|
||||||
name("localhost"),
|
name("localhost"),
|
||||||
isReadyConnected(false),
|
authMethod(AuthPlain),
|
||||||
isAuthenticated(false),
|
connectionTimeout(5000),
|
||||||
isMailSent(false),
|
responseTimeout(5000),
|
||||||
isReset(false)
|
sendMessageTimeout(60000)
|
||||||
{
|
{
|
||||||
setConnectionType(connectionType);
|
setConnectionType(connectionType);
|
||||||
|
|
||||||
|
this->host = host;
|
||||||
|
this->port = port;
|
||||||
|
|
||||||
connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
||||||
this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));
|
this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));
|
||||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
|
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||||
@ -46,189 +45,48 @@ SmtpClient::SmtpClient(const QString & host, int port, ConnectionType connection
|
|||||||
this, SLOT(socketReadyRead()));
|
this, SLOT(socketReadyRead()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SmtpClient::~SmtpClient() {}
|
SmtpClient::~SmtpClient() {
|
||||||
|
if (socket)
|
||||||
|
delete socket;
|
||||||
|
}
|
||||||
|
|
||||||
/* [1] --- */
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
/**
|
|
||||||
* @brief Returns the host name of the server.
|
void SmtpClient::setUser(const QString &user)
|
||||||
*/
|
|
||||||
QString SmtpClient::getHost() const
|
|
||||||
{
|
{
|
||||||
return this->host;
|
this->user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void SmtpClient::setPassword(const QString &password)
|
||||||
* @brief Return the port.
|
|
||||||
*/
|
|
||||||
int SmtpClient::getPort() const
|
|
||||||
{
|
{
|
||||||
return this->port;
|
this->password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void SmtpClient::setAuthMethod(AuthMethod method)
|
||||||
* @brief Returns the connection type used.
|
|
||||||
*/
|
|
||||||
SmtpClient::ConnectionType SmtpClient::getConnectionType() const
|
|
||||||
{
|
{
|
||||||
return connectionType;
|
this->authMethod = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void SmtpClient::setHost(const QString &host)
|
||||||
* @brief Returns the client's name.
|
|
||||||
*/
|
|
||||||
QString SmtpClient::getName() const
|
|
||||||
{
|
{
|
||||||
return this->name;
|
this->host = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void SmtpClient::setPort(int port)
|
||||||
* @brief Sets the client's name. This name is sent by the EHLO command.
|
|
||||||
*/
|
|
||||||
void SmtpClient::setName(const QString &name)
|
|
||||||
{
|
{
|
||||||
this->name = name;
|
this->port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the last response of the server.
|
|
||||||
*/
|
|
||||||
QString SmtpClient::getResponseText() const
|
|
||||||
{
|
|
||||||
return responseText;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the last response code recived by the client.
|
|
||||||
*/
|
|
||||||
int SmtpClient::getResponseCode() const
|
|
||||||
{
|
|
||||||
return responseCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the socket used by the client. The type of the of the
|
|
||||||
* connection is QTcpConnection in case of TcpConnection, and QSslSocket
|
|
||||||
* for SslConnection and TlsConnection.
|
|
||||||
*/
|
|
||||||
QTcpSocket* SmtpClient::getSocket() {
|
|
||||||
return socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [2] --- */
|
|
||||||
|
|
||||||
|
|
||||||
/* [3] Public methods */
|
|
||||||
|
|
||||||
void SmtpClient::connectToHost()
|
|
||||||
{
|
|
||||||
if (state != UnconnectedState)
|
|
||||||
return;
|
|
||||||
|
|
||||||
changeState(ConnectingState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmtpClient::login()
|
|
||||||
{
|
|
||||||
if (!isReadyConnected || isAuthenticated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
changeState(AuthenticatingState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmtpClient::login(const QString &user, const QString &password, AuthMethod method)
|
|
||||||
{
|
|
||||||
this->authInfo = AuthInfo(user, password, method);
|
|
||||||
login();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmtpClient::sendMail(const MimeMessage & email)
|
|
||||||
{
|
|
||||||
if (!isReadyConnected)
|
|
||||||
return;
|
|
||||||
|
|
||||||
isMailSent = false;
|
|
||||||
|
|
||||||
this->email = &email;
|
|
||||||
this->rcptType = 0;
|
|
||||||
changeState(MailSendingState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmtpClient::quit()
|
|
||||||
{
|
|
||||||
changeState(DisconnectingState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmtpClient::reset()
|
|
||||||
{
|
|
||||||
if (!isReadyConnected)
|
|
||||||
return;
|
|
||||||
|
|
||||||
isReset = false;
|
|
||||||
|
|
||||||
changeState(ResetState);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SmtpClient::waitForReadyConnected(int msec) {
|
|
||||||
if (state == UnconnectedState)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (isReadyConnected)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
waitForEvent(msec, SIGNAL(readyConnected()));
|
|
||||||
|
|
||||||
return isReadyConnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SmtpClient::waitForAuthenticated(int msec) {
|
|
||||||
if (!isReadyConnected)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (isAuthenticated)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
waitForEvent(msec, SIGNAL(authenticated()));
|
|
||||||
|
|
||||||
return isAuthenticated;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SmtpClient::waitForMailSent(int msec) {
|
|
||||||
if (!isReadyConnected)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (isMailSent)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
waitForEvent(msec, SIGNAL(mailSent()));
|
|
||||||
|
|
||||||
return isMailSent;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SmtpClient::waitForReset(int msec)
|
|
||||||
{
|
|
||||||
if (!isReadyConnected)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (isReset)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
waitForEvent(msec, SIGNAL(mailReset()));
|
|
||||||
|
|
||||||
return isReset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [3] --- */
|
|
||||||
|
|
||||||
|
|
||||||
/* [4] Protected methods */
|
|
||||||
|
|
||||||
void SmtpClient::setConnectionType(ConnectionType ct)
|
void SmtpClient::setConnectionType(ConnectionType ct)
|
||||||
{
|
{
|
||||||
this->connectionType = ct;
|
this->connectionType = ct;
|
||||||
|
|
||||||
|
if (socket)
|
||||||
|
delete socket;
|
||||||
|
|
||||||
switch (connectionType)
|
switch (connectionType)
|
||||||
{
|
{
|
||||||
case TcpConnection:
|
case TcpConnection:
|
||||||
@ -237,338 +95,384 @@ void SmtpClient::setConnectionType(ConnectionType ct)
|
|||||||
case SslConnection:
|
case SslConnection:
|
||||||
case TlsConnection:
|
case TlsConnection:
|
||||||
socket = new QSslSocket(this);
|
socket = new QSslSocket(this);
|
||||||
connect(socket, SIGNAL(encrypted()),
|
|
||||||
this, SLOT(socketEncrypted()));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmtpClient::changeState(SmtpClient::ClientState state) {
|
const QString& SmtpClient::getHost() const
|
||||||
this->state = state;
|
{
|
||||||
|
return this->host;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef QT_NO_DEBUG
|
const QString& SmtpClient::getUser() const
|
||||||
// Emit stateChanged signal only for non-internal states
|
{
|
||||||
if (state <= DisconnectingState) {
|
return this->user;
|
||||||
emit stateChanged(state);
|
}
|
||||||
}
|
|
||||||
#else
|
|
||||||
// emit all in debug mode
|
|
||||||
qDebug() << "[SmtpClient] State:" << staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("ClientState")).valueToKey(state);
|
|
||||||
emit stateChanged(state);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (state)
|
const QString& SmtpClient::getPassword() const
|
||||||
|
{
|
||||||
|
return this->password;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmtpClient::AuthMethod SmtpClient::getAuthMethod() const
|
||||||
|
{
|
||||||
|
return this->authMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmtpClient::getPort() const
|
||||||
|
{
|
||||||
|
return this->port;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmtpClient::ConnectionType SmtpClient::getConnectionType() const
|
||||||
|
{
|
||||||
|
return connectionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& SmtpClient::getName() const
|
||||||
|
{
|
||||||
|
return this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setName(const QString &name)
|
||||||
|
{
|
||||||
|
this->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & SmtpClient::getResponseText() const
|
||||||
|
{
|
||||||
|
return responseText;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmtpClient::getResponseCode() const
|
||||||
|
{
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTcpSocket* SmtpClient::getSocket() {
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmtpClient::getConnectionTimeout() const
|
||||||
|
{
|
||||||
|
return connectionTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setConnectionTimeout(int msec)
|
||||||
|
{
|
||||||
|
connectionTimeout = msec;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmtpClient::getResponseTimeout() const
|
||||||
|
{
|
||||||
|
return responseTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setResponseTimeout(int msec)
|
||||||
|
{
|
||||||
|
responseTimeout = msec;
|
||||||
|
}
|
||||||
|
int SmtpClient::getSendMessageTimeout() const
|
||||||
|
{
|
||||||
|
return sendMessageTimeout;
|
||||||
|
}
|
||||||
|
void SmtpClient::setSendMessageTimeout(int msec)
|
||||||
|
{
|
||||||
|
sendMessageTimeout = msec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Public methods */
|
||||||
|
|
||||||
|
bool SmtpClient::connectToHost()
|
||||||
|
{
|
||||||
|
switch (connectionType)
|
||||||
{
|
{
|
||||||
case ConnectingState:
|
case TlsConnection:
|
||||||
switch (connectionType)
|
case TcpConnection:
|
||||||
|
socket->connectToHost(host, port);
|
||||||
|
break;
|
||||||
|
case SslConnection:
|
||||||
|
((QSslSocket*) socket)->connectToHostEncrypted(host, port);
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
case TlsConnection:
|
emit smtpError(ServerError);
|
||||||
case TcpConnection:
|
return false;
|
||||||
socket->connectToHost(host, port);
|
|
||||||
break;
|
|
||||||
case SslConnection:
|
|
||||||
((QSslSocket*) socket)->connectToHostEncrypted(host, port);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case AuthenticatingState:
|
// Send a EHLO/HELO message to the server
|
||||||
isAuthenticated = false;
|
// The client's first command must be EHLO/HELO
|
||||||
changeState(authInfo.authMethod == AuthPlain ? _AUTH_PLAIN_0 : _AUTH_LOGIN_0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MailSendingState:
|
|
||||||
isMailSent = false;
|
|
||||||
changeState(_MAIL_0_FROM);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DisconnectingState:
|
|
||||||
sendMessage("QUIT");
|
|
||||||
socket->disconnectFromHost();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ResetState:
|
|
||||||
sendMessage("RSET");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _EHLO_State:
|
|
||||||
// Service ready. Send EHLO message and change the state
|
|
||||||
sendMessage("EHLO " + name);
|
sendMessage("EHLO " + name);
|
||||||
break;
|
|
||||||
|
|
||||||
case _READY_Connected:
|
// Wait for the server's response
|
||||||
isReadyConnected = true;
|
waitForResponse();
|
||||||
changeState(ReadyState);
|
|
||||||
emit readyConnected();
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* --- TLS --- */
|
// The response code needs to be 250.
|
||||||
case _TLS_State:
|
if (responseCode != 250) {
|
||||||
changeState(_TLS_0_STARTTLS);
|
emit smtpError(ServerError);
|
||||||
break;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
case _TLS_0_STARTTLS:
|
if (connectionType == TlsConnection) {
|
||||||
// send a request to start TLS handshake
|
// send a request to start TLS handshake
|
||||||
sendMessage("STARTTLS");
|
sendMessage("STARTTLS");
|
||||||
break;
|
|
||||||
|
|
||||||
case _TLS_1_ENCRYPT:
|
// Wait for the server's response
|
||||||
((QSslSocket*) socket)->startClientEncryption();
|
waitForResponse();
|
||||||
break;
|
|
||||||
|
|
||||||
case _TLS_2_EHLO:
|
// The response code needs to be 220.
|
||||||
// Send EHLO one more time
|
if (responseCode != 220) {
|
||||||
sendMessage("EHLO " + name);
|
emit smtpError(ServerError);
|
||||||
break;
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
case _READY_Encrypted:
|
((QSslSocket*) socket)->startClientEncryption();
|
||||||
changeState(_READY_Connected);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* --- AUTH --- */
|
if (!((QSslSocket*) socket)->waitForEncrypted(connectionTimeout)) {
|
||||||
case _AUTH_PLAIN_0:
|
qDebug() << ((QSslSocket*) socket)->errorString();
|
||||||
// Sending command: AUTH PLAIN base64('\0' + username + '\0' + password)
|
emit smtpError(ConnectionTimeoutError);
|
||||||
sendMessage("AUTH PLAIN " + QByteArray().append((char) 0).append(authInfo.username)
|
return false;
|
||||||
.append((char) 0).append(authInfo.password).toBase64());
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case _AUTH_LOGIN_0:
|
// Send ELHO one more time
|
||||||
sendMessage("AUTH LOGIN");
|
sendMessage("EHLO " + name);
|
||||||
break;
|
|
||||||
|
|
||||||
case _AUTH_LOGIN_1_USER:
|
// Wait for the server's response
|
||||||
// Send the username in base64
|
waitForResponse();
|
||||||
sendMessage(QByteArray().append(authInfo.username).toBase64());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _AUTH_LOGIN_2_PASS:
|
// The response code needs to be 250.
|
||||||
// Send the password in base64
|
if (responseCode != 250) {
|
||||||
sendMessage(QByteArray().append(authInfo.password).toBase64());
|
emit smtpError(ServerError);
|
||||||
break;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ResponseTimeoutException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (SendMessageTimeoutException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
case _READY_Authenticated:
|
// If no errors occured the function returns true.
|
||||||
isAuthenticated = true;
|
return true;
|
||||||
authInfo = AuthInfo();
|
}
|
||||||
changeState(ReadyState);
|
|
||||||
emit authenticated();
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* --- MAIL --- */
|
bool SmtpClient::login()
|
||||||
case _MAIL_0_FROM:
|
{
|
||||||
sendMessage("MAIL FROM:<" + email->getSender().getAddress() + ">");
|
return login(user, password, authMethod);
|
||||||
break;
|
}
|
||||||
|
|
||||||
case _MAIL_1_RCPT_INIT:
|
bool SmtpClient::login(const QString &user, const QString &password, AuthMethod method)
|
||||||
rcptType++;
|
{
|
||||||
const QList<EmailAddress> *addressList;
|
try {
|
||||||
switch (rcptType)
|
if (method == AuthPlain)
|
||||||
{
|
{
|
||||||
case _TO:
|
// Sending command: AUTH PLAIN base64('\0' + username + '\0' + password)
|
||||||
addressList = &email->getRecipients(MimeMessage::To);
|
sendMessage("AUTH PLAIN " + QByteArray().append((char) 0).append(user).append((char) 0).append(password).toBase64());
|
||||||
break;
|
|
||||||
case _CC:
|
|
||||||
addressList = &email->getRecipients(MimeMessage::Cc);
|
|
||||||
break;
|
|
||||||
case _BCC:
|
|
||||||
addressList = &email->getRecipients(MimeMessage::Bcc);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
changeState(_MAIL_3_DATA);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
addressIt = addressList->constBegin();
|
|
||||||
addressItEnd = addressList->constEnd();
|
|
||||||
changeState(_MAIL_2_RCPT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _MAIL_2_RCPT:
|
// Wait for the server's response
|
||||||
if (addressIt != addressItEnd) {
|
waitForResponse();
|
||||||
sendMessage("RCPT TO:<" + addressIt->getAddress() + ">");
|
|
||||||
addressIt++;
|
|
||||||
} else {
|
|
||||||
changeState(_MAIL_1_RCPT_INIT);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _MAIL_3_DATA:
|
// If the response is not 235 then the authentication was faild
|
||||||
|
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).toBase64());
|
||||||
|
|
||||||
|
// Wait for 334
|
||||||
|
waitForResponse();
|
||||||
|
if (responseCode != 334) { emit smtpError(AuthenticationFailedError); return false; }
|
||||||
|
|
||||||
|
// Send the password in base64
|
||||||
|
sendMessage(QByteArray().append(password).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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SmtpClient::sendMail(MimeMessage& email)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Send the MAIL command with the sender
|
||||||
|
sendMessage("MAIL FROM:<" + email.getSender().getAddress() + ">");
|
||||||
|
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 250) return false;
|
||||||
|
|
||||||
|
// Send RCPT command for each recipient
|
||||||
|
QList<EmailAddress*>::const_iterator it, itEnd;
|
||||||
|
// To (primary recipients)
|
||||||
|
for (it = email.getRecipients().begin(), itEnd = email.getRecipients().end();
|
||||||
|
it != itEnd; ++it)
|
||||||
|
{
|
||||||
|
|
||||||
|
sendMessage("RCPT TO:<" + (*it)->getAddress() + ">");
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
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");
|
sendMessage("DATA");
|
||||||
break;
|
waitForResponse();
|
||||||
|
|
||||||
case _MAIL_4_SEND_DATA:
|
if (responseCode != 354) return false;
|
||||||
email->writeToDevice(*socket);
|
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
sendMessage(email.toString());
|
||||||
qDebug() << "[Socket] OUT:";
|
|
||||||
qDebug() << email->toString();
|
|
||||||
#endif
|
|
||||||
sendMessage("\r\n.");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _READY_MailSent:
|
// Send \r\n.\r\n to end the mail data
|
||||||
isMailSent = true;
|
sendMessage(".");
|
||||||
changeState(ReadyState);
|
|
||||||
emit mailSent();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
waitForResponse();
|
||||||
;
|
|
||||||
|
if (responseCode != 250) return false;
|
||||||
|
}
|
||||||
|
catch (ResponseTimeoutException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (SendMessageTimeoutException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::quit()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sendMessage("QUIT");
|
||||||
|
}
|
||||||
|
catch(SmtpClient::SendMessageTimeoutException)
|
||||||
|
{
|
||||||
|
//Manually close the connection to the smtp server if message "QUIT" wasn't received by the smtp server
|
||||||
|
if(socket->state() == QAbstractSocket::ConnectedState || socket->state() == QAbstractSocket::ConnectingState || socket->state() == QAbstractSocket::HostLookupState)
|
||||||
|
socket->disconnectFromHost();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmtpClient::processResponse() {
|
/* [3] --- */
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case ConnectedState:
|
|
||||||
// Just connected to the server. Wait for 220 (Service ready)
|
|
||||||
if (responseCode != 220) {
|
|
||||||
emitError(ServerError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_EHLO_State);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ResetState:
|
/* [4] Protected methods */
|
||||||
if (responseCode != 250) {
|
|
||||||
emitError(ServerError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emit mailReset();
|
|
||||||
changeState(ReadyState);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _EHLO_State:
|
void SmtpClient::waitForResponse()
|
||||||
// The response code needs to be 250.
|
{
|
||||||
if (responseCode != 250) {
|
do {
|
||||||
emitError(ServerError);
|
if (!socket->waitForReadyRead(responseTimeout))
|
||||||
return;
|
{
|
||||||
|
emit smtpError(ResponseTimeoutError);
|
||||||
|
throw ResponseTimeoutException();
|
||||||
}
|
}
|
||||||
|
|
||||||
changeState((connectionType != TlsConnection) ? _READY_Connected : _TLS_State);
|
while (socket->canReadLine()) {
|
||||||
break;
|
// Save the server's response
|
||||||
|
responseText = socket->readLine();
|
||||||
|
|
||||||
/* --- TLS --- */
|
// Extract the respose code from the server's responce (first 3 digits)
|
||||||
case _TLS_0_STARTTLS:
|
responseCode = responseText.left(3).toInt();
|
||||||
// The response code needs to be 220.
|
|
||||||
if (responseCode != 220) {
|
if (responseCode / 100 == 4)
|
||||||
emitError(ServerError);
|
emit smtpError(ServerError);
|
||||||
return;
|
|
||||||
|
if (responseCode / 100 == 5)
|
||||||
|
emit smtpError(ClientError);
|
||||||
|
|
||||||
|
if (responseText[3] == ' ') { return; }
|
||||||
}
|
}
|
||||||
changeState(_TLS_1_ENCRYPT);
|
} while (true);
|
||||||
break;
|
|
||||||
|
|
||||||
case _TLS_2_EHLO:
|
|
||||||
// The response code needs to be 250.
|
|
||||||
if (responseCode != 250) {
|
|
||||||
emitError(ServerError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_READY_Encrypted);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* --- AUTH --- */
|
|
||||||
case _AUTH_PLAIN_0:
|
|
||||||
// If the response is not 235 then the authentication was failed
|
|
||||||
if (responseCode != 235) {
|
|
||||||
emitError(AuthenticationError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_READY_Authenticated);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _AUTH_LOGIN_0:
|
|
||||||
if (responseCode != 334) {
|
|
||||||
emitError(AuthenticationError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_AUTH_LOGIN_1_USER);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _AUTH_LOGIN_1_USER:
|
|
||||||
if (responseCode != 334) {
|
|
||||||
emitError(AuthenticationError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_AUTH_LOGIN_2_PASS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _AUTH_LOGIN_2_PASS:
|
|
||||||
if (responseCode != 235) {
|
|
||||||
emitError(AuthenticationError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_READY_Authenticated);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* --- MAIL --- */
|
|
||||||
case _MAIL_0_FROM:
|
|
||||||
if (responseCode != 250) {
|
|
||||||
emitError(MailSendingError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_MAIL_1_RCPT_INIT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _MAIL_2_RCPT:
|
|
||||||
if (responseCode != 250) {
|
|
||||||
emitError(MailSendingError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_MAIL_2_RCPT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _MAIL_3_DATA:
|
|
||||||
if (responseCode != 354) {
|
|
||||||
emitError(MailSendingError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_MAIL_4_SEND_DATA);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _MAIL_4_SEND_DATA:
|
|
||||||
if (responseCode != 250) {
|
|
||||||
emitError(MailSendingError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
changeState(_READY_MailSent);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmtpClient::sendMessage(const QString &text)
|
void SmtpClient::sendMessage(const QString &text)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
|
||||||
qDebug() << "[Socket] OUT:" << text;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
socket->flush();
|
|
||||||
socket->write(text.toUtf8() + "\r\n");
|
socket->write(text.toUtf8() + "\r\n");
|
||||||
}
|
if (! socket->waitForBytesWritten(sendMessageTimeout))
|
||||||
|
|
||||||
void SmtpClient::emitError(SmtpClient::SmtpError e)
|
|
||||||
{
|
|
||||||
emit error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmtpClient::waitForEvent(int msec, const char *successSignal)
|
|
||||||
{
|
|
||||||
QEventLoop loop;
|
|
||||||
QObject::connect(this, successSignal, &loop, SLOT(quit()));
|
|
||||||
QObject::connect(this, SIGNAL(error(SmtpClient::SmtpError)), &loop, SLOT(quit()));
|
|
||||||
|
|
||||||
if(msec > 0)
|
|
||||||
{
|
{
|
||||||
QTimer timer;
|
emit smtpError(SendDataTimeoutError);
|
||||||
timer.setSingleShot(true);
|
throw SendMessageTimeoutException();
|
||||||
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
|
||||||
timer.start(msec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loop.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
@ -576,79 +480,16 @@ void SmtpClient::waitForEvent(int msec, const char *successSignal)
|
|||||||
|
|
||||||
/* [5] Slots for the socket's signals */
|
/* [5] Slots for the socket's signals */
|
||||||
|
|
||||||
void SmtpClient::socketStateChanged(QAbstractSocket::SocketState state) {
|
void SmtpClient::socketStateChanged(QAbstractSocket::SocketState /*state*/)
|
||||||
|
{
|
||||||
#ifndef QT_NO_DEBUG
|
|
||||||
qDebug() << "[Socket] State:" << state;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case QAbstractSocket::ConnectedState:
|
|
||||||
changeState(ConnectedState);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case QAbstractSocket::UnconnectedState:
|
|
||||||
changeState(UnconnectedState);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmtpClient::socketError(QAbstractSocket::SocketError socketError) {
|
void SmtpClient::socketError(QAbstractSocket::SocketError /*socketError*/)
|
||||||
#ifndef QT_NO_DEBUG
|
{
|
||||||
qDebug() << "[Socket] ERROR:" << socketError;
|
|
||||||
#else
|
|
||||||
Q_UNUSED(socketError);
|
|
||||||
#endif
|
|
||||||
emit error(SocketError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmtpClient::socketReadyRead()
|
void SmtpClient::socketReadyRead()
|
||||||
{
|
{
|
||||||
QString responseLine;
|
|
||||||
|
|
||||||
while (socket->canReadLine()) {
|
|
||||||
// Save the server's response
|
|
||||||
responseLine = socket->readLine();
|
|
||||||
tempResponse += responseLine;
|
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
|
||||||
qDebug() << "[Socket] IN: " << responseLine;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Is this the last line of the response
|
|
||||||
if (responseLine[3] == ' ') {
|
|
||||||
responseText = tempResponse;
|
|
||||||
tempResponse = "";
|
|
||||||
|
|
||||||
// Extract the respose code from the server's responce (first 3 digits)
|
|
||||||
responseCode = responseLine.left(3).toInt();
|
|
||||||
|
|
||||||
// Check for server error
|
|
||||||
if (responseCode / 100 == 4) {
|
|
||||||
emitError(ServerError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for client error
|
|
||||||
if (responseCode / 100 == 5) {
|
|
||||||
emitError(ClientError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
processResponse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmtpClient::socketEncrypted() {
|
|
||||||
if (state == _TLS_1_ENCRYPT) {
|
|
||||||
changeState(_TLS_2_EHLO);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [5] --- */
|
/* [5] --- */
|
||||||
|
176
src/smtpclient.h
176
src/smtpclient.h
@ -21,15 +21,13 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QtNetwork/QSslSocket>
|
#include <QtNetwork/QSslSocket>
|
||||||
#include <QEventLoop>
|
|
||||||
#include "smtpmime_global.h"
|
|
||||||
#include "mimemessage.h"
|
#include "mimemessage.h"
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT SmtpClient : public QObject
|
||||||
class SMTP_MIME_EXPORT SmtpClient : public QObject
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_ENUMS (AuthMethod SmtpError ConnectionType ClientState)
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* [0] Enumerations */
|
/* [0] Enumerations */
|
||||||
@ -42,60 +40,19 @@ public:
|
|||||||
|
|
||||||
enum SmtpError
|
enum SmtpError
|
||||||
{
|
{
|
||||||
ConnectionTimeoutError = 0,
|
ConnectionTimeoutError,
|
||||||
ResponseTimeoutError = 1,
|
ResponseTimeoutError,
|
||||||
AuthenticationError = 2,
|
SendDataTimeoutError,
|
||||||
MailSendingError = 3,
|
AuthenticationFailedError,
|
||||||
ServerError = 4, // 4xx smtp error
|
ServerError, // 4xx smtp error
|
||||||
ClientError = 5, // 5xx smtp error
|
ClientError // 5xx smtp error
|
||||||
SocketError = 6
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ConnectionType
|
enum ConnectionType
|
||||||
{
|
{
|
||||||
TcpConnection = 0,
|
TcpConnection,
|
||||||
SslConnection = 1,
|
SslConnection,
|
||||||
TlsConnection = 2 // STARTTLS
|
TlsConnection // STARTTLS
|
||||||
};
|
|
||||||
|
|
||||||
enum ClientState {
|
|
||||||
UnconnectedState = 0,
|
|
||||||
ConnectingState = 1,
|
|
||||||
ConnectedState = 2,
|
|
||||||
ReadyState = 3,
|
|
||||||
AuthenticatingState = 4,
|
|
||||||
MailSendingState = 5,
|
|
||||||
DisconnectingState = 6,
|
|
||||||
ResetState = 7,
|
|
||||||
|
|
||||||
/* Internal States */
|
|
||||||
_EHLO_State = 50,
|
|
||||||
_TLS_State = 51,
|
|
||||||
|
|
||||||
_READY_Connected = 52,
|
|
||||||
_READY_Authenticated = 53,
|
|
||||||
_READY_MailSent = 54,
|
|
||||||
_READY_Encrypted = 55,
|
|
||||||
|
|
||||||
/* Internal Substates */
|
|
||||||
|
|
||||||
// TLS
|
|
||||||
_TLS_0_STARTTLS = 60,
|
|
||||||
_TLS_1_ENCRYPT = 61,
|
|
||||||
_TLS_2_EHLO = 62,
|
|
||||||
|
|
||||||
// AUTH
|
|
||||||
_AUTH_PLAIN_0 = 70,
|
|
||||||
_AUTH_LOGIN_0 = 71,
|
|
||||||
_AUTH_LOGIN_1_USER = 72,
|
|
||||||
_AUTH_LOGIN_2_PASS = 73,
|
|
||||||
|
|
||||||
// MAIL
|
|
||||||
_MAIL_0_FROM = 81,
|
|
||||||
_MAIL_1_RCPT_INIT = 82,
|
|
||||||
_MAIL_2_RCPT = 83,
|
|
||||||
_MAIL_3_DATA = 84,
|
|
||||||
_MAIL_4_SEND_DATA = 85
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* [0] --- */
|
/* [0] --- */
|
||||||
@ -112,36 +69,56 @@ public:
|
|||||||
|
|
||||||
/* [2] Getters and Setters */
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
QString getHost() const;
|
const QString& getHost() const;
|
||||||
int getPort() const;
|
void setHost(const QString &host);
|
||||||
ConnectionType getConnectionType() const;
|
|
||||||
|
|
||||||
QString getName() const;
|
int getPort() const;
|
||||||
|
void setPort(int port);
|
||||||
|
|
||||||
|
const QString& getName() const;
|
||||||
void setName(const QString &name);
|
void setName(const QString &name);
|
||||||
|
|
||||||
QString getResponseText() const;
|
ConnectionType getConnectionType() const;
|
||||||
|
void setConnectionType(ConnectionType ct);
|
||||||
|
|
||||||
|
const QString & getUser() const;
|
||||||
|
void setUser(const QString &user);
|
||||||
|
|
||||||
|
const QString & getPassword() const;
|
||||||
|
void setPassword(const QString &password);
|
||||||
|
|
||||||
|
SmtpClient::AuthMethod getAuthMethod() const;
|
||||||
|
void setAuthMethod(AuthMethod method);
|
||||||
|
|
||||||
|
const QString & getResponseText() const;
|
||||||
int getResponseCode() const;
|
int getResponseCode() const;
|
||||||
|
|
||||||
|
int getConnectionTimeout() const;
|
||||||
|
void setConnectionTimeout(int msec);
|
||||||
|
|
||||||
|
int getResponseTimeout() const;
|
||||||
|
void setResponseTimeout(int msec);
|
||||||
|
|
||||||
|
int getSendMessageTimeout() const;
|
||||||
|
void setSendMessageTimeout(int msec);
|
||||||
|
|
||||||
QTcpSocket* getSocket();
|
QTcpSocket* getSocket();
|
||||||
|
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [3] Public methods */
|
/* [3] Public methods */
|
||||||
|
|
||||||
void connectToHost();
|
bool connectToHost();
|
||||||
void login(const QString &user, const QString &password, AuthMethod method = AuthLogin);
|
|
||||||
void sendMail(const MimeMessage & email);
|
bool login();
|
||||||
|
bool login(const QString &user, const QString &password, AuthMethod method = AuthLogin);
|
||||||
|
|
||||||
|
bool sendMail(MimeMessage& email);
|
||||||
|
|
||||||
void quit();
|
void quit();
|
||||||
void reset();
|
|
||||||
|
|
||||||
bool isConnected();
|
|
||||||
bool isLogged();
|
|
||||||
|
|
||||||
bool waitForReadyConnected(int msec = 30000);
|
|
||||||
bool waitForAuthenticated(int msec = 30000);
|
|
||||||
bool waitForMailSent(int msec = 30000);
|
|
||||||
bool waitForReset(int msec = 30000);
|
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
@ -149,54 +126,37 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected members */
|
/* [4] Protected members */
|
||||||
|
|
||||||
struct AuthInfo {
|
|
||||||
QString username;
|
|
||||||
QString password;
|
|
||||||
AuthMethod authMethod;
|
|
||||||
|
|
||||||
AuthInfo(const QString & username = "", const QString &password = "", AuthMethod authMethod = AuthPlain) :
|
|
||||||
username(username), password(password), authMethod(authMethod) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
QTcpSocket *socket;
|
QTcpSocket *socket;
|
||||||
ClientState state;
|
|
||||||
|
|
||||||
const QString host;
|
QString host;
|
||||||
const int port;
|
int port;
|
||||||
ConnectionType connectionType;
|
ConnectionType connectionType;
|
||||||
|
|
||||||
QString name;
|
QString name;
|
||||||
|
|
||||||
AuthInfo authInfo;
|
QString user;
|
||||||
|
QString password;
|
||||||
|
AuthMethod authMethod;
|
||||||
|
|
||||||
|
int connectionTimeout;
|
||||||
|
int responseTimeout;
|
||||||
|
int sendMessageTimeout;
|
||||||
|
|
||||||
|
|
||||||
QString responseText;
|
QString responseText;
|
||||||
QString tempResponse;
|
|
||||||
int responseCode;
|
int responseCode;
|
||||||
|
|
||||||
bool isReadyConnected;
|
|
||||||
bool isAuthenticated;
|
|
||||||
bool isMailSent;
|
|
||||||
bool isReset;
|
|
||||||
|
|
||||||
const MimeMessage *email;
|
class ResponseTimeoutException {};
|
||||||
|
class SendMessageTimeoutException {};
|
||||||
int rcptType;
|
|
||||||
enum _RcptType { _TO = 1, _CC = 2, _BCC = 3};
|
|
||||||
|
|
||||||
QList<EmailAddress>::const_iterator addressIt;
|
|
||||||
QList<EmailAddress>::const_iterator addressItEnd;
|
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
|
||||||
/* [5] Protected methods */
|
/* [5] Protected methods */
|
||||||
void login();
|
|
||||||
void setConnectionType(ConnectionType ct);
|
void waitForResponse();
|
||||||
void changeState(ClientState state);
|
|
||||||
void processResponse();
|
|
||||||
void sendMessage(const QString &text);
|
void sendMessage(const QString &text);
|
||||||
void emitError(SmtpClient::SmtpError e);
|
|
||||||
void waitForEvent(int msec, const char *successSignal);
|
|
||||||
|
|
||||||
/* [5] --- */
|
/* [5] --- */
|
||||||
|
|
||||||
@ -207,7 +167,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();
|
||||||
void socketEncrypted();
|
|
||||||
|
|
||||||
/* [6] --- */
|
/* [6] --- */
|
||||||
|
|
||||||
@ -216,14 +175,7 @@ signals:
|
|||||||
|
|
||||||
/* [7] Signals */
|
/* [7] Signals */
|
||||||
|
|
||||||
void error(SmtpClient::SmtpError e);
|
void smtpError(SmtpClient::SmtpError e);
|
||||||
void stateChanged(SmtpClient::ClientState s);
|
|
||||||
void connected();
|
|
||||||
void readyConnected();
|
|
||||||
void authenticated();
|
|
||||||
void mailSent();
|
|
||||||
void mailReset();
|
|
||||||
void disconnected();
|
|
||||||
|
|
||||||
/* [7] --- */
|
/* [7] --- */
|
||||||
|
|
||||||
|
12
src/smtpexports.h
Normal file
12
src/smtpexports.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef SMTPEXPORTS_H
|
||||||
|
#define SMTPEXPORTS_H
|
||||||
|
|
||||||
|
#ifdef SMTP_BUILD
|
||||||
|
#define SMTP_EXPORT Q_DECL_EXPORT
|
||||||
|
#elseif SMTP_USE
|
||||||
|
#define SMTP_EXPORT Q_DECL_IMPORT
|
||||||
|
#else
|
||||||
|
#define SMTP_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SMTPEXPORTS_H
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef SMTPMIME_GLOBAL_H
|
|
||||||
#define SMTPMIME_GLOBAL_H
|
|
||||||
|
|
||||||
#ifdef SMTP_MIME_LIBRARY
|
|
||||||
#define SMTP_MIME_EXPORT Q_DECL_EXPORT
|
|
||||||
#else
|
|
||||||
#define SMTP_MIME_EXPORT Q_DECL_IMPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SMTPMIME_GLOBAL_H
|
|
@ -1,10 +0,0 @@
|
|||||||
smtp.gmail.com 25 1
|
|
||||||
smtp.gmail.com 465 2
|
|
||||||
smtp.gmail.com 587 3
|
|
||||||
smtp.mail.yahoo.com 25 1
|
|
||||||
smtp.mail.yahoo.com 465 2
|
|
||||||
smtp.1and1.com 25 1
|
|
||||||
smtp.1and1.com 465 2
|
|
||||||
smtp.1and1.com 587 3
|
|
||||||
smtp.live.com 25 1
|
|
||||||
smtp.live.com 587 3
|
|
@ -1,55 +0,0 @@
|
|||||||
#include "connectiontest.h"
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QtTest/QtTest>
|
|
||||||
#include "../src/smtpclient.h"
|
|
||||||
|
|
||||||
ConnectionTest::ConnectionTest(QObject *parent) :
|
|
||||||
QObject(parent) {}
|
|
||||||
|
|
||||||
|
|
||||||
void ConnectionTest::init() {
|
|
||||||
//qDebug() << "Init...";
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnectionTest::testConnect() {
|
|
||||||
QFETCH(QString, host);
|
|
||||||
QFETCH(int, port);
|
|
||||||
QFETCH(int, connectionType);
|
|
||||||
|
|
||||||
const SmtpClient::ConnectionType cTypes[] = {
|
|
||||||
SmtpClient::TcpConnection,
|
|
||||||
SmtpClient::SslConnection,
|
|
||||||
SmtpClient::TcpConnection
|
|
||||||
};
|
|
||||||
|
|
||||||
SmtpClient::ConnectionType cType = cTypes[--connectionType];
|
|
||||||
|
|
||||||
SmtpClient smtp(host, port, cType);
|
|
||||||
smtp.connectToHost();
|
|
||||||
|
|
||||||
QCOMPARE(smtp.waitForReadyConnected(5000), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnectionTest::testConnect_data() {
|
|
||||||
QTest::addColumn<QString>("host");
|
|
||||||
QTest::addColumn<int>("port");
|
|
||||||
QTest::addColumn<int>("connectionType");
|
|
||||||
|
|
||||||
QFile file("../connect_data.txt");
|
|
||||||
file.open(QIODevice::ReadOnly);
|
|
||||||
QTextStream in(&file);
|
|
||||||
|
|
||||||
while (!in.atEnd()) {
|
|
||||||
QString host;
|
|
||||||
int port;
|
|
||||||
int connectionType;
|
|
||||||
in >> host >> port >> connectionType;
|
|
||||||
if (!host.isEmpty()) {
|
|
||||||
QTest::newRow(QString("%1:%2").arg(host).arg(port).toLocal8Bit().data()) << host << port << connectionType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnectionTest::cleanup() {
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#ifndef CONNECTIONTEST_H
|
|
||||||
#define CONNECTIONTEST_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
class ConnectionTest : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
ConnectionTest(QObject *parent = 0);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
|
|
||||||
void init();
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
void testConnect();
|
|
||||||
void testConnect_data();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CONNECTIONTEST_H
|
|
@ -1,26 +0,0 @@
|
|||||||
#include <QCoreApplication>
|
|
||||||
#include <QtTest/QTest>
|
|
||||||
#include <QDebug>
|
|
||||||
#include "connectiontest.h"
|
|
||||||
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
static void runTest(QObject *test, int argc, char** argv) {
|
|
||||||
int retVal = QTest::qExec(test, argc, argv);
|
|
||||||
delete test;
|
|
||||||
success &= retVal == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
QCoreApplication a(argc, argv);
|
|
||||||
|
|
||||||
runTest(new ConnectionTest(), argc, argv);
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
qDebug() << "SUCCESS";
|
|
||||||
else
|
|
||||||
qDebug() << "FAIL";
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#-------------------------------------------------
|
|
||||||
#
|
|
||||||
# Project created by QtCreator 2012-09-22T16:39:45
|
|
||||||
#
|
|
||||||
#-------------------------------------------------
|
|
||||||
|
|
||||||
QT += testlib
|
|
||||||
QT -= gui
|
|
||||||
|
|
||||||
TARGET = test
|
|
||||||
CONFIG += console
|
|
||||||
CONFIG -= app_bundle
|
|
||||||
|
|
||||||
TEMPLATE = app
|
|
||||||
|
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
|
||||||
connectiontest.cpp
|
|
||||||
|
|
||||||
HEADERS += \
|
|
||||||
connectiontest.h
|
|
||||||
|
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../bin/lib/release/ -lSmtpMime
|
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../bin/lib/debug/ -lSmtpMime
|
|
||||||
else:unix:!symbian: LIBS += -L$$PWD/../bin/lib/release/ -lSmtpMime
|
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/../bin/lib/release
|
|
||||||
DEPENDPATH += $$PWD/../bin/lib/release
|
|
Loading…
Reference in New Issue
Block a user