Started the state machine implementation.
This commit is contained in:
parent
04b7054aa9
commit
b0e7a31b64
@ -25,6 +25,7 @@
|
||||
/* [1] Constructors and destructors */
|
||||
|
||||
SmtpClient::SmtpClient(const QString & host, int port, ConnectionType connectionType) :
|
||||
state(UnconnectedState),
|
||||
name("localhost"),
|
||||
authMethod(AuthPlain),
|
||||
connectionTimeout(5000),
|
||||
@ -377,7 +378,6 @@ void SmtpClient::quit()
|
||||
|
||||
|
||||
/* [4] Protected methods */
|
||||
|
||||
void SmtpClient::waitForResponse() throw (ResponseTimeoutException)
|
||||
{
|
||||
if (!socket->waitForReadyRead(responseTimeout))
|
||||
@ -386,17 +386,70 @@ void SmtpClient::waitForResponse() throw (ResponseTimeoutException)
|
||||
throw ResponseTimeoutException();
|
||||
}
|
||||
|
||||
processResponse();
|
||||
}
|
||||
|
||||
void SmtpClient::changeState(ClientState state) {
|
||||
this->state = state;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case _ELHO_State:
|
||||
// Service ready. Send ELHO message and chage the state
|
||||
sendMessage("ELHO " + name);
|
||||
break;
|
||||
|
||||
case _TLS_State:
|
||||
// send a request to start TLS handshake
|
||||
sendMessage("STARTTLS");
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if (state <= DisconnectingState) { // don't emit for internal signals
|
||||
emit stateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
void SmtpClient::processResponse() {
|
||||
// Save the server's response
|
||||
responseText = socket->readAll();
|
||||
|
||||
// Extract the respose code from the server's responce (first 3 digits)
|
||||
responseCode = responseText.left(3).toInt();
|
||||
|
||||
if (responseCode / 100 == 4)
|
||||
emit smtpError(ServerError);
|
||||
if (responseCode / 100 == 4) {
|
||||
emit smtpError(ServerError); return;
|
||||
}
|
||||
|
||||
if (responseCode / 100 == 5)
|
||||
emit smtpError(ClientError);
|
||||
if (responseCode / 100 == 5) {
|
||||
emit smtpError(ClientError); return;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ConnectedState:
|
||||
// Just connected to the server. Wait for 220 (Service ready)
|
||||
if (responseCode != 220) {
|
||||
emit smtpError(ServerError); return;
|
||||
}
|
||||
changeState(_ELHO_State);
|
||||
break;
|
||||
|
||||
case _ELHO_State:
|
||||
// The response code needs to be 250.
|
||||
if (responseCode != 250) {
|
||||
emit smtpError(ServerError); return;
|
||||
}
|
||||
|
||||
changeState((connectionType != TlsConnection) ? ReadyState : _TLS_State);
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void SmtpClient::sendMessage(const QString &text)
|
||||
@ -409,16 +462,28 @@ void SmtpClient::sendMessage(const QString &text)
|
||||
|
||||
/* [5] Slots for the socket's signals */
|
||||
|
||||
void SmtpClient::socketStateChanged(QAbstractSocket::SocketState state)
|
||||
void SmtpClient::socketStateChanged(QAbstractSocket::SocketState state) {
|
||||
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) {
|
||||
emit smtpError(SocketError);
|
||||
}
|
||||
|
||||
void SmtpClient::socketReadyRead()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* [5] --- */
|
||||
|
@ -44,7 +44,8 @@ public:
|
||||
ResponseTimeoutError,
|
||||
AuthenticationFailedError,
|
||||
ServerError, // 4xx smtp error
|
||||
ClientError // 5xx smtp error
|
||||
ClientError, // 5xx smtp error
|
||||
SocketError
|
||||
};
|
||||
|
||||
enum ConnectionType
|
||||
@ -54,13 +55,24 @@ public:
|
||||
TlsConnection // STARTTLS
|
||||
};
|
||||
|
||||
enum State {
|
||||
UnconnectedState,
|
||||
ConnectingState,
|
||||
ConnectedState,
|
||||
AuthenticatingState,
|
||||
MailSendingState,
|
||||
DisconnectingState
|
||||
enum ClientState {
|
||||
UnconnectedState = 0,
|
||||
ConnectingState = 1,
|
||||
ConnectedState = 2,
|
||||
ReadyState = 3,
|
||||
AuthenticatingState = 4,
|
||||
MailSendingState = 5,
|
||||
DisconnectingState = 6,
|
||||
|
||||
/* Internal States */
|
||||
_ELHO_State = 50,
|
||||
_TLS_State = 51,
|
||||
|
||||
/* Internal Substates */
|
||||
_TLS_0_START = 60,
|
||||
_TLS_1_ENCRYPT = 61,
|
||||
_TLS_2_ELHO = 62
|
||||
|
||||
};
|
||||
|
||||
/* [0] --- */
|
||||
@ -126,6 +138,8 @@ protected:
|
||||
/* [4] Protected members */
|
||||
|
||||
QTcpSocket *socket;
|
||||
ClientState state;
|
||||
bool syncMode;
|
||||
|
||||
QString host;
|
||||
int port;
|
||||
@ -149,6 +163,9 @@ protected:
|
||||
|
||||
|
||||
/* [5] Protected methods */
|
||||
void changeState(ClientState state);
|
||||
|
||||
void processResponse();
|
||||
|
||||
void waitForResponse() throw (ResponseTimeoutException);
|
||||
|
||||
@ -172,6 +189,7 @@ signals:
|
||||
/* [7] Signals */
|
||||
|
||||
void smtpError(SmtpError e);
|
||||
void stateChanged(ClientState s);
|
||||
|
||||
/* [7] --- */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user