QwwSmtpClient

It’s often good to improve your mood by “doing something nice for yourself” which in my case often means “implement something interesting even if it’s currently completely useless for you but provides a challenge for your brain”.

As some time ago I felt really bad, I did follow that advice and implemented a class for Qt to handle SMTP connections. Only yesterday I noticed J-P Nurmi has implemented a library to handle the IRC protocol which means the family of protocols supported by plain Qt is now at least HTTP, FTP (both internally via QHttp and QFtp), IRC (via LibIrcClient-Qt) and SMTP (QwwSmtpClient). I have plans to also implement POP3 as it’s very simple but I’m waiting for the next wave of bad mood to do it.

So… what does QwwSmtpClient do? It mimics QHttp, so it’s command-based which means you have to issue a few commands and monitor their result to be able to do something useful. I know that sucks a bit, but I wanted to have a similar architecture to QHttp and the next step is to implement a wrapper around the class to provide an interface similar to QNetworkAccessManager which should be quite easy and should not require bad mood to do it.

QwwSmtpClient currently supports:

  • plain connections to SMTP (port 25 by default),
  • SSL connections to SMTP (port 465 by default),
  • TLS connections (STARTTLS command after a plaintext connection),
  • Authentication via PLAIN or LOGIN methods,
  • sending mail using low-level commands (MAIL, RCPT, DATA),
  • HELO or EHLO conversations.

The library is not yet foul-proof nor very idiot-proof but it works allowing one to send mails directly from within Qt applications. I’ll release the code to the public soon.

Here is a small example:

#include <QApplication>
#include <QStringList>
#include "qwwsmtpclient.h"
 
int main(int argc, char **argv){
    QApplication app(argc, argv);
    QwwSmtpClient client;
    // ignore certificate errors as suggested by ssl socket docs:
    app.connect(&client, SIGNAL(sslErrors(const QList &)), 
                &client, SLOT(ignoreSslErrors())); 
    // start plain-text connection:
    client.connectToHost("mail.example.com");
    // start encryption handshake:
    client.startTls();
    // when that's done authenticate yourself to the server:
    client.authenticate("user", "pass", QwwSmtpClient::AuthLogin);
    // send an email:
    client.sendMail("sender@example.com", "receiver@example.com", 
                           "From:    sender@example.com\r\n"
                           "To:      receiver@example.com\r\n"
                           "Subject: testing QwwSmtpClient\r\n"
                           "\r\n" // blank line to denote end of headers
                           "Does it work?");
    // disconnect afterwards:
    client.disconnectFromHost();
    // quit when you're done:
    app.connect(&client, SIGNAL(disconnected()), &app, SLOT(quit()));
    return app.exec();
}

Tags: , , , ,

14 Responses to “QwwSmtpClient”

  1. Anon says:

    Very nice! Can this be used by non-GUI Qt apps?

  2. Alex says:

    I believe it’s a good example of writing a code which communicates with most servers (my collegues were not successful in trying with one Exchange server out of 3 but this could’ve been caused by some extra filtering applied there).

  3. GeorgeP says:

    Hmm, this looks very cool, I might use this someday :)

    Cheers.

  4. Jan Kundrát says:

    Hi Witold, did you proceed with publishing the sources? I’d like to use that in my bachelor’s thesis, so that I don’t have to invent the SMTP client wheel again.

  5. Jan Žižka says:

    Nice! I like it.

    Would it be possible to change client.sendMail(…
    to use something like QwwMail class object instead of this ugly C-style function parameters?
    You could easily update properties of QwwMail object to set to:, subject: etc.

    • wysota says:

      This is so low-level on purpose. I’m going to implement a higher level API that uses something similar to QNetworkRequest and QNetworkReply and the methods you mentioned are going to be there.

      Stay tuned!

  6. nanortemis says:

    Unable to compile with nmake :(

  7. hermoso says:

    hi, this work is very great and helps a lot.. just want to ask if this is this capable for attaching file? and adding CC for multiple receivers..

    cheers! ;P

    • wysota says:

      Yes, it’s capable of both these things but you have to remember this is a low-level mechanism – there is no “attachFile” method, you have to craft the body of the message appropriately yourself. As for CC it is just a matter of adding a CC header.

  8. Hello dear developer!
    Your sw product usage is great!
    Currently I am trying to put qwwwsmtpclient classes to my application so as to make tell a friend user glorius feature
    What is the host, username, password I should past in the code so as to connect and to send email using your qwwsmtpclient constant and reliable?
    I try to build qwwsmtpclient but compiler could not recognize, QSslSocket type! What is the problem, why qt 4.7 on windows could not compile your qwwsmtpclasses?

    A lot of thanks,
    Pavel Mazniker

  9. Hi
    I have succeed to compile qwwsmtp client classes and “attached” them to my application. Now I am sending emails using your classes but I have next error(problem)
    1)I use as a host “smtp://smtp.gmail.com”, my gmail username, my gmail password and QSslSocket that is in use in qwwsmtp classes does not reach state sending HELO(EHLO) it is reaching disconnect function after authentification function
    2) Why did you comment int QwwSmtpClient::connectToHost(const QHostAddress & address, quint16 port) in the code?
    3) I continue to put the classes to work try to understand the classes and succeed with sending email
    Thanks in advance,
    Pavel

  10. michael says:

    Hey,
    Thanks for the code. However I am sorry to break to you that it does not work. It was tested on Qt 4.7 on windows with OPENSSL installed.

  11. Pavl says:

    Hi,
    trying to send emails from Ubuntu using the qwwwsmtpclient classes.If I I understand right:
    1. sending to/from gmail – server name smtp.gmail.com , port 587 , username – “your gmail account” ,password – “your gmail pass.”
    2.On Ubuntu SSL version installed:OpenSSL 1.0.0e 6 Sep 2011
    3. Qt Version 4.8.0
    4. Using main.cpp and qwwwsmtpclient.h/qwwsmtpclient.cpp downloaded from here – still emails can’t be sent.
    Trying to put it to work…

Leave a Reply to Anon