1 /*
2  *  Copyright (c) 2004-2019 by Jakob Schröter <js@camaya.net>
3  *  This file is part of the gloox library. http://camaya.net/gloox
4  *
5  *  This software is distributed under a license. The full license
6  *  agreement can be found in the file LICENSE in this distribution.
7  *  This software may not be copied, modified, sold or distributed
8  *  other than expressed in the named license agreement.
9  *
10  *  This software is distributed without any warranty.
11  */
12 
13 #define CLIENT_TEST
14 #define CLIENTBASE_TEST
15 #include "../client.h"
16 #include "../messagesessionhandler.h"
17 #include "../messageeventhandler.h"
18 #include "../messageeventfilter.h"
19 #include "../chatstatehandler.h"
20 #include "../chatstatefilter.h"
21 #include "../connectionlistener.h"
22 #include "../disco.h"
23 #include "../message.h"
24 #include "../gloox.h"
25 #include "../lastactivity.h"
26 #include "../loghandler.h"
27 #include "../logsink.h"
28 #include "../connectiontcpclient.h"
29 #include "../connectionsocks5proxy.h"
30 #include "../connectionhttpproxy.h"
31 #include "../messagehandler.h"
32 using namespace gloox;
33 
34 #ifndef _WIN32
35 # include <unistd.h>
36 #endif
37 
38 #include <stdio.h>
39 #include <string>
40 
41 #include <cstdio> // [s]print[f]
42 
43 #if defined( WIN32 ) || defined( _WIN32 )
44 # include <windows.h>
45 #endif
46 
47 class MessageTest : public MessageSessionHandler, ConnectionListener, LogHandler,
48                     MessageEventHandler, MessageHandler, ChatStateHandler
49 {
50   public:
MessageTest()51     MessageTest() : m_session( 0 ), m_reconnect( false ) {}
52 
~MessageTest()53     virtual ~MessageTest() {}
54 
start()55     void start()
56     {
57 
58       JID jid( "admin@jabba.us/gloox" );
59       j = new Client( jid, "test" );
60       j->registerConnectionListener( this );
61       j->registerMessageSessionHandler( this, 0 );
62       j->disco()->setVersion( "reconnectTest", GLOOX_VERSION, "Linux" );
63       j->disco()->setIdentity( "client", "bot" );
64       j->disco()->addFeature( XMLNS_CHAT_STATES );
65 //       j->setTls( TLSDisabled );
66       j->setCompression( false );
67       j->setStreamManagement( true, true );
68       StringList ca;
69       ca.push_back( "/path/to/cacert.crt" );
70       j->setCACerts( ca );
71 
72       j->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll, this );
73 
74 //
75 // this code connects to a jabber server through a SOCKS5 proxy
76 //
77 //       ConnectionSOCKS5Proxy* conn = new ConnectionSOCKS5Proxy( j,
78 //                                   new ConnectionTCP( j->logInstance(),
79 //                                                      "sockshost", 1080 ),
80 //                                   j->logInstance(), "example.net" );
81 //       conn->setProxyAuth( "socksuser", "sockspwd" );
82 //       j->setConnectionImpl( conn );
83 
84 //
85 // this code connects to a jabber server through a HTTP proxy through a SOCKS5 proxy
86 //
87 //       ConnectionTCP* conn0 = new ConnectionTCP( j->logInstance(), "old", 1080 );
88 //       ConnectionSOCKS5Proxy* conn1 = new ConnectionSOCKS5Proxy( conn0, j->logInstance(), "old", 8080 );
89 //       conn1->setProxyAuth( "socksuser", "sockspwd" );
90 //       ConnectionHTTPProxy* conn2 = new ConnectionHTTPProxy( j, conn1, j->logInstance(), "jabber.cc" );
91 //       conn2->setProxyAuth( "httpuser", "httppwd" );
92 //       j->setConnectionImpl( conn2 );
93 
94 
95       ConnectionError ce = ConnNoError;
96       if( j->connect( false ) )
97       {
98         while( ce == ConnNoError )
99         {
100           ce = j->recv();
101         }
102         printf( "ce: %d\n", ce );
103       }
104 
105       m_reconnect = true;
106       ce = ConnNoError;
107       if( j->connect( false ) )
108       {
109         while( ce == ConnNoError )
110         {
111           ce = j->recv();
112         }
113         printf( "ce: %d\n", ce );
114       }
115 
116       delete( j );
117     }
118 
onConnect()119     virtual void onConnect()
120     {
121       printf( "connected!!!\n" );
122     }
123 
onDisconnect(ConnectionError e)124     virtual void onDisconnect( ConnectionError e )
125     {
126       printf( "message_test: disconnected: %d\n", e );
127       if( e == ConnAuthenticationFailed )
128         printf( "auth failed. reason: %d\n", j->authError() );
129     }
130 
onTLSConnect(const CertInfo & info)131     virtual bool onTLSConnect( const CertInfo& info )
132     {
133       time_t from( info.date_from );
134       time_t to( info.date_to );
135 
136       printf( "status: %d\nissuer: %s\npeer: %s\nprotocol: %s\nmac: %s\ncipher: %s\ncompression: %s\n",
137               info.status, info.issuer.c_str(), info.server.c_str(),
138               info.protocol.c_str(), info.mac.c_str(), info.cipher.c_str(),
139               info.compression.c_str() );
140       printf( "from: %s", ctime( &from ) );
141       printf( "to:   %s", ctime( &to ) );
142       return true;
143     }
144 
handleMessage(const Message & msg,MessageSession *)145     virtual void handleMessage( const Message& msg, MessageSession * /*session*/ )
146     {
147       printf( "type: %d, subject: %s, message: %s, thread id: %s\n", msg.subtype(),
148               msg.subject().c_str(), msg.body().c_str(), msg.thread().c_str() );
149 
150 
151       if( msg.body().substr( 0, 3 ) == "ack" ) // using substr() to work around some stupid clients
152         j->ackStreamManagement();
153       else if( msg.body().substr( 0, 3 ) == "req" )
154         j->reqStreamManagement();
155       else if( msg.body().substr( 0, 4 ) == "quit" )
156         j->disconnect();
157       else
158       {
159         std::string re = "You said:\n> " + msg.body() + "\nI like that statement.";
160         m_session->send( re, gloox::EmptyString );
161       }
162     }
163 
handleMessageEvent(const JID & from,MessageEventType event)164     virtual void handleMessageEvent( const JID& from, MessageEventType event )
165     {
166       printf( "received event: %d from: %s\n", event, from.full().c_str() );
167     }
168 
handleChatState(const JID & from,ChatStateType state)169     virtual void handleChatState( const JID& from, ChatStateType state )
170     {
171       printf( "received state: %d from: %s\n", state, from.full().c_str() );
172     }
173 
handleMessageSession(MessageSession * session)174     virtual void handleMessageSession( MessageSession *session )
175     {
176       printf( "got new session\n");
177       // this example can handle only one session. so we get rid of the old session
178       j->disposeMessageSession( m_session );
179       m_session = session;
180       m_session->registerMessageHandler( this );
181     }
182 
handleLog(LogLevel level,LogArea area,const std::string & message)183     virtual void handleLog( LogLevel level, LogArea area, const std::string& message )
184     {
185       printf("log: level: %d, area: %d, %s\n", level, area, message.c_str() );
186 
187       if( message.substr( 0, 10 ) == "<stream:er" )
188         printf( "something's foul\n" );
189 
190       if( !m_reconnect && j->m_smHandled > 10 )
191         j->disconnect( ConnTlsFailed ); // fake disconnect reason so that no </stream:stream> is sent
192     }
193 
194   private:
195     Client *j;
196     MessageSession *m_session;
197     bool m_reconnect;
198 };
199 
main(int,char **)200 int main( int /*argc*/, char** /*argv*/ )
201 {
202   MessageTest *r = new MessageTest();
203   r->start();
204   delete( r );
205   return 0;
206 }
207