hybi13.hpp 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078
  1. /*
  2. * Copyright (c) 2015, Peter Thorson. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. * * Redistributions of source code must retain the above copyright
  7. * notice, this list of conditions and the following disclaimer.
  8. * * Redistributions in binary form must reproduce the above copyright
  9. * notice, this list of conditions and the following disclaimer in the
  10. * documentation and/or other materials provided with the distribution.
  11. * * Neither the name of the WebSocket++ Project nor the
  12. * names of its contributors may be used to endorse or promote products
  13. * derived from this software without specific prior written permission.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
  19. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. *
  26. */
  27. #ifndef WEBSOCKETPP_PROCESSOR_HYBI13_HPP
  28. #define WEBSOCKETPP_PROCESSOR_HYBI13_HPP
  29. #include <websocketpp/processors/processor.hpp>
  30. #include <websocketpp/frame.hpp>
  31. #include <websocketpp/http/constants.hpp>
  32. #include <websocketpp/utf8_validator.hpp>
  33. #include <websocketpp/sha1/sha1.hpp>
  34. #include <websocketpp/base64/base64.hpp>
  35. #include <websocketpp/common/network.hpp>
  36. #include <websocketpp/common/platforms.hpp>
  37. #include <algorithm>
  38. #include <cassert>
  39. #include <string>
  40. #include <vector>
  41. #include <utility>
  42. namespace websocketpp {
  43. namespace processor {
  44. /// Processor for Hybi version 13 (RFC6455)
  45. template <typename config>
  46. class hybi13 : public processor<config> {
  47. public:
  48. typedef processor<config> base;
  49. typedef typename config::request_type request_type;
  50. typedef typename config::response_type response_type;
  51. typedef typename config::message_type message_type;
  52. typedef typename message_type::ptr message_ptr;
  53. typedef typename config::con_msg_manager_type msg_manager_type;
  54. typedef typename msg_manager_type::ptr msg_manager_ptr;
  55. typedef typename config::rng_type rng_type;
  56. typedef typename config::permessage_deflate_type permessage_deflate_type;
  57. typedef std::pair<lib::error_code,std::string> err_str_pair;
  58. explicit hybi13(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
  59. : processor<config>(secure, p_is_server)
  60. , m_msg_manager(manager)
  61. , m_rng(rng)
  62. {
  63. reset_headers();
  64. }
  65. int get_version() const {
  66. return 13;
  67. }
  68. bool has_permessage_deflate() const {
  69. return m_permessage_deflate.is_implemented();
  70. }
  71. err_str_pair negotiate_extensions(request_type const & request) {
  72. return negotiate_extensions_helper(request);
  73. }
  74. err_str_pair negotiate_extensions(response_type const & response) {
  75. return negotiate_extensions_helper(response);
  76. }
  77. /// Extension negotiation helper function
  78. /**
  79. * This exists mostly because the code for requests and responses is
  80. * identical and I can't have virtual template methods.
  81. */
  82. template <typename header_type>
  83. err_str_pair negotiate_extensions_helper(header_type const & header) {
  84. err_str_pair ret;
  85. // Respect blanket disabling of all extensions and don't even parse
  86. // the extension header
  87. if (!config::enable_extensions) {
  88. ret.first = make_error_code(error::extensions_disabled);
  89. return ret;
  90. }
  91. http::parameter_list p;
  92. bool error = header.get_header_as_plist("Sec-WebSocket-Extensions",p);
  93. if (error) {
  94. ret.first = make_error_code(error::extension_parse_error);
  95. return ret;
  96. }
  97. // If there are no extensions parsed then we are done!
  98. if (p.size() == 0) {
  99. return ret;
  100. }
  101. http::parameter_list::const_iterator it;
  102. // look through the list of extension requests to find the first
  103. // one that we can accept.
  104. if (m_permessage_deflate.is_implemented()) {
  105. err_str_pair neg_ret;
  106. for (it = p.begin(); it != p.end(); ++it) {
  107. // not a permessage-deflate extension request, ignore
  108. if (it->first != "permessage-deflate") {
  109. continue;
  110. }
  111. // if we have already successfully negotiated this extension
  112. // then skip any other requests to negotiate the same one
  113. // with different parameters
  114. if (m_permessage_deflate.is_enabled()) {
  115. continue;
  116. }
  117. // attempt to negotiate this offer
  118. neg_ret = m_permessage_deflate.negotiate(it->second);
  119. if (neg_ret.first) {
  120. // negotiation offer failed. Do nothing. We will continue
  121. // searching for a permessage-deflate config that succeeds
  122. continue;
  123. }
  124. // Negotiation tentatively succeeded
  125. // Actually try to initialize the extension before we
  126. // deem negotiation complete
  127. lib::error_code ec = m_permessage_deflate.init(base::m_server);
  128. if (ec) {
  129. // Negotiation succeeded but initialization failed this is
  130. // an error that should stop negotiation of permessage
  131. // deflate. Return the reason for the init failure
  132. ret.first = ec;
  133. break;
  134. } else {
  135. // Successfully initialized, push the negotiated response into
  136. // the reply and stop looking for additional permessage-deflate
  137. // extensions
  138. ret.second += neg_ret.second;
  139. break;
  140. }
  141. }
  142. }
  143. // support for future extensions would go here. Should check the value of
  144. // ret.first before continuing. Might need to consider whether failure of
  145. // negotiation of an earlier extension should stop negotiation of subsequent
  146. // ones
  147. return ret;
  148. }
  149. lib::error_code validate_handshake(request_type const & r) const {
  150. if (r.get_method() != "GET") {
  151. return make_error_code(error::invalid_http_method);
  152. }
  153. if (r.get_version() != "HTTP/1.1") {
  154. return make_error_code(error::invalid_http_version);
  155. }
  156. // required headers
  157. // Host is required by HTTP/1.1
  158. // Connection is required by is_websocket_handshake
  159. // Upgrade is required by is_websocket_handshake
  160. if (r.get_header("Sec-WebSocket-Key").empty()) {
  161. return make_error_code(error::missing_required_header);
  162. }
  163. return lib::error_code();
  164. }
  165. /* TODO: the 'subprotocol' parameter may need to be expanded into a more
  166. * generic struct if other user input parameters to the processed handshake
  167. * are found.
  168. */
  169. lib::error_code process_handshake(request_type const & request,
  170. std::string const & subprotocol, response_type & response) const
  171. {
  172. std::string server_key = request.get_header("Sec-WebSocket-Key");
  173. lib::error_code ec = process_handshake_key(server_key);
  174. if (ec) {
  175. return ec;
  176. }
  177. response.replace_header("Sec-WebSocket-Accept",server_key);
  178. response.append_header("Upgrade",constants::upgrade_token);
  179. response.append_header("Connection",constants::connection_token);
  180. if (!subprotocol.empty()) {
  181. response.replace_header("Sec-WebSocket-Protocol",subprotocol);
  182. }
  183. return lib::error_code();
  184. }
  185. /// Fill in a set of request headers for a client connection request
  186. /**
  187. * @param [out] req Set of headers to fill in
  188. * @param [in] uri The uri being connected to
  189. * @param [in] subprotocols The list of subprotocols to request
  190. */
  191. lib::error_code client_handshake_request(request_type & req, uri_ptr
  192. uri, std::vector<std::string> const & subprotocols) const
  193. {
  194. req.set_method("GET");
  195. req.set_uri(uri->get_resource());
  196. req.set_version("HTTP/1.1");
  197. req.append_header("Upgrade","websocket");
  198. req.append_header("Connection","Upgrade");
  199. req.replace_header("Sec-WebSocket-Version","13");
  200. req.replace_header("Host",uri->get_host_port());
  201. if (!subprotocols.empty()) {
  202. std::ostringstream result;
  203. std::vector<std::string>::const_iterator it = subprotocols.begin();
  204. result << *it++;
  205. while (it != subprotocols.end()) {
  206. result << ", " << *it++;
  207. }
  208. req.replace_header("Sec-WebSocket-Protocol",result.str());
  209. }
  210. // Generate handshake key
  211. frame::uint32_converter conv;
  212. unsigned char raw_key[16];
  213. for (int i = 0; i < 4; i++) {
  214. conv.i = m_rng();
  215. std::copy(conv.c,conv.c+4,&raw_key[i*4]);
  216. }
  217. req.replace_header("Sec-WebSocket-Key",base64_encode(raw_key, 16));
  218. if (m_permessage_deflate.is_implemented()) {
  219. std::string offer = m_permessage_deflate.generate_offer();
  220. if (!offer.empty()) {
  221. req.replace_header("Sec-WebSocket-Extensions",offer);
  222. }
  223. }
  224. return lib::error_code();
  225. }
  226. /// Validate the server's response to an outgoing handshake request
  227. /**
  228. * @param req The original request sent
  229. * @param res The reponse to generate
  230. * @return An error code, 0 on success, non-zero for other errors
  231. */
  232. lib::error_code validate_server_handshake_response(request_type const & req,
  233. response_type& res) const
  234. {
  235. // A valid response has an HTTP 101 switching protocols code
  236. if (res.get_status_code() != http::status_code::switching_protocols) {
  237. return error::make_error_code(error::invalid_http_status);
  238. }
  239. // And the upgrade token in an upgrade header
  240. std::string const & upgrade_header = res.get_header("Upgrade");
  241. if (utility::ci_find_substr(upgrade_header, constants::upgrade_token,
  242. sizeof(constants::upgrade_token)-1) == upgrade_header.end())
  243. {
  244. return error::make_error_code(error::missing_required_header);
  245. }
  246. // And the websocket token in the connection header
  247. std::string const & con_header = res.get_header("Connection");
  248. if (utility::ci_find_substr(con_header, constants::connection_token,
  249. sizeof(constants::connection_token)-1) == con_header.end())
  250. {
  251. return error::make_error_code(error::missing_required_header);
  252. }
  253. // And has a valid Sec-WebSocket-Accept value
  254. std::string key = req.get_header("Sec-WebSocket-Key");
  255. lib::error_code ec = process_handshake_key(key);
  256. if (ec || key != res.get_header("Sec-WebSocket-Accept")) {
  257. return error::make_error_code(error::missing_required_header);
  258. }
  259. // check extensions
  260. return lib::error_code();
  261. }
  262. std::string get_raw(response_type const & res) const {
  263. return res.raw();
  264. }
  265. std::string const & get_origin(request_type const & r) const {
  266. return r.get_header("Origin");
  267. }
  268. lib::error_code extract_subprotocols(request_type const & req,
  269. std::vector<std::string> & subprotocol_list)
  270. {
  271. if (!req.get_header("Sec-WebSocket-Protocol").empty()) {
  272. http::parameter_list p;
  273. if (!req.get_header_as_plist("Sec-WebSocket-Protocol",p)) {
  274. http::parameter_list::const_iterator it;
  275. for (it = p.begin(); it != p.end(); ++it) {
  276. subprotocol_list.push_back(it->first);
  277. }
  278. } else {
  279. return error::make_error_code(error::subprotocol_parse_error);
  280. }
  281. }
  282. return lib::error_code();
  283. }
  284. uri_ptr get_uri(request_type const & request) const {
  285. return get_uri_from_host(request,(base::m_secure ? "wss" : "ws"));
  286. }
  287. /// Process new websocket connection bytes
  288. /**
  289. *
  290. * Hybi 13 data streams represent a series of variable length frames. Each
  291. * frame is made up of a series of fixed length fields. The lengths of later
  292. * fields are contained in earlier fields. The first field length is fixed
  293. * by the spec.
  294. *
  295. * This processor represents a state machine that keeps track of what field
  296. * is presently being read and how many more bytes are needed to complete it
  297. *
  298. *
  299. *
  300. *
  301. * Read two header bytes
  302. * Extract full frame length.
  303. * Read extra header bytes
  304. * Validate frame header (including extension validate)
  305. * Read extension data into extension message state object
  306. * Read payload data into payload
  307. *
  308. * @param buf Input buffer
  309. *
  310. * @param len Length of input buffer
  311. *
  312. * @return Number of bytes processed or zero on error
  313. */
  314. size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) {
  315. size_t p = 0;
  316. ec = lib::error_code();
  317. //std::cout << "consume: " << utility::to_hex(buf,len) << std::endl;
  318. // Loop while we don't have a message ready and we still have bytes
  319. // left to process.
  320. while (m_state != READY && m_state != FATAL_ERROR &&
  321. (p < len || m_bytes_needed == 0))
  322. {
  323. if (m_state == HEADER_BASIC) {
  324. p += this->copy_basic_header_bytes(buf+p,len-p);
  325. if (m_bytes_needed > 0) {
  326. continue;
  327. }
  328. ec = this->validate_incoming_basic_header(
  329. m_basic_header, base::m_server, !m_data_msg.msg_ptr
  330. );
  331. if (ec) {break;}
  332. // extract full header size and adjust consume state accordingly
  333. m_state = HEADER_EXTENDED;
  334. m_cursor = 0;
  335. m_bytes_needed = frame::get_header_len(m_basic_header) -
  336. frame::BASIC_HEADER_LENGTH;
  337. } else if (m_state == HEADER_EXTENDED) {
  338. p += this->copy_extended_header_bytes(buf+p,len-p);
  339. if (m_bytes_needed > 0) {
  340. continue;
  341. }
  342. ec = validate_incoming_extended_header(m_basic_header,m_extended_header);
  343. if (ec){break;}
  344. m_state = APPLICATION;
  345. m_bytes_needed = static_cast<size_t>(get_payload_size(m_basic_header,m_extended_header));
  346. // check if this frame is the start of a new message and set up
  347. // the appropriate message metadata.
  348. frame::opcode::value op = frame::get_opcode(m_basic_header);
  349. // TODO: get_message failure conditions
  350. if (frame::opcode::is_control(op)) {
  351. m_control_msg = msg_metadata(
  352. m_msg_manager->get_message(op,m_bytes_needed),
  353. frame::get_masking_key(m_basic_header,m_extended_header)
  354. );
  355. m_current_msg = &m_control_msg;
  356. } else {
  357. if (!m_data_msg.msg_ptr) {
  358. if (m_bytes_needed > base::m_max_message_size) {
  359. ec = make_error_code(error::message_too_big);
  360. break;
  361. }
  362. m_data_msg = msg_metadata(
  363. m_msg_manager->get_message(op,m_bytes_needed),
  364. frame::get_masking_key(m_basic_header,m_extended_header)
  365. );
  366. if (m_permessage_deflate.is_enabled()) {
  367. m_data_msg.msg_ptr->set_compressed(frame::get_rsv1(m_basic_header));
  368. }
  369. } else {
  370. // Fetch the underlying payload buffer from the data message we
  371. // are writing into.
  372. std::string & out = m_data_msg.msg_ptr->get_raw_payload();
  373. if (out.size() + m_bytes_needed > base::m_max_message_size) {
  374. ec = make_error_code(error::message_too_big);
  375. break;
  376. }
  377. // Each frame starts a new masking key. All other state
  378. // remains between frames.
  379. m_data_msg.prepared_key = prepare_masking_key(
  380. frame::get_masking_key(
  381. m_basic_header,
  382. m_extended_header
  383. )
  384. );
  385. out.reserve(out.size() + m_bytes_needed);
  386. }
  387. m_current_msg = &m_data_msg;
  388. }
  389. } else if (m_state == EXTENSION) {
  390. m_state = APPLICATION;
  391. } else if (m_state == APPLICATION) {
  392. size_t bytes_to_process = (std::min)(m_bytes_needed,len-p);
  393. if (bytes_to_process > 0) {
  394. p += this->process_payload_bytes(buf+p,bytes_to_process,ec);
  395. if (ec) {break;}
  396. }
  397. if (m_bytes_needed > 0) {
  398. continue;
  399. }
  400. // If this was the last frame in the message set the ready flag.
  401. // Otherwise, reset processor state to read additional frames.
  402. if (frame::get_fin(m_basic_header)) {
  403. ec = finalize_message();
  404. if (ec) {
  405. break;
  406. }
  407. } else {
  408. this->reset_headers();
  409. }
  410. } else {
  411. // shouldn't be here
  412. ec = make_error_code(error::general);
  413. return 0;
  414. }
  415. }
  416. return p;
  417. }
  418. /// Perform any finalization actions on an incoming message
  419. /**
  420. * Called after the full message is received. Provides the opportunity for
  421. * extensions to complete any data post processing as well as final UTF8
  422. * validation checks for text messages.
  423. *
  424. * @return A code indicating errors, if any
  425. */
  426. lib::error_code finalize_message() {
  427. std::string & out = m_current_msg->msg_ptr->get_raw_payload();
  428. // if the frame is compressed, append the compression
  429. // trailer and flush the compression buffer.
  430. if (m_permessage_deflate.is_enabled()
  431. && m_current_msg->msg_ptr->get_compressed())
  432. {
  433. uint8_t trailer[4] = {0x00, 0x00, 0xff, 0xff};
  434. // Decompress current buffer into the message buffer
  435. lib::error_code ec;
  436. ec = m_permessage_deflate.decompress(trailer,4,out);
  437. if (ec) {
  438. return ec;
  439. }
  440. }
  441. // ensure that text messages end on a valid UTF8 code point
  442. if (frame::get_opcode(m_basic_header) == frame::opcode::TEXT) {
  443. if (!m_current_msg->validator.complete()) {
  444. return make_error_code(error::invalid_utf8);
  445. }
  446. }
  447. m_state = READY;
  448. return lib::error_code();
  449. }
  450. void reset_headers() {
  451. m_state = HEADER_BASIC;
  452. m_bytes_needed = frame::BASIC_HEADER_LENGTH;
  453. m_basic_header.b0 = 0x00;
  454. m_basic_header.b1 = 0x00;
  455. std::fill_n(
  456. m_extended_header.bytes,
  457. frame::MAX_EXTENDED_HEADER_LENGTH,
  458. 0x00
  459. );
  460. }
  461. /// Test whether or not the processor has a message ready
  462. bool ready() const {
  463. return (m_state == READY);
  464. }
  465. message_ptr get_message() {
  466. if (!ready()) {
  467. return message_ptr();
  468. }
  469. message_ptr ret = m_current_msg->msg_ptr;
  470. m_current_msg->msg_ptr.reset();
  471. if (frame::opcode::is_control(ret->get_opcode())) {
  472. m_control_msg.msg_ptr.reset();
  473. } else {
  474. m_data_msg.msg_ptr.reset();
  475. }
  476. this->reset_headers();
  477. return ret;
  478. }
  479. /// Test whether or not the processor is in a fatal error state.
  480. bool get_error() const {
  481. return m_state == FATAL_ERROR;
  482. }
  483. size_t get_bytes_needed() const {
  484. return m_bytes_needed;
  485. }
  486. /// Prepare a user data message for writing
  487. /**
  488. * Performs validation, masking, compression, etc. will return an error if
  489. * there was an error, otherwise msg will be ready to be written
  490. *
  491. * TODO: tests
  492. *
  493. * @param in An unprepared message to prepare
  494. * @param out A message to be overwritten with the prepared message
  495. * @return error code
  496. */
  497. virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out)
  498. {
  499. if (!in || !out) {
  500. return make_error_code(error::invalid_arguments);
  501. }
  502. frame::opcode::value op = in->get_opcode();
  503. // validate opcode: only regular data frames
  504. if (frame::opcode::is_control(op)) {
  505. return make_error_code(error::invalid_opcode);
  506. }
  507. std::string& i = in->get_raw_payload();
  508. std::string& o = out->get_raw_payload();
  509. // validate payload utf8
  510. if (op == frame::opcode::TEXT && !utf8_validator::validate(i)) {
  511. return make_error_code(error::invalid_payload);
  512. }
  513. frame::masking_key_type key;
  514. bool masked = !base::m_server;
  515. bool compressed = m_permessage_deflate.is_enabled()
  516. && in->get_compressed();
  517. bool fin = in->get_fin();
  518. if (masked) {
  519. // Generate masking key.
  520. key.i = m_rng();
  521. } else {
  522. key.i = 0;
  523. }
  524. // prepare payload
  525. if (compressed) {
  526. // compress and store in o after header.
  527. m_permessage_deflate.compress(i,o);
  528. if (o.size() < 4) {
  529. return make_error_code(error::general);
  530. }
  531. // Strip trailing 4 0x00 0x00 0xff 0xff bytes before writing to the
  532. // wire
  533. o.resize(o.size()-4);
  534. // mask in place if necessary
  535. if (masked) {
  536. this->masked_copy(o,o,key);
  537. }
  538. } else {
  539. // no compression, just copy data into the output buffer
  540. o.resize(i.size());
  541. // if we are masked, have the masking function write to the output
  542. // buffer directly to avoid another copy. If not masked, copy
  543. // directly without masking.
  544. if (masked) {
  545. this->masked_copy(i,o,key);
  546. } else {
  547. std::copy(i.begin(),i.end(),o.begin());
  548. }
  549. }
  550. // generate header
  551. frame::basic_header h(op,o.size(),fin,masked,compressed);
  552. if (masked) {
  553. frame::extended_header e(o.size(),key.i);
  554. out->set_header(frame::prepare_header(h,e));
  555. } else {
  556. frame::extended_header e(o.size());
  557. out->set_header(frame::prepare_header(h,e));
  558. }
  559. out->set_prepared(true);
  560. out->set_opcode(op);
  561. return lib::error_code();
  562. }
  563. /// Get URI
  564. lib::error_code prepare_ping(std::string const & in, message_ptr out) const {
  565. return this->prepare_control(frame::opcode::PING,in,out);
  566. }
  567. lib::error_code prepare_pong(std::string const & in, message_ptr out) const {
  568. return this->prepare_control(frame::opcode::PONG,in,out);
  569. }
  570. virtual lib::error_code prepare_close(close::status::value code,
  571. std::string const & reason, message_ptr out) const
  572. {
  573. if (close::status::reserved(code)) {
  574. return make_error_code(error::reserved_close_code);
  575. }
  576. if (close::status::invalid(code) && code != close::status::no_status) {
  577. return make_error_code(error::invalid_close_code);
  578. }
  579. if (code == close::status::no_status && reason.size() > 0) {
  580. return make_error_code(error::reason_requires_code);
  581. }
  582. if (reason.size() > frame:: limits::payload_size_basic-2) {
  583. return make_error_code(error::control_too_big);
  584. }
  585. std::string payload;
  586. if (code != close::status::no_status) {
  587. close::code_converter val;
  588. val.i = htons(code);
  589. payload.resize(reason.size()+2);
  590. payload[0] = val.c[0];
  591. payload[1] = val.c[1];
  592. std::copy(reason.begin(),reason.end(),payload.begin()+2);
  593. }
  594. return this->prepare_control(frame::opcode::CLOSE,payload,out);
  595. }
  596. protected:
  597. /// Convert a client handshake key into a server response key in place
  598. lib::error_code process_handshake_key(std::string & key) const {
  599. key.append(constants::handshake_guid);
  600. unsigned char message_digest[20];
  601. sha1::calc(key.c_str(),key.length(),message_digest);
  602. key = base64_encode(message_digest,20);
  603. return lib::error_code();
  604. }
  605. /// Reads bytes from buf into m_basic_header
  606. size_t copy_basic_header_bytes(uint8_t const * buf, size_t len) {
  607. if (len == 0 || m_bytes_needed == 0) {
  608. return 0;
  609. }
  610. if (len > 1) {
  611. // have at least two bytes
  612. if (m_bytes_needed == 2) {
  613. m_basic_header.b0 = buf[0];
  614. m_basic_header.b1 = buf[1];
  615. m_bytes_needed -= 2;
  616. return 2;
  617. } else {
  618. m_basic_header.b1 = buf[0];
  619. m_bytes_needed--;
  620. return 1;
  621. }
  622. } else {
  623. // have exactly one byte
  624. if (m_bytes_needed == 2) {
  625. m_basic_header.b0 = buf[0];
  626. m_bytes_needed--;
  627. return 1;
  628. } else {
  629. m_basic_header.b1 = buf[0];
  630. m_bytes_needed--;
  631. return 1;
  632. }
  633. }
  634. }
  635. /// Reads bytes from buf into m_extended_header
  636. size_t copy_extended_header_bytes(uint8_t const * buf, size_t len) {
  637. size_t bytes_to_read = (std::min)(m_bytes_needed,len);
  638. std::copy(buf,buf+bytes_to_read,m_extended_header.bytes+m_cursor);
  639. m_cursor += bytes_to_read;
  640. m_bytes_needed -= bytes_to_read;
  641. return bytes_to_read;
  642. }
  643. /// Reads bytes from buf into message payload
  644. /**
  645. * This function performs unmasking and uncompression, validates the
  646. * decoded bytes, and writes them to the appropriate message buffer.
  647. *
  648. * This member function will use the input buffer as stratch space for its
  649. * work. The raw input bytes will not be preserved. This applies only to the
  650. * bytes actually needed. At most min(m_bytes_needed,len) will be processed.
  651. *
  652. * @param buf Input/working buffer
  653. * @param len Length of buf
  654. * @return Number of bytes processed or zero in case of an error
  655. */
  656. size_t process_payload_bytes(uint8_t * buf, size_t len, lib::error_code& ec)
  657. {
  658. // unmask if masked
  659. if (frame::get_masked(m_basic_header)) {
  660. m_current_msg->prepared_key = frame::byte_mask_circ(
  661. buf, len, m_current_msg->prepared_key);
  662. // TODO: SIMD masking
  663. }
  664. std::string & out = m_current_msg->msg_ptr->get_raw_payload();
  665. size_t offset = out.size();
  666. // decompress message if needed.
  667. if (m_permessage_deflate.is_enabled()
  668. && m_current_msg->msg_ptr->get_compressed())
  669. {
  670. // Decompress current buffer into the message buffer
  671. ec = m_permessage_deflate.decompress(buf,len,out);
  672. if (ec) {
  673. return 0;
  674. }
  675. } else {
  676. // No compression, straight copy
  677. out.append(reinterpret_cast<char *>(buf),len);
  678. }
  679. // validate unmasked, decompressed values
  680. if (m_current_msg->msg_ptr->get_opcode() == frame::opcode::TEXT) {
  681. if (!m_current_msg->validator.decode(out.begin()+offset,out.end())) {
  682. ec = make_error_code(error::invalid_utf8);
  683. return 0;
  684. }
  685. }
  686. m_bytes_needed -= len;
  687. return len;
  688. }
  689. /// Validate an incoming basic header
  690. /**
  691. * Validates an incoming hybi13 basic header.
  692. *
  693. * @param h The basic header to validate
  694. * @param is_server Whether or not the endpoint that received this frame
  695. * is a server.
  696. * @param new_msg Whether or not this is the first frame of the message
  697. * @return 0 on success or a non-zero error code on failure
  698. */
  699. lib::error_code validate_incoming_basic_header(frame::basic_header const & h,
  700. bool is_server, bool new_msg) const
  701. {
  702. frame::opcode::value op = frame::get_opcode(h);
  703. // Check control frame size limit
  704. if (frame::opcode::is_control(op) &&
  705. frame::get_basic_size(h) > frame::limits::payload_size_basic)
  706. {
  707. return make_error_code(error::control_too_big);
  708. }
  709. // Check that RSV bits are clear
  710. // The only RSV bits allowed are rsv1 if the permessage_compress
  711. // extension is enabled for this connection and the message is not
  712. // a control message.
  713. //
  714. // TODO: unit tests for this
  715. if (frame::get_rsv1(h) && (!m_permessage_deflate.is_enabled()
  716. || frame::opcode::is_control(op)))
  717. {
  718. return make_error_code(error::invalid_rsv_bit);
  719. }
  720. if (frame::get_rsv2(h) || frame::get_rsv3(h)) {
  721. return make_error_code(error::invalid_rsv_bit);
  722. }
  723. // Check for reserved opcodes
  724. if (frame::opcode::reserved(op)) {
  725. return make_error_code(error::invalid_opcode);
  726. }
  727. // Check for invalid opcodes
  728. // TODO: unit tests for this?
  729. if (frame::opcode::invalid(op)) {
  730. return make_error_code(error::invalid_opcode);
  731. }
  732. // Check for fragmented control message
  733. if (frame::opcode::is_control(op) && !frame::get_fin(h)) {
  734. return make_error_code(error::fragmented_control);
  735. }
  736. // Check for continuation without an active message
  737. if (new_msg && op == frame::opcode::CONTINUATION) {
  738. return make_error_code(error::invalid_continuation);
  739. }
  740. // Check for new data frame when expecting continuation
  741. if (!new_msg && !frame::opcode::is_control(op) &&
  742. op != frame::opcode::CONTINUATION)
  743. {
  744. return make_error_code(error::invalid_continuation);
  745. }
  746. // Servers should reject any unmasked frames from clients.
  747. // Clients should reject any masked frames from servers.
  748. if (is_server && !frame::get_masked(h)) {
  749. return make_error_code(error::masking_required);
  750. } else if (!is_server && frame::get_masked(h)) {
  751. return make_error_code(error::masking_forbidden);
  752. }
  753. return lib::error_code();
  754. }
  755. /// Validate an incoming extended header
  756. /**
  757. * Validates an incoming hybi13 full header.
  758. *
  759. * @todo unit test for the >32 bit frames on 32 bit systems case
  760. *
  761. * @param h The basic header to validate
  762. * @param e The extended header to validate
  763. * @return An error_code, non-zero values indicate why the validation
  764. * failed
  765. */
  766. lib::error_code validate_incoming_extended_header(frame::basic_header h,
  767. frame::extended_header e) const
  768. {
  769. uint8_t basic_size = frame::get_basic_size(h);
  770. uint64_t payload_size = frame::get_payload_size(h,e);
  771. // Check for non-minimally encoded payloads
  772. if (basic_size == frame::payload_size_code_16bit &&
  773. payload_size <= frame::limits::payload_size_basic)
  774. {
  775. return make_error_code(error::non_minimal_encoding);
  776. }
  777. if (basic_size == frame::payload_size_code_64bit &&
  778. payload_size <= frame::limits::payload_size_extended)
  779. {
  780. return make_error_code(error::non_minimal_encoding);
  781. }
  782. // Check for >32bit frames on 32 bit systems
  783. if (sizeof(size_t) == 4 && (payload_size >> 32)) {
  784. return make_error_code(error::requires_64bit);
  785. }
  786. return lib::error_code();
  787. }
  788. /// Copy and mask/unmask in one operation
  789. /**
  790. * Reads input from one string and writes unmasked output to another.
  791. *
  792. * @param [in] i The input string.
  793. * @param [out] o The output string.
  794. * @param [in] key The masking key to use for masking/unmasking
  795. */
  796. void masked_copy (std::string const & i, std::string & o,
  797. frame::masking_key_type key) const
  798. {
  799. frame::byte_mask(i.begin(),i.end(),o.begin(),key);
  800. // TODO: SIMD masking
  801. }
  802. /// Generic prepare control frame with opcode and payload.
  803. /**
  804. * Internal control frame building method. Handles validation, masking, etc
  805. *
  806. * @param op The control opcode to use
  807. * @param payload The payload to use
  808. * @param out The message buffer to store the prepared frame in
  809. * @return Status code, zero on success, non-zero on error
  810. */
  811. lib::error_code prepare_control(frame::opcode::value op,
  812. std::string const & payload, message_ptr out) const
  813. {
  814. if (!out) {
  815. return make_error_code(error::invalid_arguments);
  816. }
  817. if (!frame::opcode::is_control(op)) {
  818. return make_error_code(error::invalid_opcode);
  819. }
  820. if (payload.size() > frame::limits::payload_size_basic) {
  821. return make_error_code(error::control_too_big);
  822. }
  823. frame::masking_key_type key;
  824. bool masked = !base::m_server;
  825. frame::basic_header h(op,payload.size(),true,masked);
  826. std::string & o = out->get_raw_payload();
  827. o.resize(payload.size());
  828. if (masked) {
  829. // Generate masking key.
  830. key.i = m_rng();
  831. frame::extended_header e(payload.size(),key.i);
  832. out->set_header(frame::prepare_header(h,e));
  833. this->masked_copy(payload,o,key);
  834. } else {
  835. frame::extended_header e(payload.size());
  836. out->set_header(frame::prepare_header(h,e));
  837. std::copy(payload.begin(),payload.end(),o.begin());
  838. }
  839. out->set_opcode(op);
  840. out->set_prepared(true);
  841. return lib::error_code();
  842. }
  843. enum state {
  844. HEADER_BASIC = 0,
  845. HEADER_EXTENDED = 1,
  846. EXTENSION = 2,
  847. APPLICATION = 3,
  848. READY = 4,
  849. FATAL_ERROR = 5
  850. };
  851. /// This data structure holds data related to processing a message, such as
  852. /// the buffer it is being written to, its masking key, its UTF8 validation
  853. /// state, and sometimes its compression state.
  854. struct msg_metadata {
  855. msg_metadata() {}
  856. msg_metadata(message_ptr m, size_t p) : msg_ptr(m),prepared_key(p) {}
  857. msg_metadata(message_ptr m, frame::masking_key_type p)
  858. : msg_ptr(m)
  859. , prepared_key(prepare_masking_key(p)) {}
  860. message_ptr msg_ptr; // pointer to the message data buffer
  861. size_t prepared_key; // prepared masking key
  862. utf8_validator::validator validator; // utf8 validation state
  863. };
  864. // Basic header of the frame being read
  865. frame::basic_header m_basic_header;
  866. // Pointer to a manager that can create message buffers for us.
  867. msg_manager_ptr m_msg_manager;
  868. // Number of bytes needed to complete the current operation
  869. size_t m_bytes_needed;
  870. // Number of extended header bytes read
  871. size_t m_cursor;
  872. // Metadata for the current data msg
  873. msg_metadata m_data_msg;
  874. // Metadata for the current control msg
  875. msg_metadata m_control_msg;
  876. // Pointer to the metadata associated with the frame being read
  877. msg_metadata * m_current_msg;
  878. // Extended header of current frame
  879. frame::extended_header m_extended_header;
  880. rng_type & m_rng;
  881. // Overall state of the processor
  882. state m_state;
  883. // Extensions
  884. permessage_deflate_type m_permessage_deflate;
  885. };
  886. } // namespace processor
  887. } // namespace websocketpp
  888. #endif //WEBSOCKETPP_PROCESSOR_HYBI13_HPP