WebSocket.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. #include "WebSocket.h"
  2. #include "HttpRequest.h"
  3. #include <iostream>
  4. using namespace Network;
  5. using namespace WebSocket;
  6. using namespace Framework;
  7. __declspec( dllexport ) Frame &Frame::operator+=( const Frame &b ) // baut frames zusammen welche zu einer nachricht gehören
  8. {
  9. fin = b.fin;
  10. if( opcode == 0 )
  11. opcode = b.opcode;
  12. dataLength += b.dataLength;
  13. if( dataLength )
  14. {
  15. char *data = new char[ (int)dataLength ];
  16. if( data )
  17. memcpy( data, this->data, (int)(dataLength - b.dataLength) );
  18. if( b.data )
  19. memcpy( data + dataLength, b.data, (int)b.dataLength );
  20. delete[] this->data;
  21. this->data = data;
  22. }
  23. else
  24. {
  25. delete[] this->data;
  26. this->data = 0;
  27. }
  28. return *this;
  29. }
  30. __declspec( dllexport ) WebSocketClient::WebSocketClient( const char *path, const char *host, unsigned short port )
  31. : Thread()
  32. {
  33. queue = new Array< Frame >();
  34. callback = 0;
  35. klient = 0;
  36. this->path = path;
  37. this->host = host;
  38. this->port = port;
  39. lastPingFrame = 0;
  40. nextClose = 0;
  41. }
  42. WebSocketClient::~WebSocketClient()
  43. {
  44. disconnect();
  45. while( queue->getEintragAnzahl() )
  46. {
  47. Frame f = queue->get( 0 );
  48. delete[] f.data;
  49. queue->remove( 0 );
  50. }
  51. queue->release();
  52. }
  53. __declspec( dllexport ) void WebSocketClient::setMessageCallback( std::function< void( WebSocketClient *, __int64 size, const char *data, DataType typ ) > callback )
  54. {
  55. this->callback = callback;
  56. }
  57. __declspec( dllexport ) bool WebSocketClient::connect()
  58. {
  59. char allowedKeyChars[] = { 'a', 'b','c','d','e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
  60. 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
  61. '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
  62. 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0 };
  63. __int64 numKeyChars = strlen( allowedKeyChars );
  64. if( !klient )
  65. {
  66. Text message = "GET ";
  67. message += path;
  68. message += " HTTP/1.1\r\n";
  69. message += "Host: ";
  70. message += host;
  71. message += "\r\nUpgrade: websocket\r\n";
  72. message += "Connection: Upgrade\r\n";
  73. char *key = new char[ 25 ];
  74. key[ 24 ] = 0;
  75. key[ 23 ] = '=';
  76. key[ 22 ] = '=';
  77. for( int i = 0; i < 22; i++ )
  78. key[ i ] = allowedKeyChars[ (int)( gen.rand() * numKeyChars ) ];
  79. message += "Sec-WebSocket-Key: ";
  80. message += key;
  81. delete[] key;
  82. message += "\r\nSec-WebSocket-Version: 13\r\n\r\n";
  83. klient = new Klient();
  84. if( !klient->verbinde( port, host ) )
  85. {
  86. klient = klient->release();
  87. return 0;
  88. }
  89. klient->sende( message, message.getLength() );
  90. Text answer;
  91. int br = 0;
  92. do
  93. {
  94. char buff[ 2 ];
  95. buff[ 1 ] = 0;
  96. if( klient->getNachricht( buff, 1 ) )
  97. answer += buff;
  98. else
  99. break;
  100. if( buff[ 0 ] == '\n' )
  101. br++;
  102. else if( buff[ 0 ] != '\r' )
  103. br = 0;
  104. } while( br < 2 && klient->hatNachricht( 1000 ) );
  105. HTTP::Answer *handshakeResponse = new HTTP::Answer( answer );
  106. if( handshakeResponse->getStatusCode() != 101 )
  107. {
  108. handshakeResponse->release();
  109. klient = klient->release();
  110. return 0;
  111. }
  112. handshakeResponse->release();
  113. start();
  114. return 1;
  115. }
  116. else
  117. return 1;
  118. }
  119. __declspec( dllexport ) bool WebSocketClient::send( __int64 size, const char *data, DataType typ )
  120. {
  121. Frame f;
  122. f.fin = 1;
  123. f.rsv1 = 0;
  124. f.rsv2 = 0;
  125. f.rsv3 = 0;
  126. f.mask = 1;
  127. if( typ == TEXT )
  128. f.opcode = 1;
  129. else
  130. f.opcode = 2;
  131. f.dataLength = size;
  132. f.data = new char[ (int)f.dataLength ];
  133. memcpy( f.data, data, (int)f.dataLength );
  134. f.key[ 0 ] = (unsigned char)(gen.rand() * 256);
  135. f.key[ 1 ] = (unsigned char)(gen.rand() * 256);
  136. f.key[ 2 ] = (unsigned char)(gen.rand() * 256);
  137. f.key[ 3 ] = (unsigned char)(gen.rand() * 256);
  138. c.lock();
  139. queue->add( f );
  140. c.unlock();
  141. return 1;
  142. }
  143. __declspec( dllexport ) void WebSocketClient::thread()
  144. {
  145. while( klient )
  146. {
  147. c2.lock();
  148. if( !klient )
  149. {
  150. c2.unlock();
  151. return;
  152. }
  153. if( klient->hatNachricht( 100 ) )
  154. {
  155. bool ok = 1;
  156. c2.unlock();
  157. bool first = 1;
  158. Frame m;
  159. unsigned char byte;
  160. do
  161. {
  162. c2.lock();
  163. if( !klient )
  164. {
  165. c2.unlock();
  166. return;
  167. }
  168. Frame message;
  169. ok &= klient->getNachricht( (char*)&byte, 1 );
  170. message.fin = ( byte & 0x80 ) != 0;
  171. message.rsv1 = ( byte & 0x40 ) != 0;
  172. message.rsv2 = ( byte & 0x20 ) != 0;
  173. message.rsv3 = ( byte & 0x10 ) != 0;
  174. message.opcode = byte & 0xF;
  175. ok &= klient->getNachricht( (char*)&byte, 1 );
  176. message.mask = ( byte & 0x80 ) != 0;
  177. message.dataLength = byte & 0x7F;
  178. if( message.dataLength == 126 )
  179. {
  180. ok &= klient->getNachricht( (char*)&byte, 1 );
  181. message.dataLength = byte << 8;
  182. ok &= klient->getNachricht( (char*)&byte, 1 );
  183. message.dataLength |= byte;
  184. }
  185. else if( message.dataLength == 127 )
  186. {
  187. ok &= klient->getNachricht( (char*)&byte, 1 );
  188. message.dataLength = (__int64)byte << 56;
  189. ok &= klient->getNachricht( (char*)&byte, 1 );
  190. message.dataLength |= (__int64)byte << 48;
  191. ok &= klient->getNachricht( (char*)&byte, 1 );
  192. message.dataLength |= (__int64)byte << 40;
  193. ok &= klient->getNachricht( (char*)&byte, 1 );
  194. message.dataLength |= (__int64)byte << 32;
  195. ok &= klient->getNachricht( (char*)&byte, 1 );
  196. message.dataLength |= (__int64)byte << 24;
  197. ok &= klient->getNachricht( (char*)&byte, 1 );
  198. message.dataLength |= (__int64)byte << 16;
  199. ok &= klient->getNachricht( (char*)&byte, 1 );
  200. message.dataLength |= (__int64)byte << 8;
  201. ok &= klient->getNachricht( (char*)&byte, 1 );
  202. message.dataLength |= (__int64)byte;
  203. }
  204. if( message.mask )
  205. {
  206. ok &= klient->getNachricht( (char*)&byte, 1 );
  207. message.key[ 0 ] = byte;
  208. ok &= klient->getNachricht( (char*)&byte, 1 );
  209. message.key[ 1 ] = byte;
  210. ok &= klient->getNachricht( (char*)&byte, 1 );
  211. message.key[ 2 ] = byte;
  212. ok &= klient->getNachricht( (char*)&byte, 1 );
  213. message.key[ 3 ] = byte;
  214. }
  215. if( !ok )
  216. message.dataLength = 1;
  217. message.data = 0;
  218. if( message.dataLength )
  219. message.data = new char[ (int)message.dataLength ];
  220. for( int i = 0; i < message.dataLength; i++ )
  221. {
  222. ok &= klient->getNachricht( (char*)&byte, 1 );
  223. if( message.mask )
  224. message.data[ i ] = byte ^ message.key[ i % 4 ];
  225. else
  226. message.data[ i ] = byte;
  227. }
  228. c2.unlock();
  229. if( first )
  230. m = message;
  231. else
  232. {
  233. m += message;
  234. delete[] message.data;
  235. }
  236. first = 0;
  237. if( !ok )
  238. break;
  239. } while( !m.fin );
  240. if( !ok )
  241. {
  242. delete[] m.data;
  243. return;
  244. }
  245. if( m.opcode == 0x9 )
  246. {
  247. m.opcode = 0xA;
  248. m.key[ 0 ] = (unsigned char)( gen.rand() * 256 );
  249. m.key[ 1 ] = (unsigned char)( gen.rand() * 256 );
  250. m.key[ 2 ] = (unsigned char)( gen.rand() * 256 );
  251. m.key[ 3 ] = (unsigned char)( gen.rand() * 256 );
  252. queue->add( m );
  253. }
  254. else if( m.opcode == 0xA )
  255. {
  256. delete[] m.data;
  257. }
  258. else if( m.opcode == 0x8 )
  259. {
  260. if( nextClose )
  261. {
  262. delete[] m.data;
  263. c2.lock();
  264. klient->trenne();
  265. klient = klient->release();
  266. c2.unlock();
  267. return;
  268. }
  269. else
  270. {
  271. m.key[ 0 ] = (unsigned char)( gen.rand() * 256 );
  272. m.key[ 1 ] = (unsigned char)( gen.rand() * 256 );
  273. m.key[ 2 ] = (unsigned char)( gen.rand() * 256 );
  274. m.key[ 3 ] = (unsigned char)( gen.rand() * 256 );
  275. queue->add( m );
  276. nextClose = 1;
  277. }
  278. }
  279. else if( callback )
  280. {
  281. callback( this, m.dataLength, m.data, m.opcode == 1 ? TEXT : BINARY );
  282. delete[] m.data;
  283. }
  284. }
  285. else
  286. {
  287. c2.unlock();
  288. c.lock();
  289. while( queue->getEintragAnzahl() )
  290. {
  291. Frame f = queue->get( 0 );
  292. c.unlock();
  293. unsigned char byte = ( f.fin ? 1 : 0 ) << 7;
  294. byte |= ( f.rsv1 ? 1 : 0 ) << 6;
  295. byte |= ( f.rsv2 ? 1 : 0 ) << 5;
  296. byte |= ( f.rsv3 ? 1 : 0 ) << 4;
  297. byte |= f.opcode & 0xF;
  298. c2.lock();
  299. if( !klient )
  300. {
  301. c2.unlock();
  302. return;
  303. }
  304. klient->sende( (char*)&byte, 1 );
  305. byte = ( f.mask ? 1 : 0 ) << 7;
  306. if( f.dataLength < 126 )
  307. byte |= (unsigned char)f.dataLength & 0x7F;
  308. else if( f.dataLength <= 32767 )
  309. byte |= 126;
  310. else
  311. byte |= 127;
  312. klient->sende( (char*)&byte, 1 );
  313. if( f.dataLength >= 126 )
  314. {
  315. if( f.dataLength <= 32767 )
  316. {
  317. byte = (unsigned char)( f.dataLength >> 8 );
  318. klient->sende( (char*)&byte, 1 );
  319. byte = (unsigned char)f.dataLength & 0xFF;
  320. klient->sende( (char*)&byte, 1 );
  321. }
  322. else
  323. {
  324. byte = (unsigned char)( f.dataLength >> 56 );
  325. klient->sende( (char*)&byte, 1 );
  326. byte = (unsigned char)( f.dataLength >> 48 );
  327. klient->sende( (char*)&byte, 1 );
  328. byte = (unsigned char)( f.dataLength >> 40 );
  329. klient->sende( (char*)&byte, 1 );
  330. byte = (unsigned char)( f.dataLength >> 32 );
  331. klient->sende( (char*)&byte, 1 );
  332. byte = (unsigned char)( f.dataLength >> 24 );
  333. klient->sende( (char*)&byte, 1 );
  334. byte = (unsigned char)( f.dataLength >> 16 );
  335. klient->sende( (char*)&byte, 1 );
  336. byte = (unsigned char)( f.dataLength >> 8 );
  337. klient->sende( (char*)&byte, 1 );
  338. byte = (unsigned char)f.dataLength & 0xFF;
  339. klient->sende( (char*)&byte, 1 );
  340. }
  341. }
  342. if( f.mask )
  343. {
  344. byte = (unsigned char)f.key[ 0 ];
  345. klient->sende( (char*)&byte, 1 );
  346. byte = (unsigned char)f.key[ 1 ];
  347. klient->sende( (char*)&byte, 1 );
  348. byte = (unsigned char)f.key[ 2 ];
  349. klient->sende( (char*)&byte, 1 );
  350. byte = (unsigned char)f.key[ 3 ];
  351. klient->sende( (char*)&byte, 1 );
  352. }
  353. if( f.dataLength )
  354. {
  355. for( int i = 0; i < f.dataLength; i++ )
  356. {
  357. if( f.mask )
  358. byte = (unsigned char)f.data[ i ] ^ f.key[ i % 4 ];
  359. else
  360. byte = (unsigned char)f.data[ i ];
  361. klient->sende( (char*)&byte, 1 );
  362. }
  363. }
  364. c2.unlock();
  365. delete[] f.data;
  366. c.lock();
  367. queue->remove( 0 );
  368. if( f.opcode == 0x8 )
  369. {
  370. if( nextClose )
  371. {
  372. c.unlock();
  373. c2.lock();
  374. klient->trenne();
  375. klient = klient->release();
  376. c2.unlock();
  377. return;
  378. }
  379. else
  380. {
  381. nextClose = 1;
  382. }
  383. }
  384. }
  385. c.unlock();
  386. }
  387. }
  388. }
  389. __declspec( dllexport ) void WebSocketClient::disconnect()
  390. {
  391. if( !klient )
  392. return;
  393. c2.lock();
  394. klient->trenne();
  395. klient = klient->release();
  396. c2.unlock();
  397. warteAufThread( 1000 );
  398. }
  399. __declspec( dllexport ) bool WebSocketClient::isConnected() const
  400. {
  401. return klient != 0;
  402. }
  403. // löscht das objekt wenn es nicht mehr gebraucht wird und beendet den Thread
  404. Thread *WebSocketClient::release()
  405. {
  406. #ifdef WIN32
  407. if( ref == 2 && run )
  408. disconnect();
  409. #endif
  410. return Thread::release();
  411. }