Added support for enhanced status codes (RFC-3463).
This commit is contained in:
parent
2591c82079
commit
8cd361ff8c
@ -35,6 +35,8 @@
|
|||||||
#include "vmime/net/socket.hpp"
|
#include "vmime/net/socket.hpp"
|
||||||
#include "vmime/net/timeoutHandler.hpp"
|
#include "vmime/net/timeoutHandler.hpp"
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
|
||||||
namespace vmime {
|
namespace vmime {
|
||||||
namespace net {
|
namespace net {
|
||||||
@ -71,6 +73,12 @@ int SMTPResponse::getCode() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const SMTPResponse::enhancedStatusCode SMTPResponse::getEnhancedCode() const
|
||||||
|
{
|
||||||
|
return m_lines[m_lines.size() - 1].getEnhancedCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const string SMTPResponse::getText() const
|
const string SMTPResponse::getText() const
|
||||||
{
|
{
|
||||||
string text = m_lines[0].getText();
|
string text = m_lines[0].getText();
|
||||||
@ -175,7 +183,7 @@ const SMTPResponse::responseLine SMTPResponse::getNextResponse()
|
|||||||
else
|
else
|
||||||
text = "";
|
text = "";
|
||||||
|
|
||||||
return responseLine(code, text);
|
return responseLine(code, text, extractEnhancedCode(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -195,6 +203,33 @@ int SMTPResponse::extractResponseCode(const string& response)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
const SMTPResponse::enhancedStatusCode SMTPResponse::extractEnhancedCode(const string& responseText)
|
||||||
|
{
|
||||||
|
enhancedStatusCode enhCode;
|
||||||
|
|
||||||
|
std::istringstream iss(responseText);
|
||||||
|
|
||||||
|
if (std::isdigit(iss.peek()))
|
||||||
|
{
|
||||||
|
iss >> enhCode.klass;
|
||||||
|
|
||||||
|
if (iss.get() == '.' && std::isdigit(iss.peek()))
|
||||||
|
{
|
||||||
|
iss >> enhCode.subject;
|
||||||
|
|
||||||
|
if (iss.get() == '.' && std::isdigit(iss.peek()))
|
||||||
|
{
|
||||||
|
iss >> enhCode.detail;
|
||||||
|
return enhCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return enhancedStatusCode(); // no enhanced code found
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const SMTPResponse::responseLine SMTPResponse::getLineAt(const size_t pos) const
|
const SMTPResponse::responseLine SMTPResponse::getLineAt(const size_t pos) const
|
||||||
{
|
{
|
||||||
return m_lines[pos];
|
return m_lines[pos];
|
||||||
@ -225,8 +260,8 @@ const SMTPResponse::state SMTPResponse::getCurrentState() const
|
|||||||
|
|
||||||
// SMTPResponse::responseLine
|
// SMTPResponse::responseLine
|
||||||
|
|
||||||
SMTPResponse::responseLine::responseLine(const int code, const string& text)
|
SMTPResponse::responseLine::responseLine(const int code, const string& text, const enhancedStatusCode& enhCode)
|
||||||
: m_code(code), m_text(text)
|
: m_code(code), m_text(text), m_enhCode(enhCode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +278,18 @@ int SMTPResponse::responseLine::getCode() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SMTPResponse::responseLine::setEnhancedCode(const enhancedStatusCode& enhCode)
|
||||||
|
{
|
||||||
|
m_enhCode = enhCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const SMTPResponse::enhancedStatusCode SMTPResponse::responseLine::getEnhancedCode() const
|
||||||
|
{
|
||||||
|
return m_enhCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SMTPResponse::responseLine::setText(const string& text)
|
void SMTPResponse::responseLine::setText(const string& text)
|
||||||
{
|
{
|
||||||
m_text = text;
|
m_text = text;
|
||||||
@ -255,6 +302,22 @@ const string SMTPResponse::responseLine::getText() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// SMTPResponse::enhancedStatusCode
|
||||||
|
|
||||||
|
|
||||||
|
SMTPResponse::enhancedStatusCode::enhancedStatusCode()
|
||||||
|
: klass(0), subject(0), detail(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SMTPResponse::enhancedStatusCode::enhancedStatusCode(const enhancedStatusCode& enhCode)
|
||||||
|
: klass(enhCode.klass), subject(enhCode.subject), detail(enhCode.detail)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // smtp
|
} // smtp
|
||||||
} // net
|
} // net
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -35,6 +35,9 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest)
|
|||||||
VMIME_TEST(testMultiLineResponseDifferentCode)
|
VMIME_TEST(testMultiLineResponseDifferentCode)
|
||||||
VMIME_TEST(testIncompleteMultiLineResponse)
|
VMIME_TEST(testIncompleteMultiLineResponse)
|
||||||
VMIME_TEST(testNoResponseText)
|
VMIME_TEST(testNoResponseText)
|
||||||
|
VMIME_TEST(testEnhancedStatusCode)
|
||||||
|
VMIME_TEST(testNoEnhancedStatusCode)
|
||||||
|
VMIME_TEST(testInvalidEnhancedStatusCode)
|
||||||
VMIME_TEST_LIST_END
|
VMIME_TEST_LIST_END
|
||||||
|
|
||||||
|
|
||||||
@ -171,6 +174,68 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest)
|
|||||||
VASSERT_EQ("Text", "", resp->getText());
|
VASSERT_EQ("Text", "", resp->getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testEnhancedStatusCode()
|
||||||
|
{
|
||||||
|
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||||
|
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||||
|
vmime::create <testTimeoutHandler>();
|
||||||
|
|
||||||
|
socket->localSend("250 2.1.5 OK fu13sm4720601wic.7 - gsmtp\r\n");
|
||||||
|
|
||||||
|
vmime::net::smtp::SMTPResponse::state responseState;
|
||||||
|
|
||||||
|
vmime::ref <vmime::net::smtp::SMTPResponse> resp =
|
||||||
|
vmime::net::smtp::SMTPResponse::readResponse(socket, toh, responseState);
|
||||||
|
|
||||||
|
VASSERT_EQ("Code", 250, resp->getCode());
|
||||||
|
VASSERT_EQ("Lines", 1, resp->getLineCount());
|
||||||
|
VASSERT_EQ("Text", "2.1.5 OK fu13sm4720601wic.7 - gsmtp", resp->getText());
|
||||||
|
VASSERT_EQ("Enh.class", 2, resp->getEnhancedCode().klass);
|
||||||
|
VASSERT_EQ("Enh.subject", 1, resp->getEnhancedCode().subject);
|
||||||
|
VASSERT_EQ("Enh.detail", 5, resp->getEnhancedCode().detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNoEnhancedStatusCode()
|
||||||
|
{
|
||||||
|
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||||
|
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||||
|
vmime::create <testTimeoutHandler>();
|
||||||
|
|
||||||
|
socket->localSend("354 Go ahead fu13sm4720601wic.7 - gsmtp\r\n");
|
||||||
|
|
||||||
|
vmime::net::smtp::SMTPResponse::state responseState;
|
||||||
|
|
||||||
|
vmime::ref <vmime::net::smtp::SMTPResponse> resp =
|
||||||
|
vmime::net::smtp::SMTPResponse::readResponse(socket, toh, responseState);
|
||||||
|
|
||||||
|
VASSERT_EQ("Code", 354, resp->getCode());
|
||||||
|
VASSERT_EQ("Lines", 1, resp->getLineCount());
|
||||||
|
VASSERT_EQ("Text", "Go ahead fu13sm4720601wic.7 - gsmtp", resp->getText());
|
||||||
|
VASSERT_EQ("Enh.class", 0, resp->getEnhancedCode().klass);
|
||||||
|
VASSERT_EQ("Enh.subject", 0, resp->getEnhancedCode().subject);
|
||||||
|
VASSERT_EQ("Enh.detail", 0, resp->getEnhancedCode().detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testInvalidEnhancedStatusCode()
|
||||||
|
{
|
||||||
|
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||||
|
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||||
|
vmime::create <testTimeoutHandler>();
|
||||||
|
|
||||||
|
socket->localSend("250 4.2 xxx\r\n");
|
||||||
|
|
||||||
|
vmime::net::smtp::SMTPResponse::state responseState;
|
||||||
|
|
||||||
|
vmime::ref <vmime::net::smtp::SMTPResponse> resp =
|
||||||
|
vmime::net::smtp::SMTPResponse::readResponse(socket, toh, responseState);
|
||||||
|
|
||||||
|
VASSERT_EQ("Code", 250, resp->getCode());
|
||||||
|
VASSERT_EQ("Lines", 1, resp->getLineCount());
|
||||||
|
VASSERT_EQ("Text", "4.2 xxx", resp->getText());
|
||||||
|
VASSERT_EQ("Enh.class", 0, resp->getEnhancedCode().klass);
|
||||||
|
VASSERT_EQ("Enh.subject", 0, resp->getEnhancedCode().subject);
|
||||||
|
VASSERT_EQ("Enh.detail", 0, resp->getEnhancedCode().detail);
|
||||||
|
}
|
||||||
|
|
||||||
VMIME_TEST_SUITE_END
|
VMIME_TEST_SUITE_END
|
||||||
|
|
||||||
|
@ -60,16 +60,30 @@ public:
|
|||||||
string responseBuffer;
|
string responseBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Enhanced status code (as per RFC-3463). */
|
||||||
|
struct enhancedStatusCode
|
||||||
|
{
|
||||||
|
enhancedStatusCode();
|
||||||
|
enhancedStatusCode(const enhancedStatusCode& enhCode);
|
||||||
|
|
||||||
|
unsigned short klass; /**< Success/failure. */
|
||||||
|
unsigned short subject; /**< Source of anomaly. */
|
||||||
|
unsigned short detail; /**< Precise error condition. */
|
||||||
|
};
|
||||||
|
|
||||||
/** An element of a SMTP response. */
|
/** An element of a SMTP response. */
|
||||||
class responseLine
|
class responseLine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
responseLine(const int code, const string& text);
|
responseLine(const int code, const string& text, const enhancedStatusCode& enhCode);
|
||||||
|
|
||||||
void setCode(const int code);
|
void setCode(const int code);
|
||||||
int getCode() const;
|
int getCode() const;
|
||||||
|
|
||||||
|
void setEnhancedCode(const enhancedStatusCode& enhCode);
|
||||||
|
const enhancedStatusCode getEnhancedCode() const;
|
||||||
|
|
||||||
void setText(const string& text);
|
void setText(const string& text);
|
||||||
const string getText() const;
|
const string getText() const;
|
||||||
|
|
||||||
@ -77,6 +91,7 @@ public:
|
|||||||
|
|
||||||
int m_code;
|
int m_code;
|
||||||
string m_text;
|
string m_text;
|
||||||
|
enhancedStatusCode m_enhCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Receive and parse a new SMTP response from the
|
/** Receive and parse a new SMTP response from the
|
||||||
@ -97,6 +112,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
int getCode() const;
|
int getCode() const;
|
||||||
|
|
||||||
|
/** Return the SMTP enhanced status code, if available.
|
||||||
|
*
|
||||||
|
* @return enhanced status code
|
||||||
|
*/
|
||||||
|
const enhancedStatusCode getEnhancedCode() const;
|
||||||
|
|
||||||
/** Return the SMTP response text.
|
/** Return the SMTP response text.
|
||||||
* The text of each line is concatenated.
|
* The text of each line is concatenated.
|
||||||
*
|
*
|
||||||
@ -140,6 +161,7 @@ private:
|
|||||||
const responseLine getNextResponse();
|
const responseLine getNextResponse();
|
||||||
|
|
||||||
static int extractResponseCode(const string& response);
|
static int extractResponseCode(const string& response);
|
||||||
|
static const enhancedStatusCode extractEnhancedCode(const string& responseText);
|
||||||
|
|
||||||
|
|
||||||
std::vector <responseLine> m_lines;
|
std::vector <responseLine> m_lines;
|
||||||
|
Loading…
Reference in New Issue
Block a user