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/timeoutHandler.hpp"
|
||||
|
||||
#include <cctype>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
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
|
||||
{
|
||||
string text = m_lines[0].getText();
|
||||
@ -175,7 +183,7 @@ const SMTPResponse::responseLine SMTPResponse::getNextResponse()
|
||||
else
|
||||
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
|
||||
{
|
||||
return m_lines[pos];
|
||||
@ -225,8 +260,8 @@ const SMTPResponse::state SMTPResponse::getCurrentState() const
|
||||
|
||||
// SMTPResponse::responseLine
|
||||
|
||||
SMTPResponse::responseLine::responseLine(const int code, const string& text)
|
||||
: m_code(code), m_text(text)
|
||||
SMTPResponse::responseLine::responseLine(const int code, const string& text, const enhancedStatusCode& enhCode)
|
||||
: 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)
|
||||
{
|
||||
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
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -35,6 +35,9 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest)
|
||||
VMIME_TEST(testMultiLineResponseDifferentCode)
|
||||
VMIME_TEST(testIncompleteMultiLineResponse)
|
||||
VMIME_TEST(testNoResponseText)
|
||||
VMIME_TEST(testEnhancedStatusCode)
|
||||
VMIME_TEST(testNoEnhancedStatusCode)
|
||||
VMIME_TEST(testInvalidEnhancedStatusCode)
|
||||
VMIME_TEST_LIST_END
|
||||
|
||||
|
||||
@ -171,6 +174,68 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest)
|
||||
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
|
||||
|
||||
|
@ -60,16 +60,30 @@ public:
|
||||
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. */
|
||||
class responseLine
|
||||
{
|
||||
public:
|
||||
|
||||
responseLine(const int code, const string& text);
|
||||
responseLine(const int code, const string& text, const enhancedStatusCode& enhCode);
|
||||
|
||||
void setCode(const int code);
|
||||
int getCode() const;
|
||||
|
||||
void setEnhancedCode(const enhancedStatusCode& enhCode);
|
||||
const enhancedStatusCode getEnhancedCode() const;
|
||||
|
||||
void setText(const string& text);
|
||||
const string getText() const;
|
||||
|
||||
@ -77,6 +91,7 @@ public:
|
||||
|
||||
int m_code;
|
||||
string m_text;
|
||||
enhancedStatusCode m_enhCode;
|
||||
};
|
||||
|
||||
/** Receive and parse a new SMTP response from the
|
||||
@ -97,6 +112,12 @@ public:
|
||||
*/
|
||||
int getCode() const;
|
||||
|
||||
/** Return the SMTP enhanced status code, if available.
|
||||
*
|
||||
* @return enhanced status code
|
||||
*/
|
||||
const enhancedStatusCode getEnhancedCode() const;
|
||||
|
||||
/** Return the SMTP response text.
|
||||
* The text of each line is concatenated.
|
||||
*
|
||||
@ -140,6 +161,7 @@ private:
|
||||
const responseLine getNextResponse();
|
||||
|
||||
static int extractResponseCode(const string& response);
|
||||
static const enhancedStatusCode extractEnhancedCode(const string& responseText);
|
||||
|
||||
|
||||
std::vector <responseLine> m_lines;
|
||||
|
Loading…
Reference in New Issue
Block a user