connection.hpp 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596
  1. /*
  2. * Copyright (c) 2014, 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_CONNECTION_HPP
  28. #define WEBSOCKETPP_CONNECTION_HPP
  29. #include <websocketpp/close.hpp>
  30. #include <websocketpp/error.hpp>
  31. #include <websocketpp/frame.hpp>
  32. #include <websocketpp/logger/levels.hpp>
  33. #include <websocketpp/processors/processor.hpp>
  34. #include <websocketpp/transport/base/connection.hpp>
  35. #include <websocketpp/http/constants.hpp>
  36. #include <websocketpp/common/connection_hdl.hpp>
  37. #include <websocketpp/common/cpp11.hpp>
  38. #include <websocketpp/common/functional.hpp>
  39. #include <queue>
  40. #include <sstream>
  41. #include <string>
  42. #include <vector>
  43. namespace websocketpp {
  44. /// The type and function signature of an open handler
  45. /**
  46. * The open handler is called once for every successful WebSocket connection
  47. * attempt. Either the fail handler or the open handler will be called for each
  48. * WebSocket connection attempt. HTTP Connections that did not attempt to
  49. * upgrade the connection to the WebSocket protocol will trigger the http
  50. * handler instead of fail/open.
  51. */
  52. typedef lib::function<void(connection_hdl)> open_handler;
  53. /// The type and function signature of a close handler
  54. /**
  55. * The close handler is called once for every successfully established
  56. * connection after it is no longer capable of sending or receiving new messages
  57. *
  58. * The close handler will be called exactly once for every connection for which
  59. * the open handler was called.
  60. */
  61. typedef lib::function<void(connection_hdl)> close_handler;
  62. /// The type and function signature of a fail handler
  63. /**
  64. * The fail handler is called once for every unsuccessful WebSocket connection
  65. * attempt. Either the fail handler or the open handler will be called for each
  66. * WebSocket connection attempt. HTTP Connections that did not attempt to
  67. * upgrade the connection to the WebSocket protocol will trigger the http
  68. * handler instead of fail/open.
  69. */
  70. typedef lib::function<void(connection_hdl)> fail_handler;
  71. /// The type and function signature of an interrupt handler
  72. /**
  73. * The interrupt handler is called when a connection receives an interrupt
  74. * request from the application. Interrupts allow the application to trigger a
  75. * handler to be run in the absense of a WebSocket level handler trigger (like
  76. * a new message).
  77. *
  78. * This is typically used by another application thread to schedule some tasks
  79. * that can only be run from within the handler chain for thread safety reasons.
  80. */
  81. typedef lib::function<void(connection_hdl)> interrupt_handler;
  82. /// The type and function signature of a ping handler
  83. /**
  84. * The ping handler is called when the connection receives a WebSocket ping
  85. * control frame. The string argument contains the ping payload. The payload is
  86. * a binary string up to 126 bytes in length. The ping handler returns a bool,
  87. * true if a pong response should be sent, false if the pong response should be
  88. * suppressed.
  89. */
  90. typedef lib::function<bool(connection_hdl,std::string)> ping_handler;
  91. /// The type and function signature of a pong handler
  92. /**
  93. * The pong handler is called when the connection receives a WebSocket pong
  94. * control frame. The string argument contains the pong payload. The payload is
  95. * a binary string up to 126 bytes in length.
  96. */
  97. typedef lib::function<void(connection_hdl,std::string)> pong_handler;
  98. /// The type and function signature of a pong timeout handler
  99. /**
  100. * The pong timeout handler is called when a ping goes unanswered by a pong for
  101. * longer than the locally specified timeout period.
  102. */
  103. typedef lib::function<void(connection_hdl,std::string)> pong_timeout_handler;
  104. /// The type and function signature of a validate handler
  105. /**
  106. * The validate handler is called after a WebSocket handshake has been received
  107. * and processed but before it has been accepted. This gives the application a
  108. * chance to implement connection details specific policies for accepting
  109. * connections and the ability to negotiate extensions and subprotocols.
  110. *
  111. * The validate handler return value indicates whether or not the connection
  112. * should be accepted. Additional methods may be called during the function to
  113. * set response headers, set HTTP return/error codes, etc.
  114. */
  115. typedef lib::function<bool(connection_hdl)> validate_handler;
  116. /// The type and function signature of a http handler
  117. /**
  118. * The http handler is called when an HTTP connection is made that does not
  119. * attempt to upgrade the connection to the WebSocket protocol. This allows
  120. * WebSocket++ servers to respond to these requests with regular HTTP responses.
  121. *
  122. * This can be used to deliver error pages & dashboards and to deliver static
  123. * files such as the base HTML & JavaScript for an otherwise single page
  124. * WebSocket application.
  125. *
  126. * Note: WebSocket++ is designed to be a high performance WebSocket server. It
  127. * is not tuned to provide a full featured, high performance, HTTP web server
  128. * solution. The HTTP handler is appropriate only for low volume HTTP traffic.
  129. * If you expect to serve high volumes of HTTP traffic a dedicated HTTP web
  130. * server is strongly recommended.
  131. *
  132. * The default HTTP handler will return a 426 Upgrade Required error. Custom
  133. * handlers may override the response status code to deliver any type of
  134. * response.
  135. */
  136. typedef lib::function<void(connection_hdl)> http_handler;
  137. //
  138. typedef lib::function<void(lib::error_code const & ec, size_t bytes_transferred)> read_handler;
  139. typedef lib::function<void(lib::error_code const & ec)> write_frame_handler;
  140. // constants related to the default WebSocket protocol versions available
  141. #ifdef _WEBSOCKETPP_INITIALIZER_LISTS_ // simplified C++11 version
  142. /// Container that stores the list of protocol versions supported
  143. /**
  144. * @todo Move this to configs to allow compile/runtime disabling or enabling
  145. * of protocol versions
  146. */
  147. static std::vector<int> const versions_supported = {0,7,8,13};
  148. #else
  149. /// Helper array to get around lack of initializer lists pre C++11
  150. static int const helper[] = {0,7,8,13};
  151. /// Container that stores the list of protocol versions supported
  152. /**
  153. * @todo Move this to configs to allow compile/runtime disabling or enabling
  154. * of protocol versions
  155. */
  156. static std::vector<int> const versions_supported(helper,helper+4);
  157. #endif
  158. namespace session {
  159. namespace state {
  160. // externally visible session state (states based on the RFC)
  161. enum value {
  162. connecting = 0,
  163. open = 1,
  164. closing = 2,
  165. closed = 3
  166. };
  167. } // namespace state
  168. namespace fail {
  169. namespace status {
  170. enum value {
  171. GOOD = 0, // no failure yet!
  172. SYSTEM = 1, // system call returned error, check that code
  173. WEBSOCKET = 2, // websocket close codes contain error
  174. UNKNOWN = 3, // No failure information is available
  175. TIMEOUT_TLS = 4, // TLS handshake timed out
  176. TIMEOUT_WS = 5 // WS handshake timed out
  177. };
  178. } // namespace status
  179. } // namespace fail
  180. namespace internal_state {
  181. // More granular internal states. These are used for multi-threaded
  182. // connection synchronization and preventing values that are not yet or no
  183. // longer available from being used.
  184. enum value {
  185. USER_INIT = 0,
  186. TRANSPORT_INIT = 1,
  187. READ_HTTP_REQUEST = 2,
  188. WRITE_HTTP_REQUEST = 3,
  189. READ_HTTP_RESPONSE = 4,
  190. WRITE_HTTP_RESPONSE = 5,
  191. PROCESS_HTTP_REQUEST = 6,
  192. PROCESS_CONNECTION = 7
  193. };
  194. } // namespace internal_state
  195. namespace http_state {
  196. // states to keep track of the progress of http connections
  197. enum value {
  198. init = 0,
  199. deferred = 1,
  200. headers_written = 2,
  201. body_written = 3,
  202. closed = 4
  203. };
  204. } // namespace http_state
  205. } // namespace session
  206. /// Represents an individual WebSocket connection
  207. template <typename config>
  208. class connection
  209. : public config::transport_type::transport_con_type
  210. , public config::connection_base
  211. {
  212. public:
  213. /// Type of this connection
  214. typedef connection<config> type;
  215. /// Type of a shared pointer to this connection
  216. typedef lib::shared_ptr<type> ptr;
  217. /// Type of a weak pointer to this connection
  218. typedef lib::weak_ptr<type> weak_ptr;
  219. /// Type of the concurrency component of this connection
  220. typedef typename config::concurrency_type concurrency_type;
  221. /// Type of the access logging policy
  222. typedef typename config::alog_type alog_type;
  223. /// Type of the error logging policy
  224. typedef typename config::elog_type elog_type;
  225. /// Type of the transport component of this connection
  226. typedef typename config::transport_type::transport_con_type
  227. transport_con_type;
  228. /// Type of a shared pointer to the transport component of this connection
  229. typedef typename transport_con_type::ptr transport_con_ptr;
  230. typedef lib::function<void(ptr)> termination_handler;
  231. typedef typename concurrency_type::scoped_lock_type scoped_lock_type;
  232. typedef typename concurrency_type::mutex_type mutex_type;
  233. typedef typename config::request_type request_type;
  234. typedef typename config::response_type response_type;
  235. typedef typename config::message_type message_type;
  236. typedef typename message_type::ptr message_ptr;
  237. typedef typename config::con_msg_manager_type con_msg_manager_type;
  238. typedef typename con_msg_manager_type::ptr con_msg_manager_ptr;
  239. /// Type of RNG
  240. typedef typename config::rng_type rng_type;
  241. typedef processor::processor<config> processor_type;
  242. typedef lib::shared_ptr<processor_type> processor_ptr;
  243. // Message handler (needs to know message type)
  244. typedef lib::function<void(connection_hdl,message_ptr)> message_handler;
  245. /// Type of a pointer to a transport timer handle
  246. typedef typename transport_con_type::timer_ptr timer_ptr;
  247. // Misc Convenience Types
  248. typedef session::internal_state::value istate_type;
  249. private:
  250. enum terminate_status {
  251. failed = 1,
  252. closed,
  253. unknown
  254. };
  255. public:
  256. explicit connection(bool p_is_server, std::string const & ua, alog_type& alog,
  257. elog_type& elog, rng_type & rng)
  258. : transport_con_type(p_is_server, alog, elog)
  259. , m_handle_read_frame(lib::bind(
  260. &type::handle_read_frame,
  261. this,
  262. lib::placeholders::_1,
  263. lib::placeholders::_2
  264. ))
  265. , m_write_frame_handler(lib::bind(
  266. &type::handle_write_frame,
  267. this,
  268. lib::placeholders::_1
  269. ))
  270. , m_user_agent(ua)
  271. , m_open_handshake_timeout_dur(config::timeout_open_handshake)
  272. , m_close_handshake_timeout_dur(config::timeout_close_handshake)
  273. , m_pong_timeout_dur(config::timeout_pong)
  274. , m_max_message_size(config::max_message_size)
  275. , m_state(session::state::connecting)
  276. , m_internal_state(session::internal_state::USER_INIT)
  277. , m_msg_manager(new con_msg_manager_type())
  278. , m_send_buffer_size(0)
  279. , m_write_flag(false)
  280. , m_read_flag(true)
  281. , m_is_server(p_is_server)
  282. , m_alog(alog)
  283. , m_elog(elog)
  284. , m_rng(rng)
  285. , m_local_close_code(close::status::abnormal_close)
  286. , m_remote_close_code(close::status::abnormal_close)
  287. , m_is_http(false)
  288. , m_http_state(session::http_state::init)
  289. , m_was_clean(false)
  290. {
  291. m_alog.write(log::alevel::devel,"connection constructor");
  292. }
  293. /// Get a shared pointer to this component
  294. ptr get_shared() {
  295. return lib::static_pointer_cast<type>(transport_con_type::get_shared());
  296. }
  297. ///////////////////////////
  298. // Set Handler Callbacks //
  299. ///////////////////////////
  300. /// Set open handler
  301. /**
  302. * The open handler is called after the WebSocket handshake is complete and
  303. * the connection is considered OPEN.
  304. *
  305. * @param h The new open_handler
  306. */
  307. void set_open_handler(open_handler h) {
  308. m_open_handler = h;
  309. }
  310. /// Set close handler
  311. /**
  312. * The close handler is called immediately after the connection is closed.
  313. *
  314. * @param h The new close_handler
  315. */
  316. void set_close_handler(close_handler h) {
  317. m_close_handler = h;
  318. }
  319. /// Set fail handler
  320. /**
  321. * The fail handler is called whenever the connection fails while the
  322. * handshake is bring processed.
  323. *
  324. * @param h The new fail_handler
  325. */
  326. void set_fail_handler(fail_handler h) {
  327. m_fail_handler = h;
  328. }
  329. /// Set ping handler
  330. /**
  331. * The ping handler is called whenever the connection receives a ping
  332. * control frame. The ping payload is included.
  333. *
  334. * The ping handler's return time controls whether or not a pong is
  335. * sent in response to this ping. Returning false will suppress the
  336. * return pong. If no ping handler is set a pong will be sent.
  337. *
  338. * @param h The new ping_handler
  339. */
  340. void set_ping_handler(ping_handler h) {
  341. m_ping_handler = h;
  342. }
  343. /// Set pong handler
  344. /**
  345. * The pong handler is called whenever the connection receives a pong
  346. * control frame. The pong payload is included.
  347. *
  348. * @param h The new pong_handler
  349. */
  350. void set_pong_handler(pong_handler h) {
  351. m_pong_handler = h;
  352. }
  353. /// Set pong timeout handler
  354. /**
  355. * If the transport component being used supports timers, the pong timeout
  356. * handler is called whenever a pong control frame is not received with the
  357. * configured timeout period after the application sends a ping.
  358. *
  359. * The config setting `timeout_pong` controls the length of the timeout
  360. * period. It is specified in milliseconds.
  361. *
  362. * This can be used to probe the health of the remote endpoint's WebSocket
  363. * implementation. This does not guarantee that the remote application
  364. * itself is still healthy but can be a useful diagnostic.
  365. *
  366. * Note: receipt of this callback doesn't mean the pong will never come.
  367. * This functionality will not suppress delivery of the pong in question
  368. * should it arrive after the timeout.
  369. *
  370. * @param h The new pong_timeout_handler
  371. */
  372. void set_pong_timeout_handler(pong_timeout_handler h) {
  373. m_pong_timeout_handler = h;
  374. }
  375. /// Set interrupt handler
  376. /**
  377. * The interrupt handler is called whenever the connection is manually
  378. * interrupted by the application.
  379. *
  380. * @param h The new interrupt_handler
  381. */
  382. void set_interrupt_handler(interrupt_handler h) {
  383. m_interrupt_handler = h;
  384. }
  385. /// Set http handler
  386. /**
  387. * The http handler is called after an HTTP request other than a WebSocket
  388. * upgrade request is received. It allows a WebSocket++ server to respond
  389. * to regular HTTP requests on the same port as it processes WebSocket
  390. * connections. This can be useful for hosting error messages, flash
  391. * policy files, status pages, and other simple HTTP responses. It is not
  392. * intended to be used as a primary web server.
  393. *
  394. * @param h The new http_handler
  395. */
  396. void set_http_handler(http_handler h) {
  397. m_http_handler = h;
  398. }
  399. /// Set validate handler
  400. /**
  401. * The validate handler is called after a WebSocket handshake has been
  402. * parsed but before a response is returned. It provides the application
  403. * a chance to examine the request and determine whether or not it wants
  404. * to accept the connection.
  405. *
  406. * Returning false from the validate handler will reject the connection.
  407. * If no validate handler is present, all connections will be allowed.
  408. *
  409. * @param h The new validate_handler
  410. */
  411. void set_validate_handler(validate_handler h) {
  412. m_validate_handler = h;
  413. }
  414. /// Set message handler
  415. /**
  416. * The message handler is called after a new message has been received.
  417. *
  418. * @param h The new message_handler
  419. */
  420. void set_message_handler(message_handler h) {
  421. m_message_handler = h;
  422. }
  423. //////////////////////////////////////////
  424. // Connection timeouts and other limits //
  425. //////////////////////////////////////////
  426. /// Set open handshake timeout
  427. /**
  428. * Sets the length of time the library will wait after an opening handshake
  429. * has been initiated before cancelling it. This can be used to prevent
  430. * excessive wait times for outgoing clients or excessive resource usage
  431. * from broken clients or DoS attacks on servers.
  432. *
  433. * Connections that time out will have their fail handlers called with the
  434. * open_handshake_timeout error code.
  435. *
  436. * The default value is specified via the compile time config value
  437. * 'timeout_open_handshake'. The default value in the core config
  438. * is 5000ms. A value of 0 will disable the timer entirely.
  439. *
  440. * To be effective, the transport you are using must support timers. See
  441. * the documentation for your transport policy for details about its
  442. * timer support.
  443. *
  444. * @param dur The length of the open handshake timeout in ms
  445. */
  446. void set_open_handshake_timeout(long dur) {
  447. m_open_handshake_timeout_dur = dur;
  448. }
  449. /// Set close handshake timeout
  450. /**
  451. * Sets the length of time the library will wait after a closing handshake
  452. * has been initiated before cancelling it. This can be used to prevent
  453. * excessive wait times for outgoing clients or excessive resource usage
  454. * from broken clients or DoS attacks on servers.
  455. *
  456. * Connections that time out will have their close handlers called with the
  457. * close_handshake_timeout error code.
  458. *
  459. * The default value is specified via the compile time config value
  460. * 'timeout_close_handshake'. The default value in the core config
  461. * is 5000ms. A value of 0 will disable the timer entirely.
  462. *
  463. * To be effective, the transport you are using must support timers. See
  464. * the documentation for your transport policy for details about its
  465. * timer support.
  466. *
  467. * @param dur The length of the close handshake timeout in ms
  468. */
  469. void set_close_handshake_timeout(long dur) {
  470. m_close_handshake_timeout_dur = dur;
  471. }
  472. /// Set pong timeout
  473. /**
  474. * Sets the length of time the library will wait for a pong response to a
  475. * ping. This can be used as a keepalive or to detect broken connections.
  476. *
  477. * Pong responses that time out will have the pong timeout handler called.
  478. *
  479. * The default value is specified via the compile time config value
  480. * 'timeout_pong'. The default value in the core config
  481. * is 5000ms. A value of 0 will disable the timer entirely.
  482. *
  483. * To be effective, the transport you are using must support timers. See
  484. * the documentation for your transport policy for details about its
  485. * timer support.
  486. *
  487. * @param dur The length of the pong timeout in ms
  488. */
  489. void set_pong_timeout(long dur) {
  490. m_pong_timeout_dur = dur;
  491. }
  492. /// Get maximum message size
  493. /**
  494. * Get maximum message size. Maximum message size determines the point at
  495. * which the connection will fail with the message_too_big protocol error.
  496. *
  497. * The default is set by the endpoint that creates the connection.
  498. *
  499. * @since 0.3.0
  500. */
  501. size_t get_max_message_size() const {
  502. return m_max_message_size;
  503. }
  504. /// Set maximum message size
  505. /**
  506. * Set maximum message size. Maximum message size determines the point at
  507. * which the connection will fail with the message_too_big protocol error.
  508. * This value may be changed during the connection.
  509. *
  510. * The default is set by the endpoint that creates the connection.
  511. *
  512. * @since 0.3.0
  513. *
  514. * @param new_value The value to set as the maximum message size.
  515. */
  516. void set_max_message_size(size_t new_value) {
  517. m_max_message_size = new_value;
  518. if (m_processor) {
  519. m_processor->set_max_message_size(new_value);
  520. }
  521. }
  522. /// Get maximum HTTP message body size
  523. /**
  524. * Get maximum HTTP message body size. Maximum message body size determines
  525. * the point at which the connection will stop reading an HTTP request whose
  526. * body is too large.
  527. *
  528. * The default is set by the endpoint that creates the connection.
  529. *
  530. * @since 0.5.0
  531. *
  532. * @return The maximum HTTP message body size
  533. */
  534. size_t get_max_http_body_size() const {
  535. return m_request.get_max_body_size();
  536. }
  537. /// Set maximum HTTP message body size
  538. /**
  539. * Set maximum HTTP message body size. Maximum message body size determines
  540. * the point at which the connection will stop reading an HTTP request whose
  541. * body is too large.
  542. *
  543. * The default is set by the endpoint that creates the connection.
  544. *
  545. * @since 0.5.0
  546. *
  547. * @param new_value The value to set as the maximum message size.
  548. */
  549. void set_max_http_body_size(size_t new_value) {
  550. m_request.set_max_body_size(new_value);
  551. }
  552. //////////////////////////////////
  553. // Uncategorized public methods //
  554. //////////////////////////////////
  555. /// Get the size of the outgoing write buffer (in payload bytes)
  556. /**
  557. * Retrieves the number of bytes in the outgoing write buffer that have not
  558. * already been dispatched to the transport layer. This represents the bytes
  559. * that are presently cancelable without uncleanly ending the websocket
  560. * connection
  561. *
  562. * This method invokes the m_write_lock mutex
  563. *
  564. * @return The current number of bytes in the outgoing send buffer.
  565. */
  566. size_t get_buffered_amount() const;
  567. /// DEPRECATED: use get_buffered_amount instead
  568. size_t buffered_amount() const {
  569. return get_buffered_amount();
  570. }
  571. ////////////////////
  572. // Action Methods //
  573. ////////////////////
  574. /// Create a message and then add it to the outgoing send queue
  575. /**
  576. * Convenience method to send a message given a payload string and
  577. * optionally an opcode. Default opcode is utf8 text.
  578. *
  579. * This method locks the m_write_lock mutex
  580. *
  581. * @param payload The payload string to generated the message with
  582. *
  583. * @param op The opcode to generated the message with. Default is
  584. * frame::opcode::text
  585. */
  586. lib::error_code send(std::string const & payload, frame::opcode::value op =
  587. frame::opcode::text);
  588. /// Send a message (raw array overload)
  589. /**
  590. * Convenience method to send a message given a raw array and optionally an
  591. * opcode. Default opcode is binary.
  592. *
  593. * This method locks the m_write_lock mutex
  594. *
  595. * @param payload A pointer to the array containing the bytes to send.
  596. *
  597. * @param len Length of the array.
  598. *
  599. * @param op The opcode to generated the message with. Default is
  600. * frame::opcode::binary
  601. */
  602. lib::error_code send(void const * payload, size_t len, frame::opcode::value
  603. op = frame::opcode::binary);
  604. /// Add a message to the outgoing send queue
  605. /**
  606. * If presented with a prepared message it is added without validation or
  607. * framing. If presented with an unprepared message it is validated, framed,
  608. * and then added
  609. *
  610. * Errors are returned via an exception
  611. * \todo make exception system_error rather than error_code
  612. *
  613. * This method invokes the m_write_lock mutex
  614. *
  615. * @param msg A message_ptr to the message to send.
  616. */
  617. lib::error_code send(message_ptr msg);
  618. /// Asyncronously invoke handler::on_inturrupt
  619. /**
  620. * Signals to the connection to asyncronously invoke the on_inturrupt
  621. * callback for this connection's handler once it is safe to do so.
  622. *
  623. * When the on_inturrupt handler callback is called it will be from
  624. * within the transport event loop with all the thread safety features
  625. * guaranteed by the transport to regular handlers
  626. *
  627. * Multiple inturrupt signals can be active at once on the same connection
  628. *
  629. * @return An error code
  630. */
  631. lib::error_code interrupt();
  632. /// Transport inturrupt callback
  633. void handle_interrupt();
  634. /// Pause reading of new data
  635. /**
  636. * Signals to the connection to halt reading of new data. While reading is paused,
  637. * the connection will stop reading from its associated socket. In turn this will
  638. * result in TCP based flow control kicking in and slowing data flow from the remote
  639. * endpoint.
  640. *
  641. * This is useful for applications that push new requests to a queue to be processed
  642. * by another thread and need a way to signal when their request queue is full without
  643. * blocking the network processing thread.
  644. *
  645. * Use `resume_reading()` to resume.
  646. *
  647. * If supported by the transport this is done asynchronously. As such reading may not
  648. * stop until the current read operation completes. Typically you can expect to
  649. * receive no more bytes after initiating a read pause than the size of the read
  650. * buffer.
  651. *
  652. * If reading is paused for this connection already nothing is changed.
  653. */
  654. lib::error_code pause_reading();
  655. /// Pause reading callback
  656. void handle_pause_reading();
  657. /// Resume reading of new data
  658. /**
  659. * Signals to the connection to resume reading of new data after it was paused by
  660. * `pause_reading()`.
  661. *
  662. * If reading is not paused for this connection already nothing is changed.
  663. */
  664. lib::error_code resume_reading();
  665. /// Resume reading callback
  666. void handle_resume_reading();
  667. /// Send a ping
  668. /**
  669. * Initiates a ping with the given payload/
  670. *
  671. * There is no feedback directly from ping except in cases of immediately
  672. * detectable errors. Feedback will be provided via on_pong or
  673. * on_pong_timeout callbacks.
  674. *
  675. * Ping locks the m_write_lock mutex
  676. *
  677. * @param payload Payload to be used for the ping
  678. */
  679. void ping(std::string const & payload);
  680. /// exception free variant of ping
  681. void ping(std::string const & payload, lib::error_code & ec);
  682. /// Utility method that gets called back when the ping timer expires
  683. void handle_pong_timeout(std::string payload, lib::error_code const & ec);
  684. /// Send a pong
  685. /**
  686. * Initiates a pong with the given payload.
  687. *
  688. * There is no feedback from a pong once sent.
  689. *
  690. * Pong locks the m_write_lock mutex
  691. *
  692. * @param payload Payload to be used for the pong
  693. */
  694. void pong(std::string const & payload);
  695. /// exception free variant of pong
  696. void pong(std::string const & payload, lib::error_code & ec);
  697. /// Close the connection
  698. /**
  699. * Initiates the close handshake process.
  700. *
  701. * If close returns successfully the connection will be in the closing
  702. * state and no additional messages may be sent. All messages sent prior
  703. * to calling close will be written out before the connection is closed.
  704. *
  705. * If no reason is specified none will be sent. If no code is specified
  706. * then no code will be sent.
  707. *
  708. * The handler's on_close callback will be called once the close handshake
  709. * is complete.
  710. *
  711. * Reasons will be automatically truncated to the maximum length (123 bytes)
  712. * if necessary.
  713. *
  714. * @param code The close code to send
  715. * @param reason The close reason to send
  716. */
  717. void close(close::status::value const code, std::string const & reason);
  718. /// exception free variant of close
  719. void close(close::status::value const code, std::string const & reason,
  720. lib::error_code & ec);
  721. ////////////////////////////////////////////////
  722. // Pass-through access to the uri information //
  723. ////////////////////////////////////////////////
  724. /// Returns the secure flag from the connection URI
  725. /**
  726. * This value is available after the HTTP request has been fully read and
  727. * may be called from any thread.
  728. *
  729. * @return Whether or not the connection URI is flagged secure.
  730. */
  731. bool get_secure() const;
  732. /// Returns the host component of the connection URI
  733. /**
  734. * This value is available after the HTTP request has been fully read and
  735. * may be called from any thread.
  736. *
  737. * @return The host component of the connection URI
  738. */
  739. std::string const & get_host() const;
  740. /// Returns the resource component of the connection URI
  741. /**
  742. * This value is available after the HTTP request has been fully read and
  743. * may be called from any thread.
  744. *
  745. * @return The resource component of the connection URI
  746. */
  747. std::string const & get_resource() const;
  748. /// Returns the port component of the connection URI
  749. /**
  750. * This value is available after the HTTP request has been fully read and
  751. * may be called from any thread.
  752. *
  753. * @return The port component of the connection URI
  754. */
  755. uint16_t get_port() const;
  756. /// Gets the connection URI
  757. /**
  758. * This should really only be called by internal library methods unless you
  759. * really know what you are doing.
  760. *
  761. * @return A pointer to the connection's URI
  762. */
  763. uri_ptr get_uri() const;
  764. /// Sets the connection URI
  765. /**
  766. * This should really only be called by internal library methods unless you
  767. * really know what you are doing.
  768. *
  769. * @param uri The new URI to set
  770. */
  771. void set_uri(uri_ptr uri);
  772. /////////////////////////////
  773. // Subprotocol negotiation //
  774. /////////////////////////////
  775. /// Gets the negotated subprotocol
  776. /**
  777. * Retrieves the subprotocol that was negotiated during the handshake. This
  778. * method is valid in the open handler and later.
  779. *
  780. * @return The negotiated subprotocol
  781. */
  782. std::string const & get_subprotocol() const;
  783. /// Gets all of the subprotocols requested by the client
  784. /**
  785. * Retrieves the subprotocols that were requested during the handshake. This
  786. * method is valid in the validate handler and later.
  787. *
  788. * @return A vector of the requested subprotocol
  789. */
  790. std::vector<std::string> const & get_requested_subprotocols() const;
  791. /// Adds the given subprotocol string to the request list (exception free)
  792. /**
  793. * Adds a subprotocol to the list to send with the opening handshake. This
  794. * may be called multiple times to request more than one. If the server
  795. * supports one of these, it may choose one. If so, it will return it
  796. * in it's handshake reponse and the value will be available via
  797. * get_subprotocol(). Subprotocol requests should be added in order of
  798. * preference.
  799. *
  800. * @param request The subprotocol to request
  801. * @param ec A reference to an error code that will be filled in the case of
  802. * errors
  803. */
  804. void add_subprotocol(std::string const & request, lib::error_code & ec);
  805. /// Adds the given subprotocol string to the request list
  806. /**
  807. * Adds a subprotocol to the list to send with the opening handshake. This
  808. * may be called multiple times to request more than one. If the server
  809. * supports one of these, it may choose one. If so, it will return it
  810. * in it's handshake reponse and the value will be available via
  811. * get_subprotocol(). Subprotocol requests should be added in order of
  812. * preference.
  813. *
  814. * @param request The subprotocol to request
  815. */
  816. void add_subprotocol(std::string const & request);
  817. /// Select a subprotocol to use (exception free)
  818. /**
  819. * Indicates which subprotocol should be used for this connection. Valid
  820. * only during the validate handler callback. Subprotocol selected must have
  821. * been requested by the client. Consult get_requested_subprotocols() for a
  822. * list of valid subprotocols.
  823. *
  824. * This member function is valid on server endpoints/connections only
  825. *
  826. * @param value The subprotocol to select
  827. * @param ec A reference to an error code that will be filled in the case of
  828. * errors
  829. */
  830. void select_subprotocol(std::string const & value, lib::error_code & ec);
  831. /// Select a subprotocol to use
  832. /**
  833. * Indicates which subprotocol should be used for this connection. Valid
  834. * only during the validate handler callback. Subprotocol selected must have
  835. * been requested by the client. Consult get_requested_subprotocols() for a
  836. * list of valid subprotocols.
  837. *
  838. * This member function is valid on server endpoints/connections only
  839. *
  840. * @param value The subprotocol to select
  841. */
  842. void select_subprotocol(std::string const & value);
  843. /////////////////////////////////////////////////////////////
  844. // Pass-through access to the request and response objects //
  845. /////////////////////////////////////////////////////////////
  846. /// Retrieve a request header
  847. /**
  848. * Retrieve the value of a header from the handshake HTTP request.
  849. *
  850. * @param key Name of the header to get
  851. * @return The value of the header
  852. */
  853. std::string const & get_request_header(std::string const & key) const;
  854. /// Retrieve a request body
  855. /**
  856. * Retrieve the value of the request body. This value is typically used with
  857. * PUT and POST requests to upload files or other data. Only HTTP
  858. * connections will ever have bodies. WebSocket connection's will always
  859. * have blank bodies.
  860. *
  861. * @return The value of the request body.
  862. */
  863. std::string const & get_request_body() const;
  864. /// Retrieve a response header
  865. /**
  866. * Retrieve the value of a header from the handshake HTTP request.
  867. *
  868. * @param key Name of the header to get
  869. * @return The value of the header
  870. */
  871. std::string const & get_response_header(std::string const & key) const;
  872. /// Set response status code and message
  873. /**
  874. * Sets the response status code to `code` and looks up the corresponding
  875. * message for standard codes. Non-standard codes will be entered as Unknown
  876. * use set_status(status_code::value,std::string) overload to set both
  877. * values explicitly.
  878. *
  879. * This member function is valid only from the http() and validate() handler
  880. * callbacks.
  881. *
  882. * @param code Code to set
  883. * @param msg Message to set
  884. * @see websocketpp::http::response::set_status
  885. */
  886. void set_status(http::status_code::value code);
  887. /// Set response status code and message
  888. /**
  889. * Sets the response status code and message to independent custom values.
  890. * use set_status(status_code::value) to set the code and have the standard
  891. * message be automatically set.
  892. *
  893. * This member function is valid only from the http() and validate() handler
  894. * callbacks.
  895. *
  896. * @param code Code to set
  897. * @param msg Message to set
  898. * @see websocketpp::http::response::set_status
  899. */
  900. void set_status(http::status_code::value code, std::string const & msg);
  901. /// Set response body content
  902. /**
  903. * Set the body content of the HTTP response to the parameter string. Note
  904. * set_body will also set the Content-Length HTTP header to the appropriate
  905. * value. If you want the Content-Length header to be something else set it
  906. * to something else after calling set_body
  907. *
  908. * This member function is valid only from the http() and validate() handler
  909. * callbacks.
  910. *
  911. * @param value String data to include as the body content.
  912. * @see websocketpp::http::response::set_body
  913. */
  914. void set_body(std::string const & value);
  915. /// Append a header
  916. /**
  917. * If a header with this name already exists the value will be appended to
  918. * the existing header to form a comma separated list of values. Use
  919. * `connection::replace_header` to overwrite existing values.
  920. *
  921. * This member function is valid only from the http() and validate() handler
  922. * callbacks, or to a client connection before connect has been called.
  923. *
  924. * @param key Name of the header to set
  925. * @param val Value to add
  926. * @see replace_header
  927. * @see websocketpp::http::parser::append_header
  928. */
  929. void append_header(std::string const & key, std::string const & val);
  930. /// Replace a header
  931. /**
  932. * If a header with this name already exists the old value will be replaced
  933. * Use `connection::append_header` to append to a list of existing values.
  934. *
  935. * This member function is valid only from the http() and validate() handler
  936. * callbacks, or to a client connection before connect has been called.
  937. *
  938. * @param key Name of the header to set
  939. * @param val Value to set
  940. * @see append_header
  941. * @see websocketpp::http::parser::replace_header
  942. */
  943. void replace_header(std::string const & key, std::string const & val);
  944. /// Remove a header
  945. /**
  946. * Removes a header from the response.
  947. *
  948. * This member function is valid only from the http() and validate() handler
  949. * callbacks, or to a client connection before connect has been called.
  950. *
  951. * @param key The name of the header to remove
  952. * @see websocketpp::http::parser::remove_header
  953. */
  954. void remove_header(std::string const & key);
  955. /// Get request object
  956. /**
  957. * Direct access to request object. This can be used to call methods of the
  958. * request object that are not part of the standard request API that
  959. * connection wraps.
  960. *
  961. * Note use of this method involves using behavior specific to the
  962. * configured HTTP policy. Such behavior may not work with alternate HTTP
  963. * policies.
  964. *
  965. * @since 0.3.0-alpha3
  966. *
  967. * @return A const reference to the raw request object
  968. */
  969. request_type const & get_request() const {
  970. return m_request;
  971. }
  972. /// Defer HTTP Response until later (Exception free)
  973. /**
  974. * Used in the http handler to defer the HTTP response for this connection
  975. * until later. Handshake timers will be canceled and the connection will be
  976. * left open until `send_http_response` or an equivalent is called.
  977. *
  978. * Warning: deferred connections won't time out and as a result can tie up
  979. * resources.
  980. *
  981. * @since 0.6.0
  982. *
  983. * @return A status code, zero on success, non-zero otherwise
  984. */
  985. lib::error_code defer_http_response();
  986. /// Send deferred HTTP Response (exception free)
  987. /**
  988. * Sends an http response to an HTTP connection that was deferred. This will
  989. * send a complete response including all headers, status line, and body
  990. * text. The connection will be closed afterwards.
  991. *
  992. * @since 0.6.0
  993. *
  994. * @param ec A status code, zero on success, non-zero otherwise
  995. */
  996. void send_http_response(lib::error_code & ec);
  997. /// Send deferred HTTP Response
  998. void send_http_response();
  999. // TODO HTTPNBIO: write_headers
  1000. // function that processes headers + status so far and writes it to the wire
  1001. // beginning the HTTP response body state. This method will ignore anything
  1002. // in the response body.
  1003. // TODO HTTPNBIO: write_body_message
  1004. // queues the specified message_buffer for async writing
  1005. // TODO HTTPNBIO: finish connection
  1006. //
  1007. // TODO HTTPNBIO: write_response
  1008. // Writes the whole response, headers + body and closes the connection
  1009. /////////////////////////////////////////////////////////////
  1010. // Pass-through access to the other connection information //
  1011. /////////////////////////////////////////////////////////////
  1012. /// Get Connection Handle
  1013. /**
  1014. * The connection handle is a token that can be shared outside the
  1015. * WebSocket++ core for the purposes of identifying a connection and
  1016. * sending it messages.
  1017. *
  1018. * @return A handle to the connection
  1019. */
  1020. connection_hdl get_handle() const {
  1021. return m_connection_hdl;
  1022. }
  1023. /// Get whether or not this connection is part of a server or client
  1024. /**
  1025. * @return whether or not the connection is attached to a server endpoint
  1026. */
  1027. bool is_server() const {
  1028. return m_is_server;
  1029. }
  1030. /// Return the same origin policy origin value from the opening request.
  1031. /**
  1032. * This value is available after the HTTP request has been fully read and
  1033. * may be called from any thread.
  1034. *
  1035. * @return The connection's origin value from the opening handshake.
  1036. */
  1037. std::string const & get_origin() const;
  1038. /// Return the connection state.
  1039. /**
  1040. * Values can be connecting, open, closing, and closed
  1041. *
  1042. * @return The connection's current state.
  1043. */
  1044. session::state::value get_state() const;
  1045. /// Get the WebSocket close code sent by this endpoint.
  1046. /**
  1047. * @return The WebSocket close code sent by this endpoint.
  1048. */
  1049. close::status::value get_local_close_code() const {
  1050. return m_local_close_code;
  1051. }
  1052. /// Get the WebSocket close reason sent by this endpoint.
  1053. /**
  1054. * @return The WebSocket close reason sent by this endpoint.
  1055. */
  1056. std::string const & get_local_close_reason() const {
  1057. return m_local_close_reason;
  1058. }
  1059. /// Get the WebSocket close code sent by the remote endpoint.
  1060. /**
  1061. * @return The WebSocket close code sent by the remote endpoint.
  1062. */
  1063. close::status::value get_remote_close_code() const {
  1064. return m_remote_close_code;
  1065. }
  1066. /// Get the WebSocket close reason sent by the remote endpoint.
  1067. /**
  1068. * @return The WebSocket close reason sent by the remote endpoint.
  1069. */
  1070. std::string const & get_remote_close_reason() const {
  1071. return m_remote_close_reason;
  1072. }
  1073. /// Get the internal error code for a closed/failed connection
  1074. /**
  1075. * Retrieves a machine readable detailed error code indicating the reason
  1076. * that the connection was closed or failed. Valid only after the close or
  1077. * fail handler is called.
  1078. *
  1079. * @return Error code indicating the reason the connection was closed or
  1080. * failed
  1081. */
  1082. lib::error_code get_ec() const {
  1083. return m_ec;
  1084. }
  1085. ////////////////////////////////////////////////////////////////////////
  1086. // The remaining public member functions are for internal/policy use //
  1087. // only. Do not call from application code unless you understand what //
  1088. // you are doing. //
  1089. ////////////////////////////////////////////////////////////////////////
  1090. /// Set Connection Handle
  1091. /**
  1092. * The connection handle is a token that can be shared outside the
  1093. * WebSocket++ core for the purposes of identifying a connection and
  1094. * sending it messages.
  1095. *
  1096. * @param hdl A connection_hdl that the connection will use to refer
  1097. * to itself.
  1098. */
  1099. void set_handle(connection_hdl hdl) {
  1100. m_connection_hdl = hdl;
  1101. transport_con_type::set_handle(hdl);
  1102. }
  1103. /// Get a message buffer
  1104. /**
  1105. * Warning: The API related to directly sending message buffers may change
  1106. * before the 1.0 release. If you plan to use it, please keep an eye on any
  1107. * breaking changes notifications in future release notes. Also if you have
  1108. * any feedback about usage and capabilities now is a great time to provide
  1109. * it.
  1110. *
  1111. * Message buffers are used to store message payloads and other message
  1112. * metadata.
  1113. *
  1114. * The size parameter is a hint only. Your final payload does not need to
  1115. * match it. There may be some performance benefits if the initial size
  1116. * guess is equal to or slightly higher than the final payload size.
  1117. *
  1118. * @param op The opcode for the new message
  1119. * @param size A hint to optimize the initial allocation of payload space.
  1120. * @return A new message buffer
  1121. */
  1122. message_ptr get_message(websocketpp::frame::opcode::value op, size_t size)
  1123. const
  1124. {
  1125. return m_msg_manager->get_message(op, size);
  1126. }
  1127. void start();
  1128. void read_handshake(size_t num_bytes);
  1129. void handle_read_handshake(lib::error_code const & ec,
  1130. size_t bytes_transferred);
  1131. void handle_read_http_response(lib::error_code const & ec,
  1132. size_t bytes_transferred);
  1133. void handle_write_http_response(lib::error_code const & ec);
  1134. void handle_send_http_request(lib::error_code const & ec);
  1135. void handle_open_handshake_timeout(lib::error_code const & ec);
  1136. void handle_close_handshake_timeout(lib::error_code const & ec);
  1137. void handle_read_frame(lib::error_code const & ec, size_t bytes_transferred);
  1138. void read_frame();
  1139. /// Get array of WebSocket protocol versions that this connection supports.
  1140. std::vector<int> const & get_supported_versions() const;
  1141. /// Sets the handler for a terminating connection. Should only be used
  1142. /// internally by the endpoint class.
  1143. void set_termination_handler(termination_handler new_handler);
  1144. void terminate(lib::error_code const & ec);
  1145. void handle_terminate(terminate_status tstat, lib::error_code const & ec);
  1146. /// Checks if there are frames in the send queue and if there are sends one
  1147. /**
  1148. * \todo unit tests
  1149. *
  1150. * This method locks the m_write_lock mutex
  1151. */
  1152. void write_frame();
  1153. /// Process the results of a frame write operation and start the next write
  1154. /**
  1155. * \todo unit tests
  1156. *
  1157. * This method locks the m_write_lock mutex
  1158. *
  1159. * @param terminate Whether or not to terminate the connection upon
  1160. * completion of this write.
  1161. *
  1162. * @param ec A status code from the transport layer, zero on success,
  1163. * non-zero otherwise.
  1164. */
  1165. void handle_write_frame(lib::error_code const & ec);
  1166. protected:
  1167. void handle_transport_init(lib::error_code const & ec);
  1168. /// Set m_processor based on information in m_request. Set m_response
  1169. /// status and return an error code indicating status.
  1170. lib::error_code initialize_processor();
  1171. /// Perform WebSocket handshake validation of m_request using m_processor.
  1172. /// set m_response and return an error code indicating status.
  1173. lib::error_code process_handshake_request();
  1174. private:
  1175. /// Completes m_response, serializes it, and sends it out on the wire.
  1176. void write_http_response(lib::error_code const & ec);
  1177. /// Sends an opening WebSocket connect request
  1178. void send_http_request();
  1179. /// Alternate path for write_http_response in error conditions
  1180. void write_http_response_error(lib::error_code const & ec);
  1181. /// Process control message
  1182. /**
  1183. *
  1184. */
  1185. void process_control_frame(message_ptr msg);
  1186. /// Send close acknowledgement
  1187. /**
  1188. * If no arguments are present no close code/reason will be specified.
  1189. *
  1190. * Note: the close code/reason values provided here may be overrided by
  1191. * other settings (such as silent close).
  1192. *
  1193. * @param code The close code to send
  1194. * @param reason The close reason to send
  1195. * @return A status code, zero on success, non-zero otherwise
  1196. */
  1197. lib::error_code send_close_ack(close::status::value code =
  1198. close::status::blank, std::string const & reason = "");
  1199. /// Send close frame
  1200. /**
  1201. * If no arguments are present no close code/reason will be specified.
  1202. *
  1203. * Note: the close code/reason values provided here may be overrided by
  1204. * other settings (such as silent close).
  1205. *
  1206. * The ack flag determines what to do in the case of a blank status and
  1207. * whether or not to terminate the TCP connection after sending it.
  1208. *
  1209. * @param code The close code to send
  1210. * @param reason The close reason to send
  1211. * @param ack Whether or not this is an acknowledgement close frame
  1212. * @return A status code, zero on success, non-zero otherwise
  1213. */
  1214. lib::error_code send_close_frame(close::status::value code =
  1215. close::status::blank, std::string const & reason = "", bool ack = false,
  1216. bool terminal = false);
  1217. /// Get a pointer to a new WebSocket protocol processor for a given version
  1218. /**
  1219. * @param version Version number of the WebSocket protocol to get a
  1220. * processor for. Negative values indicate invalid/unknown versions and will
  1221. * always return a null ptr
  1222. *
  1223. * @return A shared_ptr to a new instance of the appropriate processor or a
  1224. * null ptr if there is no installed processor that matches the version
  1225. * number.
  1226. */
  1227. processor_ptr get_processor(int version) const;
  1228. /// Add a message to the write queue
  1229. /**
  1230. * Adds a message to the write queue and updates any associated shared state
  1231. *
  1232. * Must be called while holding m_write_lock
  1233. *
  1234. * @todo unit tests
  1235. *
  1236. * @param msg The message to push
  1237. */
  1238. void write_push(message_ptr msg);
  1239. /// Pop a message from the write queue
  1240. /**
  1241. * Removes and returns a message from the write queue and updates any
  1242. * associated shared state.
  1243. *
  1244. * Must be called while holding m_write_lock
  1245. *
  1246. * @todo unit tests
  1247. *
  1248. * @return the message_ptr at the front of the queue
  1249. */
  1250. message_ptr write_pop();
  1251. /// Prints information about the incoming connection to the access log
  1252. /**
  1253. * Prints information about the incoming connection to the access log.
  1254. * Includes: connection type, websocket version, remote endpoint, user agent
  1255. * path, status code.
  1256. */
  1257. void log_open_result();
  1258. /// Prints information about a connection being closed to the access log
  1259. /**
  1260. * Includes: local and remote close codes and reasons
  1261. */
  1262. void log_close_result();
  1263. /// Prints information about a connection being failed to the access log
  1264. /**
  1265. * Includes: error code and message for why it was failed
  1266. */
  1267. void log_fail_result();
  1268. /// Prints information about HTTP connections
  1269. /**
  1270. * Includes: TODO
  1271. */
  1272. void log_http_result();
  1273. /// Prints information about an arbitrary error code on the specified channel
  1274. template <typename error_type>
  1275. void log_err(log::level l, char const * msg, error_type const & ec) {
  1276. std::stringstream s;
  1277. s << msg << " error: " << ec << " (" << ec.message() << ")";
  1278. m_elog.write(l, s.str());
  1279. }
  1280. // internal handler functions
  1281. read_handler m_handle_read_frame;
  1282. write_frame_handler m_write_frame_handler;
  1283. // static settings
  1284. std::string const m_user_agent;
  1285. /// Pointer to the connection handle
  1286. connection_hdl m_connection_hdl;
  1287. /// Handler objects
  1288. open_handler m_open_handler;
  1289. close_handler m_close_handler;
  1290. fail_handler m_fail_handler;
  1291. ping_handler m_ping_handler;
  1292. pong_handler m_pong_handler;
  1293. pong_timeout_handler m_pong_timeout_handler;
  1294. interrupt_handler m_interrupt_handler;
  1295. http_handler m_http_handler;
  1296. validate_handler m_validate_handler;
  1297. message_handler m_message_handler;
  1298. /// constant values
  1299. long m_open_handshake_timeout_dur;
  1300. long m_close_handshake_timeout_dur;
  1301. long m_pong_timeout_dur;
  1302. size_t m_max_message_size;
  1303. /// External connection state
  1304. /**
  1305. * Lock: m_connection_state_lock
  1306. */
  1307. session::state::value m_state;
  1308. /// Internal connection state
  1309. /**
  1310. * Lock: m_connection_state_lock
  1311. */
  1312. istate_type m_internal_state;
  1313. mutable mutex_type m_connection_state_lock;
  1314. /// The lock used to protect the message queue
  1315. /**
  1316. * Serializes access to the write queue as well as shared state within the
  1317. * processor.
  1318. */
  1319. mutex_type m_write_lock;
  1320. // connection resources
  1321. char m_buf[config::connection_read_buffer_size];
  1322. size_t m_buf_cursor;
  1323. termination_handler m_termination_handler;
  1324. con_msg_manager_ptr m_msg_manager;
  1325. timer_ptr m_handshake_timer;
  1326. timer_ptr m_ping_timer;
  1327. /// @todo this is not memory efficient. this value is not used after the
  1328. /// handshake.
  1329. std::string m_handshake_buffer;
  1330. /// Pointer to the processor object for this connection
  1331. /**
  1332. * The processor provides functionality that is specific to the WebSocket
  1333. * protocol version that the client has negotiated. It also contains all of
  1334. * the state necessary to encode and decode the incoming and outgoing
  1335. * WebSocket byte streams
  1336. *
  1337. * Use of the prepare_data_frame method requires lock: m_write_lock
  1338. */
  1339. processor_ptr m_processor;
  1340. /// Queue of unsent outgoing messages
  1341. /**
  1342. * Lock: m_write_lock
  1343. */
  1344. std::queue<message_ptr> m_send_queue;
  1345. /// Size in bytes of the outstanding payloads in the write queue
  1346. /**
  1347. * Lock: m_write_lock
  1348. */
  1349. size_t m_send_buffer_size;
  1350. /// buffer holding the various parts of the current message being writen
  1351. /**
  1352. * Lock m_write_lock
  1353. */
  1354. std::vector<transport::buffer> m_send_buffer;
  1355. /// a list of pointers to hold on to the messages being written to keep them
  1356. /// from going out of scope before the write is complete.
  1357. std::vector<message_ptr> m_current_msgs;
  1358. /// True if there is currently an outstanding transport write
  1359. /**
  1360. * Lock m_write_lock
  1361. */
  1362. bool m_write_flag;
  1363. /// True if this connection is presently reading new data
  1364. bool m_read_flag;
  1365. // connection data
  1366. request_type m_request;
  1367. response_type m_response;
  1368. uri_ptr m_uri;
  1369. std::string m_subprotocol;
  1370. // connection data that might not be necessary to keep around for the life
  1371. // of the whole connection.
  1372. std::vector<std::string> m_requested_subprotocols;
  1373. bool const m_is_server;
  1374. alog_type& m_alog;
  1375. elog_type& m_elog;
  1376. rng_type & m_rng;
  1377. // Close state
  1378. /// Close code that was sent on the wire by this endpoint
  1379. close::status::value m_local_close_code;
  1380. /// Close reason that was sent on the wire by this endpoint
  1381. std::string m_local_close_reason;
  1382. /// Close code that was received on the wire from the remote endpoint
  1383. close::status::value m_remote_close_code;
  1384. /// Close reason that was received on the wire from the remote endpoint
  1385. std::string m_remote_close_reason;
  1386. /// Detailed internal error code
  1387. lib::error_code m_ec;
  1388. /// A flag that gets set once it is determined that the connection is an
  1389. /// HTTP connection and not a WebSocket one.
  1390. bool m_is_http;
  1391. /// A flag that gets set when the completion of an http connection is
  1392. /// deferred until later.
  1393. session::http_state::value m_http_state;
  1394. bool m_was_clean;
  1395. /// Whether or not this endpoint initiated the closing handshake.
  1396. bool m_closed_by_me;
  1397. /// ???
  1398. bool m_failed_by_me;
  1399. /// Whether or not this endpoint initiated the drop of the TCP connection
  1400. bool m_dropped_by_me;
  1401. };
  1402. } // namespace websocketpp
  1403. #include <websocketpp/impl/connection_impl.hpp>
  1404. #endif // WEBSOCKETPP_CONNECTION_HPP