All Classes Namespaces Functions Variables Groups Pages
SmtpClient.qm.dox.h
// -*- mode: c++; indent-tabs-mode: nil -*-
// @file SmtpClient.qm SmtpClient module definition
/* SmtpClient.qm Copyright 2012 Wolfgang Ritzinger, Marian Bonda, Pavol Potoncok
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
// minimum qore version
// need mime definitions
// need MailMessage classes
/* Version History
* 2012-11-24 v1.2: David Nichols <david@qore.org>:
+ added support for parsing a full URL in the SmtpClient::constructor(); added protocol support and setting the username / password from the URL
+ use Message::checkSendPossible() to throw a more descriptive exception if the message is incomplete and not ready to be sent
+ implemented support for automatically detecting if the server accepts the STARTTLS command and, if so, automatically setting the STARTTLS flag if it's not already set
* 2012-06-14 v1.1: David Nichols <david@qore.org>:
+ removed the Message and Attachment classes to the MailMessage module to be reused in the Pop3Client module
* 2012-05-21 v1.0: David Nichols <david@qore.org>:
+ updated to a user module, added initial rudimentary ESMTP handling, STARTTLS and quoted-printable encoding support + the bane of all developers: documentation :)
ritzinwo, 20090716
based on:
- http://james.apache.org/server/rfclist/smtp/rfc0821.txt
- http://tools.ietf.org/html/rfc821: initial SMTP protocol spec
- http://tools.ietf.org/html/rfc1521: quoted printable & base 64 transfer encodings
- http://tools.ietf.org/html/rfc2045: mime headers, content types, etc
- http://tools.ietf.org/html/rfc2047: "Q" and "B" encoded words (implemented by the Mime module)
- http://tools.ietf.org/html/rfc2822: message structure, headers, body, etc
*/
namespace SmtpClient {
const DefaultReadTimeout = 15s;
const DefaultConnectTimeout = 30s;
class Message : public MailMessage::Message {
public:
constructor(string sender, string subject);
};
class Attachment : public MailMessage::Attachment {
public:
};
class SmtpClient {
public:
private :
Socket sock();
// connect string
string connect;
// ensures exclusive access to the object
Mutex mutex();
bool nosend = False;
// optional info log closure
*code log_info;
// optional debug log closure
*code log_debug;
// tls flag (ie \c "STARTTLS" flag; ie application layer security)
bool tls = False;
// ssl flag (for TLS/SSL connections - ie transport layer instead of application layer security)
bool ssl = False;
// esmtp flag
bool esmtp;
// authentication credentials
*string user;
*string pass;
// logged in flag
bool logged_in = False;
// read timeout in milliseconds
timeout readTimeout = DefaultReadTimeout;
// connect timeout in milliseconds
timeout connectTimeout = DefaultConnectTimeout;
const MaxDebugLine = 2048;
public:
public :
string mpboundary = replace(makeBase64String(string(now_us())), "=", "");
const SmtpPort = 25;
const SmtpsPort = 465;
const EsmtpPort = 587;
const Protocols = (
"smtp": (
"port": SmtpPort,
"ssl": False,
"tls": False,
),
"smtps": (
"port": SmtpsPort,
"ssl": True,
"tls": False,
),
"smtptls": (
"port": SmtpsPort,
"ssl": False,
"tls": True,
),
"esmtp": (
"port": EsmtpPort,
"ssl": False,
"tls": False,
),
"esmtptls": (
"port": EsmtpPort,
"ssl": False,
"tls": True,
),
);
public:
constructor(string host, softint port, *code log, *code dbglog);
constructor(string url, *code log, *code dbglog);
destructor();
tls(bool tls);
bool tls();
ssl(bool ssl);
bool ssl();
setUserPass(string user, string pass);
test(bool ns);
bool test();
connect();
bool isConnected();
disconnect();
setReadTimeout(timeout to);
int getReadTimeoutMs();
date getReadTimeoutDate();
setConnectTimeout(timeout to);
int getConnectTimeoutMs();
date getConnectTimeoutDate();
hash sendMessage(MailMessage::Message message);
forceDisconnect();
// don't reimplement this method; fix/enhance it in the module
private:
final disconnectIntern();
public:
private:
log(string msg);
public:
private:
logDbg(string msg);
public:
private:
connectIntern();
public:
// send data over the socket
private:
sendDataIntern(data str);
public:
// send data and log in the debug log if set
private:
sendData(string str);
public:
// send data and log in the debug log if set
private:
sendData(binary b);
public:
// send a command over the socket and return the response as a hash
// don't reimplement this method; fix/enhance it in the module
private:
final hash sendCommand(string str);
public:
// read a line from the socket (terminated with \n)
private:
string readLine(timeout to);
public:
// sends the message header (without body & attachments) to the SMTP server
// don't reimplement this method; fix/enhance it in the module
private:
final hash sendMessageHeaderIntern(MailMessage::Message message);
public:
private:
forceDisconnectIntern();
public:
};
};