Added SMTPResponse to read and parse SMTP responses.
This commit is contained in:
parent
790ad36e51
commit
9dcc78085a
@ -233,6 +233,7 @@ libvmime_messaging_proto_sources = [
|
|||||||
[
|
[
|
||||||
'smtp',
|
'smtp',
|
||||||
[
|
[
|
||||||
|
'net/smtp/SMTPResponse.cpp', 'net/smtp/SMTPResponse.hpp',
|
||||||
'net/smtp/SMTPServiceInfos.cpp', 'net/smtp/SMTPServiceInfos.hpp',
|
'net/smtp/SMTPServiceInfos.cpp', 'net/smtp/SMTPServiceInfos.hpp',
|
||||||
'net/smtp/SMTPTransport.cpp', 'net/smtp/SMTPTransport.hpp',
|
'net/smtp/SMTPTransport.cpp', 'net/smtp/SMTPTransport.hpp',
|
||||||
'net/smtp/SMTPSTransport.cpp', 'net/smtp/SMTPSTransport.hpp'
|
'net/smtp/SMTPSTransport.cpp', 'net/smtp/SMTPSTransport.hpp'
|
||||||
|
242
src/net/smtp/SMTPResponse.cpp
Normal file
242
src/net/smtp/SMTPResponse.cpp
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
//
|
||||||
|
// VMime library (http://www.vmime.org)
|
||||||
|
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// Linking this library statically or dynamically with other modules is making
|
||||||
|
// a combined work based on this library. Thus, the terms and conditions of
|
||||||
|
// the GNU General Public License cover the whole combination.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "vmime/net/smtp/SMTPResponse.hpp"
|
||||||
|
|
||||||
|
#include "vmime/platformDependant.hpp"
|
||||||
|
#include "vmime/utility/stringUtils.hpp"
|
||||||
|
|
||||||
|
#include "vmime/net/socket.hpp"
|
||||||
|
#include "vmime/net/timeoutHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace vmime {
|
||||||
|
namespace net {
|
||||||
|
namespace smtp {
|
||||||
|
|
||||||
|
|
||||||
|
SMTPResponse::SMTPResponse(ref <socket> sok, ref <timeoutHandler> toh)
|
||||||
|
: m_socket(sok), m_timeoutHandler(toh),
|
||||||
|
m_responseContinues(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SMTPResponse::SMTPResponse(const SMTPResponse&)
|
||||||
|
: vmime::object()
|
||||||
|
{
|
||||||
|
// Not used
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int SMTPResponse::getCode() const
|
||||||
|
{
|
||||||
|
const int firstCode = m_lines[0].getCode();
|
||||||
|
|
||||||
|
for (unsigned int i = 1 ; i < m_lines.size() ; ++i)
|
||||||
|
{
|
||||||
|
// All response codes returned must be equal
|
||||||
|
// or else this in an error...
|
||||||
|
if (m_lines[i].getCode() != firstCode)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string SMTPResponse::getText() const
|
||||||
|
{
|
||||||
|
string text = m_lines[0].getText();
|
||||||
|
|
||||||
|
for (unsigned int i = 1 ; i < m_lines.size() ; ++i)
|
||||||
|
{
|
||||||
|
text += '\n';
|
||||||
|
text += m_lines[i].getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
ref <SMTPResponse> SMTPResponse::readResponse
|
||||||
|
(ref <socket> sok, ref <timeoutHandler> toh)
|
||||||
|
{
|
||||||
|
ref <SMTPResponse> resp = vmime::create <SMTPResponse>(sok, toh);
|
||||||
|
|
||||||
|
resp->readResponse();
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SMTPResponse::readResponse()
|
||||||
|
{
|
||||||
|
responseLine line = getNextResponse();
|
||||||
|
m_lines.push_back(line);
|
||||||
|
|
||||||
|
while (m_responseContinues)
|
||||||
|
{
|
||||||
|
line = getNextResponse();
|
||||||
|
m_lines.push_back(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string SMTPResponse::readResponseLine()
|
||||||
|
{
|
||||||
|
string currentBuffer = m_responseBuffer;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// Get a line from the response buffer
|
||||||
|
string::size_type lineEnd = currentBuffer.find_first_of('\n');
|
||||||
|
|
||||||
|
if (lineEnd != string::npos)
|
||||||
|
{
|
||||||
|
const string line(currentBuffer.begin(), currentBuffer.begin() + lineEnd);
|
||||||
|
|
||||||
|
currentBuffer.erase(currentBuffer.begin(), currentBuffer.begin() + lineEnd + 1);
|
||||||
|
m_responseBuffer = currentBuffer;
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the time-out delay is elapsed
|
||||||
|
if (m_timeoutHandler && m_timeoutHandler->isTimeOut())
|
||||||
|
{
|
||||||
|
if (!m_timeoutHandler->handleTimeOut())
|
||||||
|
throw exceptions::operation_timed_out();
|
||||||
|
|
||||||
|
m_timeoutHandler->resetTimeOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive data from the socket
|
||||||
|
string receiveBuffer;
|
||||||
|
m_socket->receive(receiveBuffer);
|
||||||
|
|
||||||
|
if (receiveBuffer.empty()) // buffer is empty
|
||||||
|
{
|
||||||
|
platformDependant::getHandler()->wait();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentBuffer += receiveBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const SMTPResponse::responseLine SMTPResponse::getNextResponse()
|
||||||
|
{
|
||||||
|
string line = readResponseLine();
|
||||||
|
|
||||||
|
// Special case where CRLF occurs after response code
|
||||||
|
if (line.length() < 4)
|
||||||
|
line = line + '\n' + readResponseLine();
|
||||||
|
|
||||||
|
const int code = extractResponseCode(line);
|
||||||
|
string text;
|
||||||
|
|
||||||
|
m_responseContinues = (line.length() >= 4 && line[3] == '-');
|
||||||
|
|
||||||
|
if (line.length() > 4)
|
||||||
|
text = utility::stringUtils::trim(line.substr(4));
|
||||||
|
else
|
||||||
|
text = utility::stringUtils::trim(line);
|
||||||
|
|
||||||
|
return responseLine(code, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
const int SMTPResponse::extractResponseCode(const string& response)
|
||||||
|
{
|
||||||
|
int code = 0;
|
||||||
|
|
||||||
|
if (response.length() >= 3)
|
||||||
|
{
|
||||||
|
code = (response[0] - '0') * 100
|
||||||
|
+ (response[1] - '0') * 10
|
||||||
|
+ (response[2] - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const SMTPResponse::responseLine SMTPResponse::getLineAt(const unsigned int pos) const
|
||||||
|
{
|
||||||
|
return m_lines[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const unsigned int SMTPResponse::getLineCount() const
|
||||||
|
{
|
||||||
|
return m_lines.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const SMTPResponse::responseLine SMTPResponse::getLastLine() const
|
||||||
|
{
|
||||||
|
return m_lines[m_lines.size() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// SMTPResponse::responseLine
|
||||||
|
|
||||||
|
SMTPResponse::responseLine::responseLine(const int code, const string& text)
|
||||||
|
: m_code(code), m_text(text)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SMTPResponse::responseLine::setCode(const int code)
|
||||||
|
{
|
||||||
|
m_code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int SMTPResponse::responseLine::getCode() const
|
||||||
|
{
|
||||||
|
return m_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SMTPResponse::responseLine::setText(const string& text)
|
||||||
|
{
|
||||||
|
m_text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string SMTPResponse::responseLine::getText() const
|
||||||
|
{
|
||||||
|
return m_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // smtp
|
||||||
|
} // net
|
||||||
|
} // vmime
|
||||||
|
|
@ -18,6 +18,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "vmime/net/smtp/SMTPTransport.hpp"
|
#include "vmime/net/smtp/SMTPTransport.hpp"
|
||||||
|
#include "vmime/net/smtp/SMTPResponse.hpp"
|
||||||
|
|
||||||
#include "vmime/exception.hpp"
|
#include "vmime/exception.hpp"
|
||||||
#include "vmime/platformDependant.hpp"
|
#include "vmime/platformDependant.hpp"
|
||||||
@ -110,19 +111,17 @@ void SMTPTransport::connect()
|
|||||||
|
|
||||||
m_socket->connect(address, port);
|
m_socket->connect(address, port);
|
||||||
|
|
||||||
m_responseBuffer.clear();
|
|
||||||
|
|
||||||
// Connection
|
// Connection
|
||||||
//
|
//
|
||||||
// eg: C: <connection to server>
|
// eg: C: <connection to server>
|
||||||
// --- S: 220 smtp.domain.com Service ready
|
// --- S: 220 smtp.domain.com Service ready
|
||||||
|
|
||||||
string response;
|
ref <SMTPResponse> resp;
|
||||||
|
|
||||||
if (readAllResponses(response) != 220)
|
if ((resp = readResponse())->getCode() != 220)
|
||||||
{
|
{
|
||||||
internalDisconnect();
|
internalDisconnect();
|
||||||
throw exceptions::connection_greeting_error(response);
|
throw exceptions::connection_greeting_error(resp->getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identification
|
// Identification
|
||||||
@ -134,7 +133,7 @@ void SMTPTransport::connect()
|
|||||||
|
|
||||||
sendRequest("EHLO " + platformDependant::getHandler()->getHostName());
|
sendRequest("EHLO " + platformDependant::getHandler()->getHostName());
|
||||||
|
|
||||||
if (readAllResponses(response, true) != 250)
|
if ((resp = readResponse())->getCode() != 250)
|
||||||
{
|
{
|
||||||
// Next, try "Basic" SMTP
|
// Next, try "Basic" SMTP
|
||||||
//
|
//
|
||||||
@ -143,10 +142,10 @@ void SMTPTransport::connect()
|
|||||||
|
|
||||||
sendRequest("HELO " + platformDependant::getHandler()->getHostName());
|
sendRequest("HELO " + platformDependant::getHandler()->getHostName());
|
||||||
|
|
||||||
if (readAllResponses(response) != 250)
|
if ((resp = readResponse())->getCode() != 250)
|
||||||
{
|
{
|
||||||
internalDisconnect();
|
internalDisconnect();
|
||||||
throw exceptions::connection_greeting_error(response);
|
throw exceptions::connection_greeting_error(resp->getLastLine().getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_extendedSMTP = false;
|
m_extendedSMTP = false;
|
||||||
@ -154,7 +153,7 @@ void SMTPTransport::connect()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_extendedSMTP = true;
|
m_extendedSMTP = true;
|
||||||
m_extendedSMTPResponse = response;
|
m_extendedSMTPResponse = resp->getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if VMIME_HAVE_TLS_SUPPORT
|
#if VMIME_HAVE_TLS_SUPPORT
|
||||||
@ -335,9 +334,9 @@ void SMTPTransport::authenticateSASL()
|
|||||||
|
|
||||||
for (bool cont = true ; cont ; )
|
for (bool cont = true ; cont ; )
|
||||||
{
|
{
|
||||||
string response;
|
ref <SMTPResponse> response = readResponse();
|
||||||
|
|
||||||
switch (readAllResponses(response))
|
switch (response->getCode())
|
||||||
{
|
{
|
||||||
case 235:
|
case 235:
|
||||||
{
|
{
|
||||||
@ -355,7 +354,7 @@ void SMTPTransport::authenticateSASL()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Extract challenge
|
// Extract challenge
|
||||||
saslContext->decodeB64(response, &challenge, &challengeLen);
|
saslContext->decodeB64(response->getText(), &challenge, &challengeLen);
|
||||||
|
|
||||||
// Prepare response
|
// Prepare response
|
||||||
saslSession->evaluateChallenge
|
saslSession->evaluateChallenge
|
||||||
@ -423,10 +422,10 @@ void SMTPTransport::startTLS()
|
|||||||
{
|
{
|
||||||
sendRequest("STARTTLS");
|
sendRequest("STARTTLS");
|
||||||
|
|
||||||
string response;
|
ref <SMTPResponse> resp = readResponse();
|
||||||
|
|
||||||
if (readAllResponses(response) != 220)
|
if (resp->getCode() != 220)
|
||||||
throw exceptions::command_error("STARTTLS", response);
|
throw exceptions::command_error("STARTTLS", resp->getText());
|
||||||
|
|
||||||
ref <tls::TLSSession> tlsSession =
|
ref <tls::TLSSession> tlsSession =
|
||||||
vmime::create <tls::TLSSession>(getCertificateVerifier());
|
vmime::create <tls::TLSSession>(getCertificateVerifier());
|
||||||
@ -494,10 +493,10 @@ void SMTPTransport::noop()
|
|||||||
{
|
{
|
||||||
sendRequest("NOOP");
|
sendRequest("NOOP");
|
||||||
|
|
||||||
string response;
|
ref <SMTPResponse> resp = readResponse();
|
||||||
|
|
||||||
if (readAllResponses(response) != 250)
|
if (resp->getCode() != 250)
|
||||||
throw exceptions::command_error("NOOP", response);
|
throw exceptions::command_error("NOOP", resp->getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -512,14 +511,14 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients
|
|||||||
throw exceptions::no_expeditor();
|
throw exceptions::no_expeditor();
|
||||||
|
|
||||||
// Emit the "MAIL" command
|
// Emit the "MAIL" command
|
||||||
string response;
|
ref <SMTPResponse> resp;
|
||||||
|
|
||||||
sendRequest("MAIL FROM: <" + expeditor.getEmail() + ">");
|
sendRequest("MAIL FROM: <" + expeditor.getEmail() + ">");
|
||||||
|
|
||||||
if (readAllResponses(response) != 250)
|
if ((resp = readResponse())->getCode() != 250)
|
||||||
{
|
{
|
||||||
internalDisconnect();
|
internalDisconnect();
|
||||||
throw exceptions::command_error("MAIL", response);
|
throw exceptions::command_error("MAIL", resp->getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit a "RCPT TO" command for each recipient
|
// Emit a "RCPT TO" command for each recipient
|
||||||
@ -529,20 +528,20 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients
|
|||||||
|
|
||||||
sendRequest("RCPT TO: <" + mbox.getEmail() + ">");
|
sendRequest("RCPT TO: <" + mbox.getEmail() + ">");
|
||||||
|
|
||||||
if (readAllResponses(response) != 250)
|
if ((resp = readResponse())->getCode() != 250)
|
||||||
{
|
{
|
||||||
internalDisconnect();
|
internalDisconnect();
|
||||||
throw exceptions::command_error("RCPT TO", response);
|
throw exceptions::command_error("RCPT TO", resp->getText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the message data
|
// Send the message data
|
||||||
sendRequest("DATA");
|
sendRequest("DATA");
|
||||||
|
|
||||||
if (readAllResponses(response) != 354)
|
if ((resp = readResponse())->getCode() != 354)
|
||||||
{
|
{
|
||||||
internalDisconnect();
|
internalDisconnect();
|
||||||
throw exceptions::command_error("DATA", response);
|
throw exceptions::command_error("DATA", resp->getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream copy with "\n." to "\n.." transformation
|
// Stream copy with "\n." to "\n.." transformation
|
||||||
@ -556,10 +555,10 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients
|
|||||||
// Send end-of-data delimiter
|
// Send end-of-data delimiter
|
||||||
m_socket->sendRaw("\r\n.\r\n", 5);
|
m_socket->sendRaw("\r\n.\r\n", 5);
|
||||||
|
|
||||||
if (readAllResponses(response) != 250)
|
if ((resp = readResponse())->getCode() != 250)
|
||||||
{
|
{
|
||||||
internalDisconnect();
|
internalDisconnect();
|
||||||
throw exceptions::command_error("DATA", response);
|
throw exceptions::command_error("DATA", resp->getText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,114 +570,9 @@ void SMTPTransport::sendRequest(const string& buffer, const bool end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int SMTPTransport::getResponseCode(const string& response)
|
ref <SMTPResponse> SMTPTransport::readResponse()
|
||||||
{
|
{
|
||||||
int code = 0;
|
return SMTPResponse::readResponse(m_socket, m_timeoutHandler);
|
||||||
|
|
||||||
if (response.length() >= 3)
|
|
||||||
{
|
|
||||||
code = (response[0] - '0') * 100
|
|
||||||
+ (response[1] - '0') * 10
|
|
||||||
+ (response[2] - '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
return (code);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const string SMTPTransport::readResponseLine()
|
|
||||||
{
|
|
||||||
string currentBuffer = m_responseBuffer;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// Get a line from the response buffer
|
|
||||||
string::size_type lineEnd = currentBuffer.find_first_of('\n');
|
|
||||||
|
|
||||||
if (lineEnd != string::npos)
|
|
||||||
{
|
|
||||||
const string line(currentBuffer.begin(), currentBuffer.begin() + lineEnd);
|
|
||||||
|
|
||||||
currentBuffer.erase(currentBuffer.begin(), currentBuffer.begin() + lineEnd + 1);
|
|
||||||
m_responseBuffer = currentBuffer;
|
|
||||||
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether the time-out delay is elapsed
|
|
||||||
if (m_timeoutHandler && m_timeoutHandler->isTimeOut())
|
|
||||||
{
|
|
||||||
if (!m_timeoutHandler->handleTimeOut())
|
|
||||||
throw exceptions::operation_timed_out();
|
|
||||||
|
|
||||||
m_timeoutHandler->resetTimeOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive data from the socket
|
|
||||||
string receiveBuffer;
|
|
||||||
m_socket->receive(receiveBuffer);
|
|
||||||
|
|
||||||
if (receiveBuffer.empty()) // buffer is empty
|
|
||||||
{
|
|
||||||
platformDependant::getHandler()->wait();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentBuffer += receiveBuffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const int SMTPTransport::readResponse(string& text)
|
|
||||||
{
|
|
||||||
string line = readResponseLine();
|
|
||||||
|
|
||||||
// Special case where CRLF occurs after response code
|
|
||||||
if (line.length() < 4)
|
|
||||||
line = line + '\n' + readResponseLine();
|
|
||||||
|
|
||||||
const int code = getResponseCode(line);
|
|
||||||
|
|
||||||
m_responseContinues = (line.length() >= 4 && line[3] == '-');
|
|
||||||
|
|
||||||
if (line.length() > 4)
|
|
||||||
text = utility::stringUtils::trim(line.substr(4));
|
|
||||||
else
|
|
||||||
text = utility::stringUtils::trim(line);
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const int SMTPTransport::readAllResponses(string& outText, const bool allText)
|
|
||||||
{
|
|
||||||
string text;
|
|
||||||
|
|
||||||
const int firstCode = readResponse(outText);
|
|
||||||
|
|
||||||
if (allText)
|
|
||||||
text = outText;
|
|
||||||
|
|
||||||
while (m_responseContinues)
|
|
||||||
{
|
|
||||||
const int code = readResponse(outText);
|
|
||||||
|
|
||||||
if (allText)
|
|
||||||
text += '\n' + outText;
|
|
||||||
|
|
||||||
if (code != firstCode)
|
|
||||||
{
|
|
||||||
if (allText)
|
|
||||||
outText = text;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allText)
|
|
||||||
outText = text;
|
|
||||||
|
|
||||||
return firstCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
142
vmime/net/smtp/SMTPResponse.hpp
Normal file
142
vmime/net/smtp/SMTPResponse.hpp
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
//
|
||||||
|
// VMime library (http://www.vmime.org)
|
||||||
|
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// Linking this library statically or dynamically with other modules is making
|
||||||
|
// a combined work based on this library. Thus, the terms and conditions of
|
||||||
|
// the GNU General Public License cover the whole combination.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef VMIME_NET_SMTP_SMTPRESPONSE_HPP_INCLUDED
|
||||||
|
#define VMIME_NET_SMTP_SMTPRESPONSE_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "vmime/object.hpp"
|
||||||
|
#include "vmime/base.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace vmime {
|
||||||
|
namespace net {
|
||||||
|
|
||||||
|
|
||||||
|
class socket;
|
||||||
|
class timeoutHandler;
|
||||||
|
|
||||||
|
|
||||||
|
namespace smtp {
|
||||||
|
|
||||||
|
|
||||||
|
/** A SMTP response, as sent by the server.
|
||||||
|
*/
|
||||||
|
class SMTPResponse : public object
|
||||||
|
{
|
||||||
|
friend class creator;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** An element of a SMTP response. */
|
||||||
|
class responseLine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
responseLine(const int code, const string& text);
|
||||||
|
|
||||||
|
void setCode(const int code);
|
||||||
|
const int getCode() const;
|
||||||
|
|
||||||
|
void setText(const string& text);
|
||||||
|
const string getText() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int m_code;
|
||||||
|
string m_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Receive and parse a new SMTP response from the
|
||||||
|
* specified socket.
|
||||||
|
*
|
||||||
|
* @param sok socket from which to read
|
||||||
|
* @param toh time-out handler
|
||||||
|
* @return SMTP response
|
||||||
|
* @throws exceptions::operation_timed_out if no data
|
||||||
|
* has been received within the granted time
|
||||||
|
*/
|
||||||
|
static ref <SMTPResponse> readResponse(ref <socket> sok, ref <timeoutHandler> toh);
|
||||||
|
|
||||||
|
/** Return the SMTP response code.
|
||||||
|
*
|
||||||
|
* @return response code
|
||||||
|
*/
|
||||||
|
const int getCode() const;
|
||||||
|
|
||||||
|
/** Return the SMTP response text.
|
||||||
|
* The text of each line is concatenated.
|
||||||
|
*
|
||||||
|
* @return response text
|
||||||
|
*/
|
||||||
|
const string getText() const;
|
||||||
|
|
||||||
|
/** Return the response line at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos line index
|
||||||
|
* @return line at the specified index
|
||||||
|
*/
|
||||||
|
const responseLine getLineAt(const unsigned int pos) const;
|
||||||
|
|
||||||
|
/** Return the number of lines in the response.
|
||||||
|
*
|
||||||
|
* @return number of lines in the response
|
||||||
|
*/
|
||||||
|
const unsigned int getLineCount() const;
|
||||||
|
|
||||||
|
/** Return the last line in the response.
|
||||||
|
*
|
||||||
|
* @return last response line
|
||||||
|
*/
|
||||||
|
const responseLine getLastLine() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SMTPResponse(ref <socket> sok, ref <timeoutHandler> toh);
|
||||||
|
SMTPResponse(const SMTPResponse&);
|
||||||
|
|
||||||
|
void readResponse();
|
||||||
|
|
||||||
|
const string readResponseLine();
|
||||||
|
const responseLine getNextResponse();
|
||||||
|
|
||||||
|
static const int extractResponseCode(const string& response);
|
||||||
|
|
||||||
|
|
||||||
|
std::vector <responseLine> m_lines;
|
||||||
|
|
||||||
|
ref <socket> m_socket;
|
||||||
|
ref <timeoutHandler> m_timeoutHandler;
|
||||||
|
|
||||||
|
string m_responseBuffer;
|
||||||
|
bool m_responseContinues;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // smtp
|
||||||
|
} // net
|
||||||
|
} // vmime
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VMIME_NET_SMTP_SMTPRESPONSE_HPP_INCLUDED
|
||||||
|
|
@ -39,6 +39,9 @@ namespace net {
|
|||||||
namespace smtp {
|
namespace smtp {
|
||||||
|
|
||||||
|
|
||||||
|
class SMTPResponse;
|
||||||
|
|
||||||
|
|
||||||
/** SMTP transport service.
|
/** SMTP transport service.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -64,13 +67,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static const int getResponseCode(const string& response);
|
|
||||||
|
|
||||||
void sendRequest(const string& buffer, const bool end = true);
|
void sendRequest(const string& buffer, const bool end = true);
|
||||||
|
ref <SMTPResponse> readResponse();
|
||||||
const string readResponseLine();
|
|
||||||
const int readResponse(string& text);
|
|
||||||
const int readAllResponses(string& text, const bool allText = false);
|
|
||||||
|
|
||||||
void internalDisconnect();
|
void internalDisconnect();
|
||||||
|
|
||||||
@ -89,9 +87,6 @@ private:
|
|||||||
bool m_extendedSMTP;
|
bool m_extendedSMTP;
|
||||||
string m_extendedSMTPResponse;
|
string m_extendedSMTPResponse;
|
||||||
|
|
||||||
string m_responseBuffer;
|
|
||||||
bool m_responseContinues;
|
|
||||||
|
|
||||||
ref <timeoutHandler> m_timeoutHandler;
|
ref <timeoutHandler> m_timeoutHandler;
|
||||||
|
|
||||||
bool m_secured;
|
bool m_secured;
|
||||||
|
Loading…
Reference in New Issue
Block a user