grequestclient.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 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 "gnet.h"
23 #include "gsmtp.h"
24 #include "gstr.h"
25 #include "grequestclient.h"
26 #include "gassert.h"
27 
28 GSmtp::RequestClient::RequestClient( const std::string & key , const std::string & ok , const std::string & eol ,
29  const GNet::ResolverInfo & resolver_info ,
30  unsigned int connect_timeout , unsigned int response_timeout ) :
31  GNet::Client(resolver_info,connect_timeout,response_timeout,0U,eol) ,
32  m_key(key) ,
33  m_ok(ok) ,
34  m_eol(eol) ,
35  m_timer(*this,&RequestClient::onTimeout,*this)
36 {
37  G_DEBUG( "GSmtp::RequestClient::ctor: " << resolver_info.displayString() << ": "
38  << connect_timeout << " " << response_timeout ) ;
39 }
40 
42 {
43 }
44 
46 {
47  G_DEBUG( "GSmtp::RequestClient::onConnect" ) ;
48  if( busy() )
49  send( requestLine(m_request) ) ;
50 }
51 
52 void GSmtp::RequestClient::request( const std::string & payload )
53 {
54  G_DEBUG( "GSmtp::RequestClient::request: \"" << payload << "\"" ) ;
55  if( busy() ) throw ProtocolError() ;
56  m_request = payload ;
57  m_timer.startTimer( 0U ) ;
58  clearInput() ; // ... but race condition possible for servers which reply with more that one line
59 }
60 
61 void GSmtp::RequestClient::onTimeout()
62 {
63  if( connected() )
64  send( requestLine(m_request) ) ;
65 }
66 
68 {
69  return !m_request.empty() ;
70 }
71 
72 void GSmtp::RequestClient::onDelete( const std::string & , bool )
73 {
74 }
75 
76 void GSmtp::RequestClient::onDeleteImp( const std::string & reason , bool b )
77 {
78  // we have to override onDeleteImp() rather than onDelete() so that we
79  // can get in early enough to guarantee that every request gets a response
80 
81  if( !reason.empty() )
82  G_WARNING( "GSmtp::RequestClient::onDeleteImp: error: " << reason ) ;
83 
84  if( busy() )
85  {
86  m_request.erase() ;
87  eventSignal().emit( m_key , reason.empty() ? std::string("error") : reason ) ;
88  }
89  Base::onDeleteImp( reason , b ) ; // use typedef because of ms compiler bug
90 }
91 
92 void GSmtp::RequestClient::onSecure( const std::string & )
93 {
94 }
95 
96 bool GSmtp::RequestClient::onReceive( const std::string & line )
97 {
98  G_DEBUG( "GSmtp::RequestClient::onReceive: [" << G::Str::printable(line) << "]" ) ;
99  if( busy() )
100  {
101  m_request.erase() ;
102  std::string scan_result = result(line) ; // empty string if scanned okay
103  scan_result = G::Str::printable( scan_result ) ; // paranoia
104  eventSignal().emit( m_key , scan_result ) ;
105  }
106  return true ;
107 }
108 
110 {
111 }
112 
113 // customisation...
114 
115 std::string GSmtp::RequestClient::requestLine( const std::string & payload ) const
116 {
117  return payload + m_eol ;
118 }
119 
120 std::string GSmtp::RequestClient::result( std::string line ) const
121 {
122  G::Str::trim( line , "\r" ) ;
123  return !m_ok.empty() && line.find(m_ok) == 0U ? std::string() : line ;
124 }
125 
static std::string printable(const std::string &in, char escape= '\\')
Returns a printable represention of the given input string.
Definition: gstr.cpp:507
Network classes.
RequestClient(const std::string &key, const std::string &ok, const std::string &eol, const GNet::ResolverInfo &host_and_service, unsigned int connect_timeout, unsigned int response_timeout)
Constructor.
virtual void onDeleteImp(const std::string &, bool)
Final override from GNet::Client.
A class that holds a host/service name pair and optionally the results of a name-to-address lookup...
Definition: gresolverinfo.h:48
virtual void onConnect()
Final override from GNet::SimpleClient.
static void trim(std::string &s, const std::string &ws)
Trims both ends of s, taking off any of the 'ws' characters.
Definition: gstr.cpp:133
virtual ~RequestClient()
Destructor.
virtual void onDelete(const std::string &, bool)
Final override from GNet::HeapClient.
virtual void onSendComplete()
Final override from GNet::BufferedClient.
virtual void onSecure(const std::string &)
Final override from GNet::SocketProtocolSink.
#define G_DEBUG(expr)
Definition: glog.h:95
A class which acts as an SMTP client, extracting messages from a message store and forwarding them to...
Definition: gsmtpclient.h:55
virtual bool onReceive(const std::string &)
Final override from GNet::Client.
void request(const std::string &)
Issues a request.
bool busy() const
Returns true after request() and before the subsequent event signal.
std::string displayString(bool simple=false) const
Returns a string representation for logging and debug.
A client class that interacts with a remote process with a stateless line-based request/response prot...
#define G_WARNING(expr)
Definition: glog.h:107