Started the state machine implementation.
This commit is contained in:
parent
04b7054aa9
commit
b0e7a31b64
@ -25,6 +25,7 @@
|
|||||||
/* [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),
|
||||||
name("localhost"),
|
name("localhost"),
|
||||||
authMethod(AuthPlain),
|
authMethod(AuthPlain),
|
||||||
connectionTimeout(5000),
|
connectionTimeout(5000),
|
||||||
@ -377,7 +378,6 @@ void SmtpClient::quit()
|
|||||||
|
|
||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
void SmtpClient::waitForResponse() throw (ResponseTimeoutException)
|
void SmtpClient::waitForResponse() throw (ResponseTimeoutException)
|
||||||
{
|
{
|
||||||
if (!socket->waitForReadyRead(responseTimeout))
|
if (!socket->waitForReadyRead(responseTimeout))
|
||||||
@ -386,17 +386,70 @@ void SmtpClient::waitForResponse() throw (ResponseTimeoutException)
|
|||||||
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
|
// Save the server's response
|
||||||
responseText = socket->readAll();
|
responseText = socket->readAll();
|
||||||
|
|
||||||
// Extract the respose code from the server's responce (first 3 digits)
|
// Extract the respose code from the server's responce (first 3 digits)
|
||||||
responseCode = responseText.left(3).toInt();
|
responseCode = responseText.left(3).toInt();
|
||||||
|
|
||||||
if (responseCode / 100 == 4)
|
if (responseCode / 100 == 4) {
|
||||||
emit smtpError(ServerError);
|
emit smtpError(ServerError); return;
|
||||||
|
}
|
||||||
|
|
||||||
if (responseCode / 100 == 5)
|
if (responseCode / 100 == 5) {
|
||||||
emit smtpError(ClientError);
|
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)
|
void SmtpClient::sendMessage(const QString &text)
|
||||||
@ -409,16 +462,28 @@ void SmtpClient::sendMessage(const QString &text)
|
|||||||
|
|
||||||
/* [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) {
|
||||||
|
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()
|
void SmtpClient::socketReadyRead()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [5] --- */
|
/* [5] --- */
|
||||||
|
@ -44,7 +44,8 @@ public:
|
|||||||
ResponseTimeoutError,
|
ResponseTimeoutError,
|
||||||
AuthenticationFailedError,
|
AuthenticationFailedError,
|
||||||
ServerError, // 4xx smtp error
|
ServerError, // 4xx smtp error
|
||||||
ClientError // 5xx smtp error
|
ClientError, // 5xx smtp error
|
||||||
|
SocketError
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ConnectionType
|
enum ConnectionType
|
||||||
@ -54,13 +55,24 @@ public:
|
|||||||
TlsConnection // STARTTLS
|
TlsConnection // STARTTLS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum State {
|
enum ClientState {
|
||||||
UnconnectedState,
|
UnconnectedState = 0,
|
||||||
ConnectingState,
|
ConnectingState = 1,
|
||||||
ConnectedState,
|
ConnectedState = 2,
|
||||||
AuthenticatingState,
|
ReadyState = 3,
|
||||||
MailSendingState,
|
AuthenticatingState = 4,
|
||||||
DisconnectingState
|
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] --- */
|
/* [0] --- */
|
||||||
@ -126,6 +138,8 @@ protected:
|
|||||||
/* [4] Protected members */
|
/* [4] Protected members */
|
||||||
|
|
||||||
QTcpSocket *socket;
|
QTcpSocket *socket;
|
||||||
|
ClientState state;
|
||||||
|
bool syncMode;
|
||||||
|
|
||||||
QString host;
|
QString host;
|
||||||
int port;
|
int port;
|
||||||
@ -149,6 +163,9 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
/* [5] Protected methods */
|
/* [5] Protected methods */
|
||||||
|
void changeState(ClientState state);
|
||||||
|
|
||||||
|
void processResponse();
|
||||||
|
|
||||||
void waitForResponse() throw (ResponseTimeoutException);
|
void waitForResponse() throw (ResponseTimeoutException);
|
||||||
|
|
||||||
@ -172,6 +189,7 @@ signals:
|
|||||||
/* [7] Signals */
|
/* [7] Signals */
|
||||||
|
|
||||||
void smtpError(SmtpError e);
|
void smtpError(SmtpError e);
|
||||||
|
void stateChanged(ClientState s);
|
||||||
|
|
||||||
/* [7] --- */
|
/* [7] --- */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user