36 const std::string & GSmtp::Client::crlf()
38 static const std::string s(
"\015\012" ) ;
43 GNet::
Client(remote,config.connection_timeout,0U,
44 config.secure_connection_timeout,crlf(),config.local_address,false) ,
46 m_processor(
ProcessorFactory::newProcessor(config.processor_address,config.processor_timeout)) ,
47 m_protocol(*this,secrets,config.client_protocol_config) ,
48 m_secure_tunnel(config.secure_tunnel)
52 m_processor->doneSignal().connect(
G::slot(*
this,&Client::preprocessorDone) ) ;
57 m_protocol.doneSignal().disconnect() ;
58 m_protocol.preprocessorSignal().disconnect() ;
59 m_processor->doneSignal().disconnect() ;
64 return m_message_done_signal ;
76 G_ASSERT( m_message.get() == NULL ) ;
80 start( *m_message.get() ) ;
84 bool GSmtp::Client::protocolSend(
const std::string & line ,
size_t offset ,
bool go_secure )
86 bool rc = send( line , offset ) ;
92 void GSmtp::Client::preprocessorStart()
94 G_ASSERT( m_message.get() != NULL ) ;
96 m_processor->start( m_message->location() ) ;
99 void GSmtp::Client::preprocessorDone(
bool ok )
101 G_ASSERT( m_message.get() != NULL ) ;
104 bool ignore_this = !ok && m_processor->cancelled() && !m_processor->repoll() ;
105 bool break_after = !ok && m_processor->cancelled() && m_processor->repoll() ;
107 if( ok || break_after )
112 G_DEBUG(
"GSmtp::Client::preprocessorDone: making this the last message" ) ;
117 m_protocol.preprocessorDone( ok || break_after ,
118 ok || ignore_this || break_after ? std::string() : m_processor->text() ) ;
123 if( m_secure_tunnel )
129 m_protocol.secure() ;
133 void GSmtp::Client::logCertificate(
const std::string & certificate )
135 if( !certificate.empty() )
137 static std::string previous ;
138 if( certificate != previous )
140 previous = certificate ;
143 for( G::Strings::iterator p = lines.begin() ; p != lines.end() ; ++p )
146 G_LOG(
"GSmtp::Client: certificate: " << (*p) ) ;
154 if( m_secure_tunnel )
164 void GSmtp::Client::doOnConnect()
166 if( m_store != NULL )
168 m_iter = m_store->iterator(
true) ;
171 G_DEBUG(
"GSmtp::Client::onConnect: deleting" ) ;
172 doDelete( std::string() ) ;
177 G_ASSERT( m_message.get() != NULL ) ;
178 start( *m_message.get() ) ;
182 bool GSmtp::Client::sendNext()
188 std::auto_ptr<StoredMessage> message( m_iter.next() ) ;
189 if( message.get() == NULL )
191 G_LOG_S(
"GSmtp::Client: no more messages to send" ) ;
194 m_message = message ;
197 start( *m_message.get() ) ;
201 void GSmtp::Client::start( StoredMessage & message )
203 eventSignal().emit(
"sending" , message.name() ) ;
206 std::string server_name = resolverInfo().name() ;
207 if( server_name.empty() )
208 server_name = resolverInfo().host() ;
210 std::auto_ptr<std::istream> content_stream( message.extractContentStream() ) ;
211 m_protocol.start( message.from() , message.to() , message.eightBit() ,
212 message.authentication() , server_name , content_stream ) ;
215 void GSmtp::Client::protocolDone( std::string reason ,
int reason_code )
217 G_DEBUG(
"GSmtp::Client::protocolDone: \"" << reason <<
"\"" ) ;
218 if( ! reason.empty() )
219 reason = std::string(
"smtp client failure: ") + reason ;
223 if( reason_code != 1 )
228 m_processor->abort() ;
229 messageFail( reason , reason_code ) ;
232 if( m_store != NULL )
236 G_DEBUG(
"GSmtp::Client::protocolDone: deleting" ) ;
237 doDelete( std::string() ) ;
242 messageDoneSignal().emit( reason ) ;
246 void GSmtp::Client::messageDestroy()
248 if( m_message.get() != NULL )
250 m_message->destroy() ;
255 void GSmtp::Client::messageFail(
const std::string & reason ,
int reason_code )
257 if( m_message.get() != NULL )
259 m_message->fail( reason , reason_code ) ;
267 bool done = m_protocol.apply( line ) ;
273 G_DEBUG(
"GSmtp::Client::onDelete: error [" << error <<
"]" ) ;
274 if( ! error.empty() )
276 G_LOG(
"GSmtp::Client: smtp client error: \"" << error <<
"\"" ) ;
277 messageFail( error , 0 ) ;
284 m_protocol.sendDone() ;
291 unsigned int secure_connection_timeout_ ,
bool secure_tunnel_ ) :
292 processor_address(processor_address_) ,
293 processor_timeout(processor_timeout_) ,
294 local_address(address) ,
295 client_protocol_config(protocol_config) ,
296 connection_timeout(connection_timeout_) ,
297 secure_connection_timeout(secure_connection_timeout_) ,
298 secure_tunnel(secure_tunnel_)
void sendMessage(std::auto_ptr< StoredMessage > message)
Starts sending the given message.
static std::string printable(const std::string &in, char escape= '\\')
Returns a printable represention of the given input string.
virtual void onConnect()
Final override from GNet::SimpleClient.
virtual bool onReceive(const std::string &)
Final override from GNet::Client.
virtual bool empty() const =0
Returns true if the message store is empty.
std::list< std::string > Strings
A std::list of std::strings.
static void splitIntoFields(const std::string &in, Strings &out, const std::string &seperators, char escape= '\0', bool discard_bogus_escapes=true)
Splits the string into fields.
G::Signal1< std::string > & messageDoneSignal()
Returns a signal that indicates that sendMessage() has completed or failed.
The Address class encapsulates an IP transport address.
Slot0 slot(T &object, void(T::*fn)())
Part of the slot/signal system.
A class that holds a host/service name pair and optionally the results of a name-to-address lookup...
A structure containing GSmtp::ClientProtocol configuration parameters.
Config(std::string, unsigned int, GNet::Address, ClientProtocol::Config, unsigned int, unsigned int, bool)
virtual ~Client()
Destructor.
virtual void onSecure(const std::string &)
Final override from GNet::SocketProtocol.
G::Signal2< std::string, int > & doneSignal()
Returns a signal that is raised once the protocol has finished with a given message.
Client(const GNet::ResolverInfo &remote, const GAuth::Secrets &secrets, Config config)
Constructor.
A class which allows SMTP messages (envelope+content) to be stored and retrieved. ...
A simple interface to a store of secrets as used in authentication.
A factory for message processors.
A structure containing GSmtp::Client configuration parameters.
A class which acts as an SMTP client, extracting messages from a message store and forwarding them to...
virtual void onDelete(const std::string &, bool)
Final override from GNet::HeapClient.
virtual void onSendComplete()
Final override from GNet::BufferedClient.
void sendMessagesFrom(MessageStore &store)
Sends all messages from the given message store once connected.
void connect(Slot2< P1, P2 > slot)
G::Signal0 & preprocessorSignal()
Returns a signal that is raised when the protocol needs to do message preprocessing.