E-MailRelay

grequestclient.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 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/// \file grequestclient.cpp
19///
20
21#include "gdef.h"
22#include "gstr.h"
23#include "grequestclient.h"
24
25 GSmtp::RequestClient::RequestClient( GNet::ExceptionSink es , const std::string & key , const std::string & ok ,
26 const GNet::Location & location , unsigned int connect_timeout , unsigned int response_timeout ) :
27 GNet::Client(es,location,netConfig(connect_timeout,response_timeout)) ,
28 m_eol(1U,'\n') ,
29 m_key(key) ,
30 m_ok(ok) ,
31 m_timer(*this,&RequestClient::onTimeout,es)
32{
33 G_DEBUG( "GSmtp::RequestClient::ctor: " << location.displayString() << ": "
34 << connect_timeout << " " << response_timeout ) ;
35}
36
37 GNet::Client::Config GSmtp::RequestClient::netConfig( unsigned int connection_timeout , unsigned int response_timeout )
38{
39 GNet::Client::Config net_config( GNet::LineBufferConfig::newline() ) ;
40 net_config.connection_timeout = connection_timeout ;
41 net_config.response_timeout = response_timeout ;
42 return net_config ;
43}
44
45 void GSmtp::RequestClient::onConnect()
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 & request_payload )
53{
54 G_DEBUG( "GSmtp::RequestClient::request: \"" << request_payload << "\"" ) ;
55 if( busy() )
56 throw ProtocolError() ;
57
58 m_request = request_payload ;
59 m_timer.startTimer( 0U ) ;
60
61 // clear the base-class line buffer of any incomplete line
62 // data from a previous request -- this is racy for servers
63 // which incorrectly reply with more than one line
64 clearInput() ;
65}
66
67 void GSmtp::RequestClient::onTimeout()
68{
69 if( connected() )
70 send( requestLine(m_request) ) ;
71}
72
73 bool GSmtp::RequestClient::busy() const
74{
75 return !m_request.empty() ;
76}
77
78 void GSmtp::RequestClient::onDelete( const std::string & reason )
79{
80 if( !reason.empty() )
81 G_WARNING( "GSmtp::RequestClient::onDelete: error: " << reason ) ;
82}
83
84 void GSmtp::RequestClient::onSecure( const std::string & , const std::string & , const std::string & )
85{
86}
87
88 bool GSmtp::RequestClient::onReceive( const char * line_data , std::size_t line_size , std::size_t ,
89 std::size_t , char )
90{
91 std::string line( line_data , line_size ) ;
92 G_DEBUG( "GSmtp::RequestClient::onReceive: [" << G::Str::printable(line) << "]" ) ;
93 if( busy() )
94 {
95 m_request.erase() ;
96 eventSignal().emit( std::string(m_key) , result(line) , std::string() ) ; // empty string if matching m_ok
97 return false ;
98 }
99 else
100 {
101 return true ;
102 }
103}
104
105 void GSmtp::RequestClient::onSendComplete()
106{
107}
108
109std::string GSmtp::RequestClient::requestLine( const std::string & request_payload ) const
110{
111 return request_payload + m_eol ;
112}
113
114std::string GSmtp::RequestClient::result( std::string line ) const
115{
116 G::Str::trimRight( line , "\r" ) ;
117 return !m_ok.empty() && line.find(m_ok) == 0U ? std::string() : line ;
118}
119
GNet::ExceptionSink
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
Definition: gexceptionsink.h:100
GNet::LineBufferConfig::newline
static LineBufferConfig newline()
Convenience factory function.
Definition: glinebuffer.cpp:247
GNet::Location
A class that represents the remote target for out-going client connections.
Definition: glocation.h:71
GNet::Location::displayString
std::string displayString() const
Returns a string representation for logging and debug.
Definition: glocation.cpp:182
GSmtp::Client
A class which acts as an SMTP client, extracting messages from a message store and forwarding them to...
Definition: gsmtpclient.h:54
GSmtp::RequestClient
A network client class that interacts with a remote server using a stateless line-based request/respo...
Definition: grequestclient.h:47
GSmtp::RequestClient::busy
bool busy() const
Returns true after request() and before the subsequent event signal.
Definition: grequestclient.cpp:73
GSmtp::RequestClient::RequestClient
RequestClient(GNet::ExceptionSink, 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:25
GSmtp::RequestClient::request
void request(const std::string &)
Issues a request.
Definition: grequestclient.cpp:52
G::Str::trimRight
static std::string & trimRight(std::string &s, string_view ws, std::size_t limit=0U)
Trims the rhs of s, taking off up to 'limit' of the 'ws' characters.
Definition: gstr.cpp:347
G::Str::printable
static std::string printable(const std::string &in, char escape='\\')
Returns a printable representation of the given input string, using chacter code ranges 0x20 to 0x7e ...
Definition: gstr.cpp:885
grequestclient.h
gstr.h
GNet
Network classes.
Definition: gdef.h:1115
GNet::Client::Config
A structure containing GNet::Client configuration parameters.
Definition: gclient.h:84