WebSocket.cpp 14 KB

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