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