WebSocket.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  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*)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*)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*)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*)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*)klient->release();
  396. c2.unlock();
  397. warteAufThread(1000);
  398. }
  399. __declspec(dllexport) bool WebSocketClient::isConnected() const
  400. {
  401. return klient != 0;
  402. }