E-MailRelay

gserverpeer.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 gserverpeer.cpp
19///
20
21#include "gdef.h"
22#include "gserver.h"
23#include "gmonitor.h"
24#include "glog.h"
25#include "gassert.h"
26#include <sstream>
27
28 GNet::ServerPeer::ServerPeer( ExceptionSink es , const ServerPeerInfo & peer_info ,
29 const LineBufferConfig & line_buffer_config ) :
30 m_address(peer_info.m_address) ,
31 m_socket(peer_info.m_socket) ,
32 m_sp(*this,es,*this,*m_socket,0U) ,
33 m_line_buffer(line_buffer_config) ,
34 m_config(peer_info.m_config) ,
35 m_idle_timer(*this,&ServerPeer::onIdleTimeout,es)
36{
37 G_ASSERT( peer_info.m_server != nullptr ) ;
38 G_ASSERT( m_socket.get() ) ;
39 //G_ASSERT( es.esrc() != nullptr ) ; // moot
40 G_DEBUG( "GNet::ServerPeer::ctor: [" << this << "]: port " << m_address.port() ) ;
41
42 if( m_config.idle_timeout )
43 m_idle_timer.startTimer( m_config.idle_timeout ) ;
44
45 m_socket->addReadHandler( *this , es ) ;
46 m_socket->addOtherHandler( *this , es ) ;
47 Monitor::addServerPeer( *this ) ;
48}
49
50 GNet::ServerPeer::~ServerPeer()
51{
52 G_DEBUG( "GNet::ServerPeer::dtor: [" << this << "]: port " << m_address.port() ) ;
53 Monitor::removeServerPeer( *this ) ;
54}
55
56 void GNet::ServerPeer::secureAccept()
57{
58 m_sp.secureAccept() ;
59}
60
61 void GNet::ServerPeer::expect( std::size_t n )
62{
63 m_line_buffer.expect( n ) ;
64}
65
66 GNet::StreamSocket & GNet::ServerPeer::socket()
67{
68 G_ASSERT( m_socket != nullptr ) ;
69 return *m_socket ;
70}
71
72 void GNet::ServerPeer::otherEvent( EventHandler::Reason reason )
73{
74 m_sp.otherEvent( reason ) ;
75}
76
77 void GNet::ServerPeer::readEvent()
78{
79 m_sp.readEvent() ;
80}
81
82std::pair<bool,GNet::Address> GNet::ServerPeer::localAddress() const
83{
84 G_ASSERT( m_socket != nullptr ) ;
85 return std::make_pair( true , m_socket->getLocalAddress() ) ;
86}
87
88std::pair<bool,GNet::Address> GNet::ServerPeer::peerAddress() const
89{
90 return std::pair<bool,Address>( true , m_address ) ;
91}
92
93std::string GNet::ServerPeer::connectionState() const
94{
95 return m_address.displayString() ;
96}
97
98std::string GNet::ServerPeer::peerCertificate() const
99{
100 return m_sp.peerCertificate() ;
101}
102
103 bool GNet::ServerPeer::send( const std::string & data , std::string::size_type offset )
104{
105 return m_sp.send( data , offset ) ;
106}
107
108 bool GNet::ServerPeer::send( const std::vector<G::string_view> & segments )
109{
110 return m_sp.send( segments ) ;
111}
112
113 void GNet::ServerPeer::writeEvent()
114{
115 if( m_sp.writeEvent() )
116 onSendComplete() ;
117}
118
119 void GNet::ServerPeer::doOnDelete( const std::string & reason , bool done )
120{
121 G_DEBUG( "GNet::ServerPeer::doOnDelete: reason=[" << reason << "]" ) ;
122 onDelete( done ? std::string() : reason ) ;
123}
124
125 void GNet::ServerPeer::onIdleTimeout()
126{
127 std::ostringstream ss ;
128 ss << "no activity after " << m_config.idle_timeout << "s" ;
129 throw IdleTimeout( ss.str() ) ;
130}
131
132 void GNet::ServerPeer::onData( const char * data , std::size_t size )
133{
134 if( m_config.idle_timeout )
135 m_idle_timer.startTimer( m_config.idle_timeout ) ;
136
137 bool fragments = m_line_buffer.transparent() ;
138 m_line_buffer.apply( this , &ServerPeer::onDataImp , data , size , fragments ) ;
139}
140
141 bool GNet::ServerPeer::onDataImp( const char * data , std::size_t size , std::size_t eolsize ,
142 std::size_t linesize , char c0 )
143{
144 return onReceive( data , size , eolsize , linesize , c0 ) ;
145}
146
147 GNet::LineBufferState GNet::ServerPeer::lineBuffer() const
148{
149 return LineBufferState( m_line_buffer ) ;
150}
151
152std::string GNet::ServerPeer::exceptionSourceId() const
153{
154 if( m_exception_source_id.empty() )
155 {
156 std::pair<bool,Address> pair = peerAddress() ; // GNet::Connection
157 if( pair.first )
158 m_exception_source_id = pair.second.hostPartString() ;
159 }
160 return m_exception_source_id ;
161}
162
163// ==
164
165GNet::ServerPeerConfig::ServerPeerConfig()
166= default;
167
168GNet::ServerPeerConfig::ServerPeerConfig( unsigned int idle_timeout_in ) :
169 idle_timeout(idle_timeout_in)
170{
171}
172
173 GNet::ServerPeerConfig & GNet::ServerPeerConfig::set_idle_timeout( unsigned int t )
174{
175 idle_timeout = t ;
176 return *this ;
177}
178
GNet::Address::port
unsigned int port() const
Returns port part of the address.
Definition: gaddress.cpp:452
GNet::ExceptionSink
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
Definition: gexceptionsink.h:100
GNet::LineBufferConfig
A configuration structure for GNet::LineBuffer.
Definition: glinebuffer.h:325
GNet::LineBufferState
Provides information abount the state of a line buffer.
Definition: glinebuffer.h:383
GNet::Monitor::addServerPeer
static void addServerPeer(const Connection &server_peer)
Adds a server connection.
Definition: gmonitor.cpp:126
GNet::Monitor::removeServerPeer
static void removeServerPeer(const Connection &server_peer) noexcept
Removes a server connection.
Definition: gmonitor.cpp:136
GNet::ServerPeerConfig
A structure that GNet::Server uses to configure its ServerPeer objects.
Definition: gserverpeer.h:51
GNet::ServerPeerInfo
A structure used in GNet::Server::newPeer().
Definition: gserver.h:142
GNet::ServerPeer
An abstract base class for the GNet::Server's connection to a remote client.
Definition: gserverpeer.h:68
GNet::ServerPeer::expect
void expect(std::size_t)
Modifies the line buffer state so that it delivers a chunk of non-line-delimited data.
Definition: gserverpeer.cpp:61
GNet::ServerPeer::~ServerPeer
~ServerPeer() override
Destructor.
Definition: gserverpeer.cpp:50
GNet::ServerPeer::secureAccept
void secureAccept()
Waits for the peer to start a secure session.
Definition: gserverpeer.cpp:56
GNet::ServerPeer::connectionState
std::string connectionState() const override
Returns the connection state display string.
Definition: gserverpeer.cpp:93
GNet::ServerPeer::send
bool send(const std::string &data, std::size_t offset=0U)
Sends data down the socket to the peer.
GNet::ServerPeer::doOnDelete
void doOnDelete(const std::string &reason, bool done)
Used by the Server class to call onDelete().
Definition: gserverpeer.cpp:119
GNet::ServerPeer::lineBuffer
LineBufferState lineBuffer() const
Returns information about the state of the internal line-buffer.
Definition: gserverpeer.cpp:147
GNet::ServerPeer::peerAddress
std::pair< bool, Address > peerAddress() const override
Returns the peer address.
Definition: gserverpeer.cpp:88
GNet::ServerPeer::peerCertificate
std::string peerCertificate() const override
Returns the peer's TLS certificate.
Definition: gserverpeer.cpp:98
GNet::ServerPeer::localAddress
std::pair< bool, Address > localAddress() const override
Returns the local address.
Definition: gserverpeer.cpp:82
GNet::ServerPeer::socket
StreamSocket & socket()
Returns a reference to the client-server connection socket.
Definition: gserverpeer.cpp:66
GNet::ServerPeer::onData
void onData(const char *, std::size_t) override
Override from GNet::SocketProtocolSink.
Definition: gserverpeer.cpp:132
GNet::ServerPeer::ServerPeer
ServerPeer(ExceptionSink, const ServerPeerInfo &, const LineBufferConfig &)
Constructor.
Definition: gserverpeer.cpp:28
GNet::StreamSocket
A derivation of GNet::Socket for a stream socket.
Definition: gsocket.h:311
gassert.h
glog.h
gmonitor.h
gserver.h