E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

grequestclient.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // grequestclient.cpp
19 //
20
21 #include "gdef.h"
22 #include "gsmtp.h"
23 #include "gstr.h"
24 #include "grequestclient.h"
25 #include "gassert.h"
26
27 GSmtp::RequestClient::RequestClient( const std::string & key , const std::string & ok ,
28 const GNet::Location & location , unsigned int connect_timeout , unsigned int response_timeout ) :
29 GNet::Client(location,connect_timeout,response_timeout,0U,config()) ,
30 m_eol(1U,'\n') ,
31 m_key(key) ,
32 m_ok(ok) ,
33 m_timer(*this,&RequestClient::onTimeout,*this)
34 {
35 G_DEBUG( "GSmtp::RequestClient::ctor: " << location.displayString() << ": "
36 << connect_timeout << " " << response_timeout ) ;
37 }
38
39 GSmtp::RequestClient::~RequestClient()
40 {
41 }
42
43 GNet::LineBufferConfig GSmtp::RequestClient::config()
44 {
45 return GNet::LineBufferConfig::newline() ;
46 }
47
48 void GSmtp::RequestClient::onConnect()
49 {
50 G_DEBUG( "GSmtp::RequestClient::onConnect" ) ;
51 if( busy() )
52 send( requestLine(m_request) ) ;
53 }
54
55 void GSmtp::RequestClient::request( const std::string & request_payload )
56 {
57 G_DEBUG( "GSmtp::RequestClient::request: \"" << request_payload << "\"" ) ;
58 if( busy() ) throw ProtocolError() ;
59 m_request = request_payload ;
60 m_timer.startTimer( 0U ) ;
61
62 // clear the base-class line buffer of any incomplete line
63 // data -- but a race condition is possible for servers
64 // which reply with more that one line
65 clearInput() ;
66 }
67
68 void GSmtp::RequestClient::onTimeout()
69 {
70 if( connected() )
71 send( requestLine(m_request) ) ;
72 }
73
74 bool GSmtp::RequestClient::busy() const
75 {
76 return !m_request.empty() ;
77 }
78
79 void GSmtp::RequestClient::onDelete( const std::string & )
80 {
81 }
82
83 void GSmtp::RequestClient::onDeleteImp( const std::string & reason )
84 {
85 // we override onDeleteImp() rather than onDelete() so that
86 // we get to emit our signal before any other signal handler --
87 // consider that they might throw an exception and then we don't
88 // get called -- so this guarantees every request gets a response
89
90 if( !reason.empty() )
91 G_WARNING( "GSmtp::RequestClient::onDeleteImp: error: " << reason ) ;
92
93 if( busy() )
94 {
95 m_request.erase() ;
96 eventSignal().emit( m_key , reason.empty() ? std::string("error") : reason ) ;
97 }
98 GNet::Client::onDeleteImp( reason ) ; // base class
99 }
100
101 void GSmtp::RequestClient::onSecure( const std::string & )
102 {
103 }
104
105 bool GSmtp::RequestClient::onReceive( const char * line_data , size_t line_size , size_t )
106 {
107 std::string line( line_data , line_size ) ;
108 G_DEBUG( "GSmtp::RequestClient::onReceive: [" << G::Str::printable(line) << "]" ) ;
109 if( busy() )
110 {
111 m_request.erase() ;
112 eventSignal().emit( m_key , result(line) ) ; // empty string if matching m_ok
113 }
114 return true ;
115 }
116
117 void GSmtp::RequestClient::onSendComplete()
118 {
119 }
120
121 std::string GSmtp::RequestClient::requestLine( const std::string & request_payload ) const
122 {
123 return request_payload + m_eol ;
124 }
125
126 std::string GSmtp::RequestClient::result( std::string line ) const
127 {
128 G::Str::trimRight( line , "\r" ) ;
129 return !m_ok.empty() && line.find(m_ok) == 0U ? std::string() : line ;
130 }
131
132 /// \file grequestclient.cpp
GNet::LineBufferConfig::newline
static LineBufferConfig newline()
Convenience factory function.
Definition: glinebuffer.cpp:301
G::Str::printable
static std::string printable(const std::string &in, char escape= '\\')
Returns a printable represention of the given input string.
Definition: gstr.cpp:701
GNet
Network classes.
Definition: gaddress.h:29
GNet::Client::onDeleteImp
virtual void onDeleteImp(const std::string &reason) override
Override from GNet::HeapClient.
Definition: gclient.cpp:60
GSmtp::RequestClient::onConnect
virtual void onConnect() override
Override from GNet::SimpleClient.
Definition: grequestclient.cpp:48
GNet::Location::displayString
std::string displayString() const
Returns a string representation for logging and debug.
Definition: glocation.cpp:169
GSmtp::RequestClient::~RequestClient
virtual ~RequestClient()
Destructor.
Definition: grequestclient.cpp:39
GSmtp::RequestClient::onDeleteImp
virtual void onDeleteImp(const std::string &) override
Override from GNet::Client.
Definition: grequestclient.cpp:83
GSmtp::RequestClient::onReceive
virtual bool onReceive(const char *, size_t, size_t) override
Override from GNet::Client.
Definition: grequestclient.cpp:105
GNet::Location
A class that holds a host/service name pair and the preferred address family (if any), and also the results of a name-to-address lookup, ie.
Definition: glocation.h:50
gstr.h
gassert.h
G::Str::trimRight
static void trimRight(std::string &s, const std::string &ws, size_type limit=0U)
Trims the rhs of s, taking off up to 'limit' of the 'ws' characters.
Definition: gstr.cpp:235
GNet::LineBufferConfig
A configuration structure for GNet::LineBuffer.
Definition: glinebuffer.h:174
GSmtp::RequestClient::onSecure
virtual void onSecure(const std::string &) override
Override from GNet::SocketProtocolSink.
Definition: grequestclient.cpp:101
GSmtp::Client
A class which acts as an SMTP client, extracting messages from a message store and forwarding them to...
Definition: gsmtpclient.h:52
GSmtp::RequestClient::onSendComplete
virtual void onSendComplete() override
Override from GNet::BufferedClient.
Definition: grequestclient.cpp:117
GSmtp::RequestClient::request
void request(const std::string &)
Issues a request.
Definition: grequestclient.cpp:55
GSmtp::RequestClient::busy
bool busy() const
Returns true after request() and before the subsequent event signal.
Definition: grequestclient.cpp:74
grequestclient.h
GSmtp::RequestClient::onDelete
virtual void onDelete(const std::string &) override
Override from GNet::HeapClient.
Definition: grequestclient.cpp:79
gsmtp.h
GSmtp::RequestClient::RequestClient
RequestClient(const std::string &key, const std::string &ok, const GNet::Location &host_and_service, unsigned int connect_timeout, unsigned int response_timeout)
Constructor.
Definition: grequestclient.cpp:27
GSmtp::RequestClient
A network client class that interacts with a remote server using a stateless line-based request/respo...
Definition: grequestclient.h:44