stream.hpp 134 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639
  1. //
  2. // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_WEBSOCKET_STREAM_HPP
  10. #define BOOST_BEAST_WEBSOCKET_STREAM_HPP
  11. #include <boost/beast/core/detail/config.hpp>
  12. #include <boost/beast/websocket/error.hpp>
  13. #include <boost/beast/websocket/option.hpp>
  14. #include <boost/beast/websocket/role.hpp>
  15. #include <boost/beast/websocket/rfc6455.hpp>
  16. #include <boost/beast/websocket/stream_fwd.hpp>
  17. #include <boost/beast/websocket/detail/frame.hpp>
  18. #include <boost/beast/websocket/detail/hybi13.hpp>
  19. #include <boost/beast/websocket/detail/mask.hpp>
  20. #include <boost/beast/websocket/detail/pausation.hpp>
  21. #include <boost/beast/websocket/detail/pmd_extension.hpp>
  22. #include <boost/beast/websocket/detail/stream_base.hpp>
  23. #include <boost/beast/websocket/detail/utf8_checker.hpp>
  24. #include <boost/beast/core/static_buffer.hpp>
  25. #include <boost/beast/core/string.hpp>
  26. #include <boost/beast/core/detail/type_traits.hpp>
  27. #include <boost/beast/http/empty_body.hpp>
  28. #include <boost/beast/http/message.hpp>
  29. #include <boost/beast/http/string_body.hpp>
  30. #include <boost/beast/http/detail/type_traits.hpp>
  31. #include <boost/asio/async_result.hpp>
  32. #include <boost/asio/error.hpp>
  33. #include <algorithm>
  34. #include <cstdint>
  35. #include <functional>
  36. #include <limits>
  37. #include <type_traits>
  38. namespace boost {
  39. namespace beast {
  40. namespace websocket {
  41. /// The type of object holding HTTP Upgrade requests
  42. using request_type = http::request<http::empty_body>;
  43. /// The type of object holding HTTP Upgrade responses
  44. using response_type = http::response<http::string_body>;
  45. /** The type of received control frame.
  46. Values of this type are passed to the control frame
  47. callback set using @ref stream::control_callback.
  48. */
  49. enum class frame_type
  50. {
  51. /// A close frame was received
  52. close,
  53. /// A ping frame was received
  54. ping,
  55. /// A pong frame was received
  56. pong
  57. };
  58. namespace detail {
  59. class frame_test;
  60. } // detail
  61. //--------------------------------------------------------------------
  62. /** Provides message-oriented functionality using WebSocket.
  63. The @ref stream class template provides asynchronous and blocking
  64. message-oriented functionality necessary for clients and servers
  65. to utilize the WebSocket protocol.
  66. For asynchronous operations, the application must ensure
  67. that they are are all performed within the same implicit
  68. or explicit strand.
  69. @par Thread Safety
  70. @e Distinct @e objects: Safe.@n
  71. @e Shared @e objects: Unsafe.
  72. The application must also ensure that all asynchronous
  73. operations are performed within the same implicit or explicit strand.
  74. @par Example
  75. To use the @ref stream template with an `ip::tcp::socket`,
  76. you would write:
  77. @code
  78. websocket::stream<ip::tcp::socket> ws{io_context};
  79. @endcode
  80. Alternatively, you can write:
  81. @code
  82. ip::tcp::socket sock{io_context};
  83. websocket::stream<ip::tcp::socket&> ws{sock};
  84. @endcode
  85. @tparam NextLayer The type representing the next layer, to which
  86. data will be read and written during operations. For synchronous
  87. operations, the type must support the @b SyncStream concept.
  88. For asynchronous operations, the type must support the
  89. @b AsyncStream concept.
  90. @tparam deflateSupported A `bool` indicating whether or not the
  91. stream will be capable of negotiating the permessage-deflate websocket
  92. extension. Note that even if this is set to `true`, the permessage
  93. deflate options (set by the caller at runtime) must still have the
  94. feature enabled for a successful negotiation to occur.
  95. @note A stream object must not be moved or destroyed while there
  96. are pending asynchronous operations associated with it.
  97. @par Concepts
  98. @b AsyncStream,
  99. @b DynamicBuffer,
  100. @b SyncStream
  101. */
  102. template<
  103. class NextLayer,
  104. bool deflateSupported>
  105. class stream
  106. #if ! BOOST_BEAST_DOXYGEN
  107. : private detail::stream_base<deflateSupported>
  108. #endif
  109. {
  110. friend class close_test;
  111. friend class frame_test;
  112. friend class ping_test;
  113. friend class read1_test;
  114. friend class read2_test;
  115. friend class stream_test;
  116. friend class write_test;
  117. /* The read buffer has to be at least as large
  118. as the largest possible control frame including
  119. the frame header.
  120. */
  121. static std::size_t constexpr max_control_frame_size = 2 + 8 + 4 + 125;
  122. static std::size_t constexpr tcp_frame_size = 1536;
  123. using control_cb_type =
  124. std::function<void(frame_type, string_view)>;
  125. enum class status
  126. {
  127. open,
  128. closing,
  129. closed,
  130. failed
  131. };
  132. NextLayer stream_; // the wrapped stream
  133. close_reason cr_; // set from received close frame
  134. control_cb_type ctrl_cb_; // control callback
  135. std::size_t rd_msg_max_ // max message size
  136. = 16 * 1024 * 1024;
  137. std::uint64_t rd_size_ // total size of current message so far
  138. = 0;
  139. std::uint64_t rd_remain_ // message frame bytes left in current frame
  140. = 0;
  141. detail::frame_header rd_fh_; // current frame header
  142. detail::prepared_key rd_key_; // current stateful mask key
  143. detail::frame_buffer rd_fb_; // to write control frames (during reads)
  144. detail::utf8_checker rd_utf8_; // to validate utf8
  145. static_buffer<
  146. +tcp_frame_size> rd_buf_; // buffer for reads
  147. detail::opcode rd_op_ // current message binary or text
  148. = detail::opcode::text;
  149. bool rd_cont_ // `true` if the next frame is a continuation
  150. = false;
  151. bool rd_done_ // set when a message is done
  152. = true;
  153. bool rd_close_ // did we read a close frame?
  154. = false;
  155. detail::soft_mutex rd_block_; // op currently reading
  156. role_type role_ // server or client
  157. = role_type::client;
  158. status status_
  159. = status::closed;
  160. detail::soft_mutex wr_block_; // op currently writing
  161. bool wr_close_ // did we write a close frame?
  162. = false;
  163. bool wr_cont_ // next write is a continuation
  164. = false;
  165. bool wr_frag_ // autofrag the current message
  166. = false;
  167. bool wr_frag_opt_ // autofrag option setting
  168. = true;
  169. bool wr_compress_ // compress current message
  170. = false;
  171. detail::opcode wr_opcode_ // message type
  172. = detail::opcode::text;
  173. std::unique_ptr<
  174. std::uint8_t[]> wr_buf_; // write buffer
  175. std::size_t wr_buf_size_ // write buffer size (current message)
  176. = 0;
  177. std::size_t wr_buf_opt_ // write buffer size option setting
  178. = 4096;
  179. detail::fh_buffer wr_fb_; // header buffer used for writes
  180. detail::pausation paused_rd_; // paused read op
  181. detail::pausation paused_wr_; // paused write op
  182. detail::pausation paused_ping_; // paused ping op
  183. detail::pausation paused_close_; // paused close op
  184. detail::pausation paused_r_rd_; // paused read op (async read)
  185. detail::pausation paused_r_close_;// paused close op (async read)
  186. public:
  187. /// Indicates if the permessage-deflate extension is supported
  188. using is_deflate_supported =
  189. std::integral_constant<bool, deflateSupported>;
  190. /// The type of the next layer.
  191. using next_layer_type =
  192. typename std::remove_reference<NextLayer>::type;
  193. /// The type of the lowest layer.
  194. using lowest_layer_type = get_lowest_layer<next_layer_type>;
  195. /// The type of the executor associated with the object.
  196. using executor_type = typename next_layer_type::executor_type;
  197. /** Destructor
  198. Destroys the stream and all associated resources.
  199. @note A stream object must not be destroyed while there
  200. are pending asynchronous operations associated with it.
  201. */
  202. ~stream() = default;
  203. /** Constructor
  204. If `NextLayer` is move constructible, this function
  205. will move-construct a new stream from the existing stream.
  206. @note The behavior of move assignment on or from streams
  207. with active or pending operations is undefined.
  208. */
  209. stream(stream&&) = default;
  210. /** Assignment
  211. If `NextLayer` is move assignable, this function
  212. will move-assign a new stream from the existing stream.
  213. @note The behavior of move assignment on or from streams
  214. with active or pending operations is undefined.
  215. */
  216. stream& operator=(stream&&) = default;
  217. /** Constructor
  218. This constructor creates a websocket stream and initializes
  219. the next layer object.
  220. @throws Any exceptions thrown by the NextLayer constructor.
  221. @param args The arguments to be passed to initialize the
  222. next layer object. The arguments are forwarded to the next
  223. layer's constructor.
  224. */
  225. template<class... Args>
  226. explicit
  227. stream(Args&&... args);
  228. //--------------------------------------------------------------------------
  229. /** Get the executor associated with the object.
  230. This function may be used to obtain the executor object that the
  231. stream uses to dispatch handlers for asynchronous operations.
  232. @return A copy of the executor that stream will use to dispatch handlers.
  233. */
  234. executor_type
  235. get_executor() noexcept
  236. {
  237. return stream_.get_executor();
  238. }
  239. /** Get a reference to the next layer
  240. This function returns a reference to the next layer
  241. in a stack of stream layers.
  242. @return A reference to the next layer in the stack of
  243. stream layers.
  244. */
  245. next_layer_type&
  246. next_layer()
  247. {
  248. return stream_;
  249. }
  250. /** Get a reference to the next layer
  251. This function returns a reference to the next layer in a
  252. stack of stream layers.
  253. @return A reference to the next layer in the stack of
  254. stream layers.
  255. */
  256. next_layer_type const&
  257. next_layer() const
  258. {
  259. return stream_;
  260. }
  261. /** Get a reference to the lowest layer
  262. This function returns a reference to the lowest layer
  263. in a stack of stream layers.
  264. @return A reference to the lowest layer in the stack of
  265. stream layers.
  266. */
  267. lowest_layer_type&
  268. lowest_layer()
  269. {
  270. return stream_.lowest_layer();
  271. }
  272. /** Get a reference to the lowest layer
  273. This function returns a reference to the lowest layer
  274. in a stack of stream layers.
  275. @return A reference to the lowest layer in the stack of
  276. stream layers. Ownership is not transferred to the caller.
  277. */
  278. lowest_layer_type const&
  279. lowest_layer() const
  280. {
  281. return stream_.lowest_layer();
  282. }
  283. //--------------------------------------------------------------------------
  284. //
  285. // Observers
  286. //
  287. //--------------------------------------------------------------------------
  288. /** Returns `true` if the stream is open.
  289. The stream is open after a successful handshake, and when
  290. no error has occurred.
  291. */
  292. bool
  293. is_open() const
  294. {
  295. return status_ == status::open;
  296. }
  297. /** Returns `true` if the latest message data indicates binary.
  298. This function informs the caller of whether the last
  299. received message frame represents a message with the
  300. binary opcode.
  301. If there is no last message frame, the return value is
  302. undefined.
  303. */
  304. bool
  305. got_binary() const
  306. {
  307. return rd_op_ == detail::opcode::binary;
  308. }
  309. /** Returns `true` if the latest message data indicates text.
  310. This function informs the caller of whether the last
  311. received message frame represents a message with the
  312. text opcode.
  313. If there is no last message frame, the return value is
  314. undefined.
  315. */
  316. bool
  317. got_text() const
  318. {
  319. return ! got_binary();
  320. }
  321. /// Returns `true` if the last completed read finished the current message.
  322. bool
  323. is_message_done() const
  324. {
  325. return rd_done_;
  326. }
  327. /** Returns the close reason received from the peer.
  328. This is only valid after a read completes with error::closed.
  329. */
  330. close_reason const&
  331. reason() const
  332. {
  333. return cr_;
  334. }
  335. /** Returns a suggested maximum buffer size for the next call to read.
  336. This function returns a reasonable upper limit on the number
  337. of bytes for the size of the buffer passed in the next call
  338. to read. The number is determined by the state of the current
  339. frame and whether or not the permessage-deflate extension is
  340. enabled.
  341. @param initial_size A non-zero size representing the caller's
  342. desired buffer size for when there is no information which may
  343. be used to calculate a more specific value. For example, when
  344. reading the first frame header of a message.
  345. */
  346. std::size_t
  347. read_size_hint(
  348. std::size_t initial_size = +tcp_frame_size) const
  349. {
  350. return read_size_hint(initial_size,
  351. is_deflate_supported{});
  352. }
  353. /** Returns a suggested maximum buffer size for the next call to read.
  354. This function returns a reasonable upper limit on the number
  355. of bytes for the size of the buffer passed in the next call
  356. to read. The number is determined by the state of the current
  357. frame and whether or not the permessage-deflate extension is
  358. enabled.
  359. @param buffer The buffer which will be used for reading. The
  360. implementation will query the buffer to obtain the optimum
  361. size of a subsequent call to `buffer.prepare` based on the
  362. state of the current frame, if any.
  363. */
  364. template<class DynamicBuffer
  365. #if ! BOOST_BEAST_DOXYGEN
  366. , class = typename std::enable_if<
  367. ! std::is_integral<DynamicBuffer>::value>::type
  368. #endif
  369. >
  370. std::size_t
  371. read_size_hint(
  372. DynamicBuffer& buffer) const;
  373. //--------------------------------------------------------------------------
  374. //
  375. // Settings
  376. //
  377. //--------------------------------------------------------------------------
  378. /** Set the permessage-deflate extension options
  379. @throws invalid_argument if `deflateSupported == false`, and either
  380. `client_enable` or `server_enable` is `true`.
  381. */
  382. void
  383. set_option(permessage_deflate const& o)
  384. {
  385. set_option(o, is_deflate_supported{});
  386. }
  387. /// Get the permessage-deflate extension options
  388. void
  389. get_option(permessage_deflate& o)
  390. {
  391. get_option(o, is_deflate_supported{});
  392. }
  393. /** Set the automatic fragmentation option.
  394. Determines if outgoing message payloads are broken up into
  395. multiple pieces.
  396. When the automatic fragmentation size is turned on, outgoing
  397. message payloads are broken up into multiple frames no larger
  398. than the write buffer size.
  399. The default setting is to fragment messages.
  400. @param value A `bool` indicating if auto fragmentation should be on.
  401. @par Example
  402. Setting the automatic fragmentation option:
  403. @code
  404. ws.auto_fragment(true);
  405. @endcode
  406. */
  407. void
  408. auto_fragment(bool value)
  409. {
  410. wr_frag_opt_ = value;
  411. }
  412. /// Returns `true` if the automatic fragmentation option is set.
  413. bool
  414. auto_fragment() const
  415. {
  416. return wr_frag_opt_;
  417. }
  418. /** Set the binary message write option.
  419. This controls whether or not outgoing message opcodes
  420. are set to binary or text. The setting is only applied
  421. at the start when a caller begins a new message. Changing
  422. the opcode after a message is started will only take effect
  423. after the current message being sent is complete.
  424. The default setting is to send text messages.
  425. @param value `true` if outgoing messages should indicate
  426. binary, or `false` if they should indicate text.
  427. @par Example
  428. Setting the message type to binary.
  429. @code
  430. ws.binary(true);
  431. @endcode
  432. */
  433. void
  434. binary(bool value)
  435. {
  436. wr_opcode_ = value ?
  437. detail::opcode::binary :
  438. detail::opcode::text;
  439. }
  440. /// Returns `true` if the binary message write option is set.
  441. bool
  442. binary() const
  443. {
  444. return wr_opcode_ == detail::opcode::binary;
  445. }
  446. /** Set a callback to be invoked on each incoming control frame.
  447. Sets the callback to be invoked whenever a ping, pong,
  448. or close control frame is received during a call to one
  449. of the following functions:
  450. @li @ref beast::websocket::stream::read
  451. @li @ref beast::websocket::stream::read_some
  452. @li @ref beast::websocket::stream::async_read
  453. @li @ref beast::websocket::stream::async_read_some
  454. Unlike completion handlers, the callback will be invoked
  455. for each control frame during a call to any synchronous
  456. or asynchronous read function. The operation is passive,
  457. with no associated error code, and triggered by reads.
  458. For close frames, the close reason code may be obtained by
  459. calling the function @ref reason.
  460. @param cb The function object to call, which must be
  461. invocable with this equivalent signature:
  462. @code
  463. void
  464. callback(
  465. frame_type kind, // The type of frame
  466. string_view payload // The payload in the frame
  467. );
  468. @endcode
  469. The implementation type-erases the callback which may require
  470. a dynamic allocation. To prevent the possiblity of a dynamic
  471. allocation, use `std::ref` to wrap the callback.
  472. If the read operation which receives the control frame is
  473. an asynchronous operation, the callback will be invoked using
  474. the same method as that used to invoke the final handler.
  475. @note Incoming ping and close frames are automatically
  476. handled. Pings are responded to with pongs, and a close frame
  477. is responded to with a close frame leading to the closure of
  478. the stream. It is not necessary to manually send pings, pongs,
  479. or close frames from inside the control callback.
  480. Attempting to manually send a close frame from inside the
  481. control callback after receiving a close frame will result
  482. in undefined behavior.
  483. */
  484. void
  485. control_callback(std::function<void(frame_type, string_view)> cb)
  486. {
  487. ctrl_cb_ = std::move(cb);
  488. }
  489. /** Reset the control frame callback.
  490. This function removes any previously set control frame callback.
  491. */
  492. void
  493. control_callback()
  494. {
  495. ctrl_cb_ = {};
  496. }
  497. /** Set the maximum incoming message size option.
  498. Sets the largest permissible incoming message size. Message
  499. frame fields indicating a size that would bring the total
  500. message size over this limit will cause a protocol failure.
  501. The default setting is 16 megabytes. A value of zero indicates
  502. a limit of the maximum value of a `std::uint64_t`.
  503. @par Example
  504. Setting the maximum read message size.
  505. @code
  506. ws.read_message_max(65536);
  507. @endcode
  508. @param amount The limit on the size of incoming messages.
  509. */
  510. void
  511. read_message_max(std::size_t amount)
  512. {
  513. rd_msg_max_ = amount;
  514. }
  515. /// Returns the maximum incoming message size setting.
  516. std::size_t
  517. read_message_max() const
  518. {
  519. return rd_msg_max_;
  520. }
  521. /** Set whether the PRNG is cryptographically secure
  522. This controls whether or not the source of pseudo-random
  523. numbers used to produce the masks required by the WebSocket
  524. protocol are of cryptographic quality. When the setting is
  525. `true`, a strong algorithm is used which cannot be guessed
  526. by observing outputs. When the setting is `false`, a much
  527. faster algorithm is used.
  528. Masking is only performed by streams operating in the client
  529. mode. For streams operating in the server mode, this setting
  530. has no effect.
  531. By default, newly constructed streams use a secure PRNG.
  532. If the WebSocket stream is used with an encrypted SSL or TLS
  533. next layer, if it is known to the application that intermediate
  534. proxies are not vulnerable to cache poisoning, or if the
  535. application is designed such that an attacker cannot send
  536. arbitrary inputs to the stream interface, then the faster
  537. algorithm may be used.
  538. For more information please consult the WebSocket protocol RFC.
  539. @param value `true` if the PRNG algorithm should be
  540. cryptographically secure.
  541. */
  542. void
  543. secure_prng(bool value)
  544. {
  545. this->secure_prng_ = value;
  546. }
  547. /** Set the write buffer size option.
  548. Sets the size of the write buffer used by the implementation to
  549. send frames. The write buffer is needed when masking payload data
  550. in the client role, compressing frames, or auto-fragmenting message
  551. data.
  552. Lowering the size of the buffer can decrease the memory requirements
  553. for each connection, while increasing the size of the buffer can reduce
  554. the number of calls made to the next layer to write data.
  555. The default setting is 4096. The minimum value is 8.
  556. The write buffer size can only be changed when the stream is not
  557. open. Undefined behavior results if the option is modified after a
  558. successful WebSocket handshake.
  559. @par Example
  560. Setting the write buffer size.
  561. @code
  562. ws.write_buffer_size(8192);
  563. @endcode
  564. @param amount The size of the write buffer in bytes.
  565. */
  566. void
  567. write_buffer_size(std::size_t amount)
  568. {
  569. if(amount < 8)
  570. BOOST_THROW_EXCEPTION(std::invalid_argument{
  571. "write buffer size underflow"});
  572. wr_buf_opt_ = amount;
  573. };
  574. /// Returns the size of the write buffer.
  575. std::size_t
  576. write_buffer_size() const
  577. {
  578. return wr_buf_opt_;
  579. }
  580. /** Set the text message write option.
  581. This controls whether or not outgoing message opcodes
  582. are set to binary or text. The setting is only applied
  583. at the start when a caller begins a new message. Changing
  584. the opcode after a message is started will only take effect
  585. after the current message being sent is complete.
  586. The default setting is to send text messages.
  587. @param value `true` if outgoing messages should indicate
  588. text, or `false` if they should indicate binary.
  589. @par Example
  590. Setting the message type to text.
  591. @code
  592. ws.text(true);
  593. @endcode
  594. */
  595. void
  596. text(bool value)
  597. {
  598. wr_opcode_ = value ?
  599. detail::opcode::text :
  600. detail::opcode::binary;
  601. }
  602. /// Returns `true` if the text message write option is set.
  603. bool
  604. text() const
  605. {
  606. return wr_opcode_ == detail::opcode::text;
  607. }
  608. //--------------------------------------------------------------------------
  609. //
  610. // Handshaking (Client)
  611. //
  612. //--------------------------------------------------------------------------
  613. /** Send an HTTP WebSocket Upgrade request and receive the response.
  614. This function is used to synchronously send the WebSocket
  615. upgrade HTTP request. The call blocks until one of the
  616. following conditions is true:
  617. @li The request is sent and the response is received.
  618. @li An error occurs on the stream
  619. This function is implemented in terms of one or more calls to the
  620. next layer's `read_some` and `write_some` functions.
  621. The operation is successful if the received HTTP response indicates
  622. a successful HTTP Upgrade (represented by a Status-Code of 101,
  623. "switching protocols").
  624. @param host The name of the remote host,
  625. required by the HTTP protocol.
  626. @param target The Request Target, which may not be empty,
  627. required by the HTTP protocol.
  628. @throws system_error Thrown on failure.
  629. @par Example
  630. @code
  631. websocket::stream<ip::tcp::socket> ws{io_context};
  632. ...
  633. try
  634. {
  635. ws.handshake("localhost", "/");
  636. }
  637. catch(...)
  638. {
  639. // An error occurred.
  640. }
  641. @endcode
  642. */
  643. void
  644. handshake(
  645. string_view host,
  646. string_view target);
  647. /** Send an HTTP WebSocket Upgrade request and receive the response.
  648. This function is used to synchronously send the WebSocket
  649. upgrade HTTP request. The call blocks until one of the
  650. following conditions is true:
  651. @li The request is sent and the response is received.
  652. @li An error occurs on the stream
  653. This function is implemented in terms of one or more calls to the
  654. next layer's `read_some` and `write_some` functions.
  655. The operation is successful if the received HTTP response indicates
  656. a successful HTTP Upgrade (represented by a Status-Code of 101,
  657. "switching protocols").
  658. @param res The HTTP Upgrade response returned by the remote
  659. endpoint.
  660. @param host The name of the remote host,
  661. required by the HTTP protocol.
  662. @param target The Request Target, which may not be empty,
  663. required by the HTTP protocol.
  664. @throws system_error Thrown on failure.
  665. @par Example
  666. @code
  667. websocket::stream<ip::tcp::socket> ws{io_context};
  668. ...
  669. try
  670. {
  671. response_type res;
  672. ws.handshake(res, "localhost", "/");
  673. }
  674. catch(...)
  675. {
  676. // An error occurred.
  677. }
  678. @endcode
  679. */
  680. void
  681. handshake(
  682. response_type& res,
  683. string_view host,
  684. string_view target);
  685. /** Send an HTTP WebSocket Upgrade request and receive the response.
  686. This function is used to synchronously send the WebSocket
  687. upgrade HTTP request. The call blocks until one of the
  688. following conditions is true:
  689. @li The request is sent and the response is received.
  690. @li An error occurs on the stream
  691. This function is implemented in terms of one or more calls to the
  692. next layer's `read_some` and `write_some` functions.
  693. The operation is successful if the received HTTP response indicates
  694. a successful HTTP Upgrade (represented by a Status-Code of 101,
  695. "switching protocols").
  696. @param host The name of the remote host,
  697. required by the HTTP protocol.
  698. @param target The Request Target, which may not be empty,
  699. required by the HTTP protocol.
  700. @param decorator A function object which will be called to modify
  701. the HTTP request object generated by the implementation. This
  702. could be used to set the User-Agent field, subprotocols, or other
  703. application or HTTP specific fields. The object will be called
  704. with this equivalent signature:
  705. @code void decorator(
  706. request_type& req
  707. ); @endcode
  708. @throws system_error Thrown on failure.
  709. @par Example
  710. @code
  711. websocket::stream<ip::tcp::socket> ws{io_context};
  712. ...
  713. try
  714. {
  715. ws.handshake("localhost", "/",
  716. [](request_type& req)
  717. {
  718. req.set(field::user_agent, "Beast");
  719. });
  720. }
  721. catch(...)
  722. {
  723. // An error occurred.
  724. }
  725. @endcode
  726. */
  727. template<class RequestDecorator>
  728. void
  729. handshake_ex(
  730. string_view host,
  731. string_view target,
  732. RequestDecorator const& decorator);
  733. /** Send an HTTP WebSocket Upgrade request and receive the response.
  734. This function is used to synchronously send the WebSocket
  735. upgrade HTTP request. The call blocks until one of the
  736. following conditions is true:
  737. @li The request is sent and the response is received.
  738. @li An error occurs on the stream
  739. This function is implemented in terms of one or more calls to the
  740. next layer's `read_some` and `write_some` functions.
  741. The operation is successful if the received HTTP response indicates
  742. a successful HTTP Upgrade (represented by a Status-Code of 101,
  743. "switching protocols").
  744. @param res The HTTP Upgrade response returned by the remote
  745. endpoint.
  746. @param host The name of the remote host,
  747. required by the HTTP protocol.
  748. @param target The Request Target, which may not be empty,
  749. required by the HTTP protocol.
  750. @param decorator A function object which will be called to modify
  751. the HTTP request object generated by the implementation. This
  752. could be used to set the User-Agent field, subprotocols, or other
  753. application or HTTP specific fields. The object will be called
  754. with this equivalent signature:
  755. @code void decorator(
  756. request_type& req
  757. ); @endcode
  758. @throws system_error Thrown on failure.
  759. @par Example
  760. @code
  761. websocket::stream<ip::tcp::socket> ws{io_context};
  762. ...
  763. try
  764. {
  765. response_type res;
  766. ws.handshake(res, "localhost", "/",
  767. [](request_type& req)
  768. {
  769. req.set(field::user_agent, "Beast");
  770. });
  771. }
  772. catch(...)
  773. {
  774. // An error occurred.
  775. }
  776. @endcode
  777. */
  778. template<class RequestDecorator>
  779. void
  780. handshake_ex(
  781. response_type& res,
  782. string_view host,
  783. string_view target,
  784. RequestDecorator const& decorator);
  785. /** Send an HTTP WebSocket Upgrade request and receive the response.
  786. This function is used to synchronously send the WebSocket
  787. upgrade HTTP request. The call blocks until one of the
  788. following conditions is true:
  789. @li The request is sent and the response is received.
  790. @li An error occurs on the stream
  791. This function is implemented in terms of one or more calls to the
  792. next layer's `read_some` and `write_some` functions.
  793. The operation is successful if the received HTTP response indicates
  794. a successful HTTP Upgrade (represented by a Status-Code of 101,
  795. "switching protocols").
  796. @param host The name of the remote host,
  797. required by the HTTP protocol.
  798. @param target The Request Target, which may not be empty,
  799. required by the HTTP protocol.
  800. @param ec Set to indicate what error occurred, if any.
  801. @par Example
  802. @code
  803. websocket::stream<ip::tcp::socket> ws{io_context};
  804. ...
  805. error_code ec;
  806. ws.handshake(host, target, ec);
  807. if(ec)
  808. {
  809. // An error occurred.
  810. }
  811. @endcode
  812. */
  813. void
  814. handshake(
  815. string_view host,
  816. string_view target,
  817. error_code& ec);
  818. /** Send an HTTP WebSocket Upgrade request and receive the response.
  819. This function is used to synchronously send the WebSocket
  820. upgrade HTTP request. The call blocks until one of the
  821. following conditions is true:
  822. @li The request is sent and the response is received.
  823. @li An error occurs on the stream
  824. This function is implemented in terms of one or more calls to the
  825. next layer's `read_some` and `write_some` functions.
  826. The operation is successful if the received HTTP response indicates
  827. a successful HTTP Upgrade (represented by a Status-Code of 101,
  828. "switching protocols").
  829. @param res The HTTP Upgrade response returned by the remote
  830. endpoint. If `ec` is set, the returned value is undefined.
  831. @param host The name of the remote host,
  832. required by the HTTP protocol.
  833. @param target The Request Target, which may not be empty,
  834. required by the HTTP protocol.
  835. @param ec Set to indicate what error occurred, if any.
  836. @par Example
  837. @code
  838. websocket::stream<ip::tcp::socket> ws{io_context};
  839. ...
  840. error_code ec;
  841. response_type res;
  842. ws.handshake(res, host, target, ec);
  843. if(ec)
  844. {
  845. // An error occurred.
  846. }
  847. @endcode
  848. */
  849. void
  850. handshake(
  851. response_type& res,
  852. string_view host,
  853. string_view target,
  854. error_code& ec);
  855. /** Send an HTTP WebSocket Upgrade request and receive the response.
  856. This function is used to synchronously send the WebSocket
  857. upgrade HTTP request. The call blocks until one of the
  858. following conditions is true:
  859. @li The request is sent and the response is received.
  860. @li An error occurs on the stream
  861. This function is implemented in terms of one or more calls to the
  862. next layer's `read_some` and `write_some` functions.
  863. The operation is successful if the received HTTP response indicates
  864. a successful HTTP Upgrade (represented by a Status-Code of 101,
  865. "switching protocols").
  866. @param host The name of the remote host,
  867. required by the HTTP protocol.
  868. @param target The Request Target, which may not be empty,
  869. required by the HTTP protocol.
  870. @param decorator A function object which will be called to modify
  871. the HTTP request object generated by the implementation. This
  872. could be used to set the User-Agent field, subprotocols, or other
  873. application or HTTP specific fields. The object will be called
  874. with this equivalent signature:
  875. @code void decorator(
  876. request_type& req
  877. ); @endcode
  878. @param ec Set to indicate what error occurred, if any.
  879. @par Example
  880. @code
  881. websocket::stream<ip::tcp::socket> ws{io_context};
  882. ...
  883. error_code ec;
  884. ws.handshake("localhost", "/",
  885. [](request_type& req)
  886. {
  887. req.set(field::user_agent, "Beast");
  888. },
  889. ec);
  890. if(ec)
  891. {
  892. // An error occurred.
  893. }
  894. @endcode
  895. */
  896. template<class RequestDecorator>
  897. void
  898. handshake_ex(
  899. string_view host,
  900. string_view target,
  901. RequestDecorator const& decorator,
  902. error_code& ec);
  903. /** Send an HTTP WebSocket Upgrade request and receive the response.
  904. This function is used to synchronously send the WebSocket
  905. upgrade HTTP request. The call blocks until one of the
  906. following conditions is true:
  907. @li The request is sent and the response is received.
  908. @li An error occurs on the stream
  909. This function is implemented in terms of one or more calls to the
  910. next layer's `read_some` and `write_some` functions.
  911. The operation is successful if the received HTTP response indicates
  912. a successful HTTP Upgrade (represented by a Status-Code of 101,
  913. "switching protocols").
  914. @param res The HTTP Upgrade response returned by the remote
  915. endpoint.
  916. @param host The name of the remote host,
  917. required by the HTTP protocol.
  918. @param target The Request Target, which may not be empty,
  919. required by the HTTP protocol.
  920. @param decorator A function object which will be called to modify
  921. the HTTP request object generated by the implementation. This
  922. could be used to set the User-Agent field, subprotocols, or other
  923. application or HTTP specific fields. The object will be called
  924. with this equivalent signature:
  925. @code void decorator(
  926. request_type& req
  927. ); @endcode
  928. @param ec Set to indicate what error occurred, if any.
  929. @par Example
  930. @code
  931. websocket::stream<ip::tcp::socket> ws{io_context};
  932. ...
  933. error_code ec;
  934. response_type res;
  935. ws.handshake(res, "localhost", "/",
  936. [](request_type& req)
  937. {
  938. req.set(field::user_agent, "Beast");
  939. },
  940. ec);
  941. if(ec)
  942. {
  943. // An error occurred.
  944. }
  945. @endcode
  946. */
  947. template<class RequestDecorator>
  948. void
  949. handshake_ex(
  950. response_type& res,
  951. string_view host,
  952. string_view target,
  953. RequestDecorator const& decorator,
  954. error_code& ec);
  955. /** Start an asynchronous operation to send an upgrade request and receive the response.
  956. This function is used to asynchronously send the HTTP WebSocket
  957. upgrade request and receive the HTTP WebSocket Upgrade response.
  958. This function call always returns immediately. The asynchronous
  959. operation will continue until one of the following conditions is
  960. true:
  961. @li The request is sent and the response is received.
  962. @li An error occurs on the stream
  963. This operation is implemented in terms of one or more calls to the
  964. next layer's `async_read_some` and `async_write_some` functions, and
  965. is known as a <em>composed operation</em>. The program must ensure
  966. that the stream performs no other operations until this operation
  967. completes.
  968. The operation is successful if the received HTTP response indicates
  969. a successful HTTP Upgrade (represented by a Status-Code of 101,
  970. "switching protocols").
  971. @param host The name of the remote host, required by
  972. the HTTP protocol. Copies may be made as needed.
  973. @param target The Request Target, which may not be empty,
  974. required by the HTTP protocol. Copies of this parameter may
  975. be made as needed.
  976. @param handler Invoked when the operation completes.
  977. The handler may be moved or copied as needed.
  978. The equivalent function signature of the handler must be:
  979. @code void handler(
  980. error_code const& ec // Result of operation
  981. ); @endcode
  982. Regardless of whether the asynchronous operation completes
  983. immediately or not, the handler will not be invoked from within
  984. this function. Invocation of the handler will be performed in a
  985. manner equivalent to using `boost::asio::io_context::post`.
  986. */
  987. template<class HandshakeHandler>
  988. BOOST_ASIO_INITFN_RESULT_TYPE(
  989. HandshakeHandler, void(error_code))
  990. async_handshake(
  991. string_view host,
  992. string_view target,
  993. HandshakeHandler&& handler);
  994. /** Start an asynchronous operation to send an upgrade request and receive the response.
  995. This function is used to asynchronously send the HTTP WebSocket
  996. upgrade request and receive the HTTP WebSocket Upgrade response.
  997. This function call always returns immediately. The asynchronous
  998. operation will continue until one of the following conditions is
  999. true:
  1000. @li The request is sent and the response is received.
  1001. @li An error occurs on the stream
  1002. This operation is implemented in terms of one or more calls to the
  1003. next layer's `async_read_some` and `async_write_some` functions, and
  1004. is known as a <em>composed operation</em>. The program must ensure
  1005. that the stream performs no other operations until this operation
  1006. completes.
  1007. The operation is successful if the received HTTP response indicates
  1008. a successful HTTP Upgrade (represented by a Status-Code of 101,
  1009. "switching protocols").
  1010. @param res The HTTP Upgrade response returned by the remote
  1011. endpoint. The caller must ensure this object is valid for at
  1012. least until the completion handler is invoked.
  1013. @param host The name of the remote host, required by
  1014. the HTTP protocol. Copies may be made as needed.
  1015. @param target The Request Target, which may not be empty,
  1016. required by the HTTP protocol. Copies of this parameter may
  1017. be made as needed.
  1018. @param handler Invoked when the operation completes.
  1019. The handler may be moved or copied as needed.
  1020. The equivalent function signature of the handler must be:
  1021. @code void handler(
  1022. error_code const& ec // Result of operation
  1023. ); @endcode
  1024. Regardless of whether the asynchronous operation completes
  1025. immediately or not, the handler will not be invoked from within
  1026. this function. Invocation of the handler will be performed in a
  1027. manner equivalent to using `boost::asio::io_context::post`.
  1028. */
  1029. template<class HandshakeHandler>
  1030. BOOST_ASIO_INITFN_RESULT_TYPE(
  1031. HandshakeHandler, void(error_code))
  1032. async_handshake(
  1033. response_type& res,
  1034. string_view host,
  1035. string_view target,
  1036. HandshakeHandler&& handler);
  1037. /** Start an asynchronous operation to send an upgrade request and receive the response.
  1038. This function is used to asynchronously send the HTTP WebSocket
  1039. upgrade request and receive the HTTP WebSocket Upgrade response.
  1040. This function call always returns immediately. The asynchronous
  1041. operation will continue until one of the following conditions is
  1042. true:
  1043. @li The request is sent and the response is received.
  1044. @li An error occurs on the stream
  1045. This operation is implemented in terms of one or more calls to the
  1046. next layer's `async_read_some` and `async_write_some` functions, and
  1047. is known as a <em>composed operation</em>. The program must ensure
  1048. that the stream performs no other operations until this operation
  1049. completes.
  1050. The operation is successful if the received HTTP response indicates
  1051. a successful HTTP Upgrade (represented by a Status-Code of 101,
  1052. "switching protocols").
  1053. @param host The name of the remote host, required by
  1054. the HTTP protocol. Copies may be made as needed.
  1055. @param target The Request Target, which may not be empty,
  1056. required by the HTTP protocol. Copies of this parameter may
  1057. be made as needed.
  1058. @param decorator A function object which will be called to modify
  1059. the HTTP request object generated by the implementation. This
  1060. could be used to set the User-Agent field, subprotocols, or other
  1061. application or HTTP specific fields. The object will be called
  1062. with this equivalent signature:
  1063. @code void decorator(
  1064. request_type& req
  1065. ); @endcode
  1066. @param handler Invoked when the operation completes.
  1067. The handler may be moved or copied as needed.
  1068. The equivalent function signature of the handler must be:
  1069. @code void handler(
  1070. error_code const& ec // Result of operation
  1071. ); @endcode
  1072. Regardless of whether the asynchronous operation completes
  1073. immediately or not, the handler will not be invoked from within
  1074. this function. Invocation of the handler will be performed in a
  1075. manner equivalent to using `boost::asio::io_context::post`.
  1076. */
  1077. template<class RequestDecorator, class HandshakeHandler>
  1078. BOOST_ASIO_INITFN_RESULT_TYPE(
  1079. HandshakeHandler, void(error_code))
  1080. async_handshake_ex(
  1081. string_view host,
  1082. string_view target,
  1083. RequestDecorator const& decorator,
  1084. HandshakeHandler&& handler);
  1085. /** Start an asynchronous operation to send an upgrade request and receive the response.
  1086. This function is used to asynchronously send the HTTP WebSocket
  1087. upgrade request and receive the HTTP WebSocket Upgrade response.
  1088. This function call always returns immediately. The asynchronous
  1089. operation will continue until one of the following conditions is
  1090. true:
  1091. @li The request is sent and the response is received.
  1092. @li An error occurs on the stream
  1093. This operation is implemented in terms of one or more calls to the
  1094. next layer's `async_read_some` and `async_write_some` functions, and
  1095. is known as a <em>composed operation</em>. The program must ensure
  1096. that the stream performs no other operations until this operation
  1097. completes.
  1098. The operation is successful if the received HTTP response indicates
  1099. a successful HTTP Upgrade (represented by a Status-Code of 101,
  1100. "switching protocols").
  1101. @param res The HTTP Upgrade response returned by the remote
  1102. endpoint. The caller must ensure this object is valid for at
  1103. least until the completion handler is invoked.
  1104. @param host The name of the remote host, required by
  1105. the HTTP protocol. Copies may be made as needed.
  1106. @param target The Request Target, which may not be empty,
  1107. required by the HTTP protocol. Copies of this parameter may
  1108. be made as needed.
  1109. @param decorator A function object which will be called to modify
  1110. the HTTP request object generated by the implementation. This
  1111. could be used to set the User-Agent field, subprotocols, or other
  1112. application or HTTP specific fields. The object will be called
  1113. with this equivalent signature:
  1114. @code void decorator(
  1115. request_type& req
  1116. ); @endcode
  1117. @param handler Invoked when the operation completes.
  1118. The handler may be moved or copied as needed.
  1119. The equivalent function signature of the handler must be:
  1120. @code void handler(
  1121. error_code const& ec // Result of operation
  1122. ); @endcode
  1123. Regardless of whether the asynchronous operation completes
  1124. immediately or not, the handler will not be invoked from within
  1125. this function. Invocation of the handler will be performed in a
  1126. manner equivalent to using `boost::asio::io_context::post`.
  1127. */
  1128. template<class RequestDecorator, class HandshakeHandler>
  1129. BOOST_ASIO_INITFN_RESULT_TYPE(
  1130. HandshakeHandler, void(error_code))
  1131. async_handshake_ex(
  1132. response_type& res,
  1133. string_view host,
  1134. string_view target,
  1135. RequestDecorator const& decorator,
  1136. HandshakeHandler&& handler);
  1137. //--------------------------------------------------------------------------
  1138. //
  1139. // Handshaking (Server)
  1140. //
  1141. //--------------------------------------------------------------------------
  1142. /** Read and respond to a WebSocket HTTP Upgrade request.
  1143. This function is used to synchronously read an HTTP WebSocket
  1144. Upgrade request and send the HTTP response. The call blocks
  1145. until one of the following conditions is true:
  1146. @li The request is received and the response finishes sending.
  1147. @li An error occurs on the stream.
  1148. This function is implemented in terms of one or more calls to
  1149. the next layer's `read_some` and `write_some` functions.
  1150. If the stream receives a valid HTTP WebSocket Upgrade request,
  1151. an HTTP response is sent back indicating a successful upgrade.
  1152. When this call returns, the stream is then ready to send and
  1153. receive WebSocket protocol frames and messages.
  1154. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1155. an HTTP response is sent indicating the reason and status code
  1156. (typically 400, "Bad Request"). This counts as a failure.
  1157. The implementation uses fixed size internal storage to
  1158. receive the request. If the request is too large, the error
  1159. @ref error::buffer_overflow will be indicated. Applications
  1160. that wish to receive larger requests should first read the
  1161. request using their own buffer and a suitable overload of
  1162. @ref http::read or @ref http::async_read, then call @ref accept
  1163. or @ref async_accept with the request.
  1164. @throws system_error Thrown on failure.
  1165. */
  1166. void
  1167. accept();
  1168. /** Read and respond to a WebSocket HTTP Upgrade request.
  1169. This function is used to synchronously read an HTTP WebSocket
  1170. Upgrade request and send the HTTP response. The call blocks
  1171. until one of the following conditions is true:
  1172. @li The request is received and the response finishes sending.
  1173. @li An error occurs on the stream.
  1174. This function is implemented in terms of one or more calls to
  1175. the next layer's `read_some` and `write_some` functions.
  1176. If the stream receives a valid HTTP WebSocket Upgrade request,
  1177. an HTTP response is sent back indicating a successful upgrade.
  1178. When this call returns, the stream is then ready to send and
  1179. receive WebSocket protocol frames and messages.
  1180. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1181. an HTTP response is sent indicating the reason and status code
  1182. (typically 400, "Bad Request"). This counts as a failure.
  1183. The implementation uses fixed size internal storage to
  1184. receive the request. If the request is too large, the error
  1185. @ref error::buffer_overflow will be indicated. Applications
  1186. that wish to receive larger requests should first read the
  1187. request using their own buffer and a suitable overload of
  1188. @ref http::read or @ref http::async_read, then call @ref accept
  1189. or @ref async_accept with the request.
  1190. @param decorator A function object which will be called to modify
  1191. the HTTP response object delivered by the implementation. This
  1192. could be used to set the Server field, subprotocols, or other
  1193. application or HTTP specific fields. The object will be called
  1194. with this equivalent signature:
  1195. @code void decorator(
  1196. response_type& res
  1197. ); @endcode
  1198. @throws system_error Thrown on failure.
  1199. */
  1200. template<class ResponseDecorator>
  1201. void
  1202. accept_ex(ResponseDecorator const& decorator);
  1203. /** Read and respond to a WebSocket HTTP Upgrade request.
  1204. This function is used to synchronously read an HTTP WebSocket
  1205. Upgrade request and send the HTTP response. The call blocks
  1206. until one of the following conditions is true:
  1207. @li The request is received and the response finishes sending.
  1208. @li An error occurs on the stream.
  1209. This function is implemented in terms of one or more calls to
  1210. the next layer's `read_some` and `write_some` functions.
  1211. If the stream receives a valid HTTP WebSocket Upgrade request,
  1212. an HTTP response is sent back indicating a successful upgrade.
  1213. When this call returns, the stream is then ready to send and
  1214. receive WebSocket protocol frames and messages.
  1215. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1216. an HTTP response is sent indicating the reason and status code
  1217. (typically 400, "Bad Request"). This counts as a failure.
  1218. The implementation uses fixed size internal storage to
  1219. receive the request. If the request is too large, the error
  1220. @ref error::buffer_overflow will be indicated. Applications
  1221. that wish to receive larger requests should first read the
  1222. request using their own buffer and a suitable overload of
  1223. @ref http::read or @ref http::async_read, then call @ref accept
  1224. or @ref async_accept with the request.
  1225. @param ec Set to indicate what error occurred, if any.
  1226. */
  1227. void
  1228. accept(error_code& ec);
  1229. /** Read and respond to a WebSocket HTTP Upgrade request.
  1230. This function is used to synchronously read an HTTP WebSocket
  1231. Upgrade request and send the HTTP response. The call blocks
  1232. until one of the following conditions is true:
  1233. @li The request is received and the response finishes sending.
  1234. @li An error occurs on the stream.
  1235. This function is implemented in terms of one or more calls to
  1236. the next layer's `read_some` and `write_some` functions.
  1237. If the stream receives a valid HTTP WebSocket Upgrade request,
  1238. an HTTP response is sent back indicating a successful upgrade.
  1239. When this call returns, the stream is then ready to send and
  1240. receive WebSocket protocol frames and messages.
  1241. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1242. an HTTP response is sent indicating the reason and status code
  1243. (typically 400, "Bad Request"). This counts as a failure.
  1244. The implementation uses fixed size internal storage to
  1245. receive the request. If the request is too large, the error
  1246. @ref error::buffer_overflow will be indicated. Applications
  1247. that wish to receive larger requests should first read the
  1248. request using their own buffer and a suitable overload of
  1249. @ref http::read or @ref http::async_read, then call @ref accept
  1250. or @ref async_accept with the request.
  1251. @param decorator A function object which will be called to modify
  1252. the HTTP response object delivered by the implementation. This
  1253. could be used to set the Server field, subprotocols, or other
  1254. application or HTTP specific fields. The object will be called
  1255. with this equivalent signature:
  1256. @code void decorator(
  1257. response_type& res
  1258. ); @endcode
  1259. @param ec Set to indicate what error occurred, if any.
  1260. */
  1261. template<class ResponseDecorator>
  1262. void
  1263. accept_ex(
  1264. ResponseDecorator const& decorator,
  1265. error_code& ec);
  1266. /** Read and respond to a WebSocket HTTP Upgrade request.
  1267. This function is used to synchronously read an HTTP WebSocket
  1268. Upgrade request and send the HTTP response. The call blocks
  1269. until one of the following conditions is true:
  1270. @li The request is received and the response finishes sending.
  1271. @li An error occurs on the stream.
  1272. This function is implemented in terms of one or more calls to
  1273. the next layer's `read_some` and `write_some` functions.
  1274. If the stream receives a valid HTTP WebSocket Upgrade request,
  1275. an HTTP response is sent back indicating a successful upgrade.
  1276. When this call returns, the stream is then ready to send and
  1277. receive WebSocket protocol frames and messages.
  1278. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1279. an HTTP response is sent indicating the reason and status code
  1280. (typically 400, "Bad Request"). This counts as a failure.
  1281. The implementation uses fixed size internal storage to
  1282. receive the request. If the request is too large, the error
  1283. @ref error::buffer_overflow will be indicated. Applications
  1284. that wish to receive larger requests should first read the
  1285. request using their own buffer and a suitable overload of
  1286. @ref http::read or @ref http::async_read, then call @ref accept
  1287. or @ref async_accept with the request.
  1288. @param buffers Caller provided data that has already been
  1289. received on the stream. The implementation will copy the
  1290. caller provided data before the function returns.
  1291. @throws system_error Thrown on failure.
  1292. */
  1293. template<class ConstBufferSequence>
  1294. #if BOOST_BEAST_DOXYGEN
  1295. void
  1296. #else
  1297. typename std::enable_if<! http::detail::is_header<
  1298. ConstBufferSequence>::value>::type
  1299. #endif
  1300. accept(ConstBufferSequence const& buffers);
  1301. /** Read and respond to a WebSocket HTTP Upgrade request.
  1302. This function is used to synchronously read an HTTP WebSocket
  1303. Upgrade request and send the HTTP response. The call blocks
  1304. until one of the following conditions is true:
  1305. @li The request is received and the response finishes sending.
  1306. @li An error occurs on the stream.
  1307. This function is implemented in terms of one or more calls to
  1308. the next layer's `read_some` and `write_some` functions.
  1309. If the stream receives a valid HTTP WebSocket Upgrade request,
  1310. an HTTP response is sent back indicating a successful upgrade.
  1311. When this call returns, the stream is then ready to send and
  1312. receive WebSocket protocol frames and messages.
  1313. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1314. an HTTP response is sent indicating the reason and status code
  1315. (typically 400, "Bad Request"). This counts as a failure.
  1316. The implementation uses fixed size internal storage to
  1317. receive the request. If the request is too large, the error
  1318. @ref error::buffer_overflow will be indicated. Applications
  1319. that wish to receive larger requests should first read the
  1320. request using their own buffer and a suitable overload of
  1321. @ref http::read or @ref http::async_read, then call @ref accept
  1322. or @ref async_accept with the request.
  1323. @param buffers Caller provided data that has already been
  1324. received on the stream. The implementation will copy the
  1325. caller provided data before the function returns.
  1326. @param decorator A function object which will be called to modify
  1327. the HTTP response object delivered by the implementation. This
  1328. could be used to set the Server field, subprotocols, or other
  1329. application or HTTP specific fields. The object will be called
  1330. with this equivalent signature:
  1331. @code void decorator(
  1332. response_type& res
  1333. ); @endcode
  1334. @throws system_error Thrown on failure.
  1335. */
  1336. template<class ConstBufferSequence,
  1337. class ResponseDecorator>
  1338. #if BOOST_BEAST_DOXYGEN
  1339. void
  1340. #else
  1341. typename std::enable_if<! http::detail::is_header<
  1342. ConstBufferSequence>::value>::type
  1343. #endif
  1344. accept_ex(
  1345. ConstBufferSequence const& buffers,
  1346. ResponseDecorator const& decorator);
  1347. /** Read and respond to a WebSocket HTTP Upgrade request.
  1348. This function is used to synchronously read an HTTP WebSocket
  1349. Upgrade request and send the HTTP response. The call blocks
  1350. until one of the following conditions is true:
  1351. @li The request is received and the response finishes sending.
  1352. @li An error occurs on the stream.
  1353. This function is implemented in terms of one or more calls to
  1354. the next layer's `read_some` and `write_some` functions.
  1355. If the stream receives a valid HTTP WebSocket Upgrade request,
  1356. an HTTP response is sent back indicating a successful upgrade.
  1357. When this call returns, the stream is then ready to send and
  1358. receive WebSocket protocol frames and messages.
  1359. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1360. an HTTP response is sent indicating the reason and status code
  1361. (typically 400, "Bad Request"). This counts as a failure.
  1362. The implementation uses fixed size internal storage to
  1363. receive the request. If the request is too large, the error
  1364. @ref error::buffer_overflow will be indicated. Applications
  1365. that wish to receive larger requests should first read the
  1366. request using their own buffer and a suitable overload of
  1367. @ref http::read or @ref http::async_read, then call @ref accept
  1368. or @ref async_accept with the request.
  1369. @param buffers Caller provided data that has already been
  1370. received on the stream. The implementation will copy the
  1371. caller provided data before the function returns.
  1372. @param ec Set to indicate what error occurred, if any.
  1373. */
  1374. template<class ConstBufferSequence>
  1375. #if BOOST_BEAST_DOXYGEN
  1376. void
  1377. #else
  1378. typename std::enable_if<! http::detail::is_header<
  1379. ConstBufferSequence>::value>::type
  1380. #endif
  1381. accept(
  1382. ConstBufferSequence const& buffers,
  1383. error_code& ec);
  1384. /** Read and respond to a WebSocket HTTP Upgrade request.
  1385. This function is used to synchronously read an HTTP WebSocket
  1386. Upgrade request and send the HTTP response. The call blocks
  1387. until one of the following conditions is true:
  1388. @li The request is received and the response finishes sending.
  1389. @li An error occurs on the stream.
  1390. This function is implemented in terms of one or more calls to
  1391. the next layer's `read_some` and `write_some` functions.
  1392. If the stream receives a valid HTTP WebSocket Upgrade request,
  1393. an HTTP response is sent back indicating a successful upgrade.
  1394. When this call returns, the stream is then ready to send and
  1395. receive WebSocket protocol frames and messages.
  1396. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1397. an HTTP response is sent indicating the reason and status code
  1398. (typically 400, "Bad Request"). This counts as a failure.
  1399. The implementation uses fixed size internal storage to
  1400. receive the request. If the request is too large, the error
  1401. @ref error::buffer_overflow will be indicated. Applications
  1402. that wish to receive larger requests should first read the
  1403. request using their own buffer and a suitable overload of
  1404. @ref http::read or @ref http::async_read, then call @ref accept
  1405. or @ref async_accept with the request.
  1406. @param buffers Caller provided data that has already been
  1407. received on the stream. The implementation will copy the
  1408. caller provided data before the function returns.
  1409. @param decorator A function object which will be called to modify
  1410. the HTTP response object delivered by the implementation. This
  1411. could be used to set the Server field, subprotocols, or other
  1412. application or HTTP specific fields. The object will be called
  1413. with this equivalent signature:
  1414. @code void decorator(
  1415. response_type& res
  1416. ); @endcode
  1417. @param ec Set to indicate what error occurred, if any.
  1418. */
  1419. template<class ConstBufferSequence, class ResponseDecorator>
  1420. #if BOOST_BEAST_DOXYGEN
  1421. void
  1422. #else
  1423. typename std::enable_if<! http::detail::is_header<
  1424. ConstBufferSequence>::value>::type
  1425. #endif
  1426. accept_ex(
  1427. ConstBufferSequence const& buffers,
  1428. ResponseDecorator const& decorator,
  1429. error_code& ec);
  1430. /** Respond to a WebSocket HTTP Upgrade request
  1431. This function is used to synchronously send the HTTP response
  1432. to an HTTP request possibly containing a WebSocket Upgrade.
  1433. The call blocks until one of the following conditions is true:
  1434. @li The response finishes sending.
  1435. @li An error occurs on the stream.
  1436. This function is implemented in terms of one or more calls to
  1437. the next layer's `read_some` and `write_some` functions.
  1438. If the stream receives a valid HTTP WebSocket Upgrade request,
  1439. an HTTP response is sent back indicating a successful upgrade.
  1440. When this call returns, the stream is then ready to send and
  1441. receive WebSocket protocol frames and messages.
  1442. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1443. an HTTP response is sent indicating the reason and status code
  1444. (typically 400, "Bad Request"). This counts as a failure.
  1445. @param req An object containing the HTTP Upgrade request.
  1446. Ownership is not transferred, the implementation will not
  1447. access this object from other threads.
  1448. @throws system_error Thrown on failure.
  1449. */
  1450. template<class Body, class Allocator>
  1451. void
  1452. accept(http::request<Body,
  1453. http::basic_fields<Allocator>> const& req);
  1454. /** Respond to a WebSocket HTTP Upgrade request
  1455. This function is used to synchronously send the HTTP response
  1456. to an HTTP request possibly containing a WebSocket Upgrade.
  1457. The call blocks until one of the following conditions is true:
  1458. @li The response finishes sending.
  1459. @li An error occurs on the stream.
  1460. This function is implemented in terms of one or more calls to
  1461. the next layer's `read_some` and `write_some` functions.
  1462. If the stream receives a valid HTTP WebSocket Upgrade request,
  1463. an HTTP response is sent back indicating a successful upgrade.
  1464. When this call returns, the stream is then ready to send and
  1465. receive WebSocket protocol frames and messages.
  1466. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1467. an HTTP response is sent indicating the reason and status code
  1468. (typically 400, "Bad Request"). This counts as a failure.
  1469. @param req An object containing the HTTP Upgrade request.
  1470. Ownership is not transferred, the implementation will not
  1471. access this object from other threads.
  1472. @param decorator A function object which will be called to modify
  1473. the HTTP response object delivered by the implementation. This
  1474. could be used to set the Server field, subprotocols, or other
  1475. application or HTTP specific fields. The object will be called
  1476. with this equivalent signature:
  1477. @code void decorator(
  1478. response_type& res
  1479. ); @endcode
  1480. @throws system_error Thrown on failure.
  1481. */
  1482. template<class Body, class Allocator,
  1483. class ResponseDecorator>
  1484. void
  1485. accept_ex(http::request<Body,
  1486. http::basic_fields<Allocator>> const& req,
  1487. ResponseDecorator const& decorator);
  1488. /** Respond to a WebSocket HTTP Upgrade request
  1489. This function is used to synchronously send the HTTP response
  1490. to an HTTP request possibly containing a WebSocket Upgrade.
  1491. The call blocks until one of the following conditions is true:
  1492. @li The response finishes sending.
  1493. @li An error occurs on the stream.
  1494. This function is implemented in terms of one or more calls to
  1495. the next layer's `read_some` and `write_some` functions.
  1496. If the stream receives a valid HTTP WebSocket Upgrade request,
  1497. an HTTP response is sent back indicating a successful upgrade.
  1498. When this call returns, the stream is then ready to send and
  1499. receive WebSocket protocol frames and messages.
  1500. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1501. an HTTP response is sent indicating the reason and status code
  1502. (typically 400, "Bad Request"). This counts as a failure.
  1503. @param req An object containing the HTTP Upgrade request.
  1504. Ownership is not transferred, the implementation will not
  1505. access this object from other threads.
  1506. @param ec Set to indicate what error occurred, if any.
  1507. */
  1508. template<class Body, class Allocator>
  1509. void
  1510. accept(http::request<Body,
  1511. http::basic_fields<Allocator>> const& req,
  1512. error_code& ec);
  1513. /** Respond to a WebSocket HTTP Upgrade request
  1514. This function is used to synchronously send the HTTP response
  1515. to an HTTP request possibly containing a WebSocket Upgrade.
  1516. The call blocks until one of the following conditions is true:
  1517. @li The response finishes sending.
  1518. @li An error occurs on the stream.
  1519. This function is implemented in terms of one or more calls to
  1520. the next layer's `read_some` and `write_some` functions.
  1521. If the stream receives a valid HTTP WebSocket Upgrade request,
  1522. an HTTP response is sent back indicating a successful upgrade.
  1523. When this call returns, the stream is then ready to send and
  1524. receive WebSocket protocol frames and messages.
  1525. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1526. an HTTP response is sent indicating the reason and status code
  1527. (typically 400, "Bad Request"). This counts as a failure.
  1528. @param req An object containing the HTTP Upgrade request.
  1529. Ownership is not transferred, the implementation will not
  1530. access this object from other threads.
  1531. @param decorator A function object which will be called to modify
  1532. the HTTP response object delivered by the implementation. This
  1533. could be used to set the Server field, subprotocols, or other
  1534. application or HTTP specific fields. The object will be called
  1535. with this equivalent signature:
  1536. @code void decorator(
  1537. response_type& res
  1538. ); @endcode
  1539. @param ec Set to indicate what error occurred, if any.
  1540. */
  1541. template<class Body, class Allocator,
  1542. class ResponseDecorator>
  1543. void
  1544. accept_ex(http::request<Body,
  1545. http::basic_fields<Allocator>> const& req,
  1546. ResponseDecorator const& decorator,
  1547. error_code& ec);
  1548. /** Start reading and responding to a WebSocket HTTP Upgrade request.
  1549. This function is used to asynchronously read an HTTP WebSocket
  1550. Upgrade request and send the HTTP response. The function call
  1551. always returns immediately. The asynchronous operation will
  1552. continue until one of the following conditions is true:
  1553. @li The request is received and the response finishes sending.
  1554. @li An error occurs on the stream.
  1555. This operation is implemented in terms of one or more calls to
  1556. the next layer's `async_read_some` and `async_write_some`
  1557. functions, and is known as a <em>composed operation</em>. The
  1558. program must ensure that the stream performs no other
  1559. asynchronous operations until this operation completes.
  1560. If the stream receives a valid HTTP WebSocket Upgrade request,
  1561. an HTTP response is sent back indicating a successful upgrade.
  1562. When the completion handler is invoked, the stream is then
  1563. ready to send and receive WebSocket protocol frames and
  1564. messages.
  1565. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1566. an HTTP response is sent indicating the reason and status code
  1567. (typically 400, "Bad Request"). This counts as a failure, and
  1568. the completion handler will be invoked with a suitable error
  1569. code set.
  1570. The implementation uses fixed size internal storage to
  1571. receive the request. If the request is too large, the error
  1572. @ref error::buffer_overflow will be indicated. Applications
  1573. that wish to receive larger requests should first read the
  1574. request using their own buffer and a suitable overload of
  1575. @ref http::read or @ref http::async_read, then call @ref accept
  1576. or @ref async_accept with the request.
  1577. @param handler Invoked when the operation completes.
  1578. The handler may be moved or copied as needed.
  1579. The equivalent function signature of the handler must be:
  1580. @code void handler(
  1581. error_code const& ec // Result of operation
  1582. ); @endcode
  1583. Regardless of whether the asynchronous operation completes
  1584. immediately or not, the handler will not be invoked from within
  1585. this function. Invocation of the handler will be performed in a
  1586. manner equivalent to using `boost::asio::io_context::post`.
  1587. */
  1588. template<class AcceptHandler>
  1589. BOOST_ASIO_INITFN_RESULT_TYPE(
  1590. AcceptHandler, void(error_code))
  1591. async_accept(AcceptHandler&& handler);
  1592. /** Start reading and responding to a WebSocket HTTP Upgrade request.
  1593. This function is used to asynchronously read an HTTP WebSocket
  1594. Upgrade request and send the HTTP response. The function call
  1595. always returns immediately. The asynchronous operation will
  1596. continue until one of the following conditions is true:
  1597. @li The request is received and the response finishes sending.
  1598. @li An error occurs on the stream.
  1599. This operation is implemented in terms of one or more calls to
  1600. the next layer's `async_read_some` and `async_write_some`
  1601. functions, and is known as a <em>composed operation</em>. The
  1602. program must ensure that the stream performs no other
  1603. asynchronous operations until this operation completes.
  1604. If the stream receives a valid HTTP WebSocket Upgrade request,
  1605. an HTTP response is sent back indicating a successful upgrade.
  1606. When the completion handler is invoked, the stream is then
  1607. ready to send and receive WebSocket protocol frames and
  1608. messages.
  1609. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1610. an HTTP response is sent indicating the reason and status code
  1611. (typically 400, "Bad Request"). This counts as a failure, and
  1612. the completion handler will be invoked with a suitable error
  1613. code set.
  1614. The implementation uses fixed size internal storage to
  1615. receive the request. If the request is too large, the error
  1616. @ref error::buffer_overflow will be indicated. Applications
  1617. that wish to receive larger requests should first read the
  1618. request using their own buffer and a suitable overload of
  1619. @ref http::read or @ref http::async_read, then call @ref accept
  1620. or @ref async_accept with the request.
  1621. @param decorator A function object which will be called to modify
  1622. the HTTP response object delivered by the implementation. This
  1623. could be used to set the Server field, subprotocols, or other
  1624. application or HTTP specific fields. The object will be called
  1625. with this equivalent signature:
  1626. @code void decorator(
  1627. response_type& res
  1628. ); @endcode
  1629. @param handler Invoked when the operation completes.
  1630. The handler may be moved or copied as needed.
  1631. The equivalent function signature of the handler must be:
  1632. @code void handler(
  1633. error_code const& ec // Result of operation
  1634. ); @endcode
  1635. Regardless of whether the asynchronous operation completes
  1636. immediately or not, the handler will not be invoked from within
  1637. this function. Invocation of the handler will be performed in a
  1638. manner equivalent to using `boost::asio::io_context::post`.
  1639. */
  1640. template<
  1641. class ResponseDecorator,
  1642. class AcceptHandler>
  1643. BOOST_ASIO_INITFN_RESULT_TYPE(
  1644. AcceptHandler, void(error_code))
  1645. async_accept_ex(
  1646. ResponseDecorator const& decorator,
  1647. AcceptHandler&& handler);
  1648. /** Start reading and responding to a WebSocket HTTP Upgrade request.
  1649. This function is used to asynchronously read an HTTP WebSocket
  1650. Upgrade request and send the HTTP response. The function call
  1651. always returns immediately. The asynchronous operation will
  1652. continue until one of the following conditions is true:
  1653. @li The request is received and the response finishes sending.
  1654. @li An error occurs on the stream.
  1655. This operation is implemented in terms of one or more calls to
  1656. the next layer's `async_read_some` and `async_write_some`
  1657. functions, and is known as a <em>composed operation</em>. The
  1658. program must ensure that the stream performs no other
  1659. asynchronous operations until this operation completes.
  1660. If the stream receives a valid HTTP WebSocket Upgrade request,
  1661. an HTTP response is sent back indicating a successful upgrade.
  1662. When the completion handler is invoked, the stream is then
  1663. ready to send and receive WebSocket protocol frames and
  1664. messages.
  1665. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1666. an HTTP response is sent indicating the reason and status code
  1667. (typically 400, "Bad Request"). This counts as a failure, and
  1668. the completion handler will be invoked with a suitable error
  1669. code set.
  1670. The implementation uses fixed size internal storage to
  1671. receive the request. If the request is too large, the error
  1672. @ref error::buffer_overflow will be indicated. Applications
  1673. that wish to receive larger requests should first read the
  1674. request using their own buffer and a suitable overload of
  1675. @ref http::read or @ref http::async_read, then call @ref accept
  1676. or @ref async_accept with the request.
  1677. @param buffers Caller provided data that has already been
  1678. received on the stream. This may be used for implementations
  1679. allowing multiple protocols on the same stream. The
  1680. buffered data will first be applied to the handshake, and
  1681. then to received WebSocket frames. The implementation will
  1682. copy the caller provided data before the function returns.
  1683. @param handler Invoked when the operation completes.
  1684. The handler may be moved or copied as needed.
  1685. The equivalent function signature of the handler must be:
  1686. @code void handler(
  1687. error_code const& ec // Result of operation
  1688. ); @endcode
  1689. Regardless of whether the asynchronous operation completes
  1690. immediately or not, the handler will not be invoked from within
  1691. this function. Invocation of the handler will be performed in a
  1692. manner equivalent to using `boost::asio::io_context::post`.
  1693. */
  1694. template<
  1695. class ConstBufferSequence,
  1696. class AcceptHandler>
  1697. #if BOOST_BEAST_DOXYGEN
  1698. void_or_deduced
  1699. #else
  1700. typename std::enable_if<
  1701. ! http::detail::is_header<ConstBufferSequence>::value,
  1702. BOOST_ASIO_INITFN_RESULT_TYPE(
  1703. AcceptHandler, void(error_code))>::type
  1704. #endif
  1705. async_accept(
  1706. ConstBufferSequence const& buffers,
  1707. AcceptHandler&& handler);
  1708. /** Start reading and responding to a WebSocket HTTP Upgrade request.
  1709. This function is used to asynchronously read an HTTP WebSocket
  1710. Upgrade request and send the HTTP response. The function call
  1711. always returns immediately. The asynchronous operation will
  1712. continue until one of the following conditions is true:
  1713. @li The request is received and the response finishes sending.
  1714. @li An error occurs on the stream.
  1715. This operation is implemented in terms of one or more calls to
  1716. the next layer's `async_read_some` and `async_write_some`
  1717. functions, and is known as a <em>composed operation</em>. The
  1718. program must ensure that the stream performs no other
  1719. asynchronous operations until this operation completes.
  1720. If the stream receives a valid HTTP WebSocket Upgrade request,
  1721. an HTTP response is sent back indicating a successful upgrade.
  1722. When the completion handler is invoked, the stream is then
  1723. ready to send and receive WebSocket protocol frames and
  1724. messages.
  1725. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1726. an HTTP response is sent indicating the reason and status code
  1727. (typically 400, "Bad Request"). This counts as a failure, and
  1728. the completion handler will be invoked with a suitable error
  1729. code set.
  1730. The implementation uses fixed size internal storage to
  1731. receive the request. If the request is too large, the error
  1732. @ref error::buffer_overflow will be indicated. Applications
  1733. that wish to receive larger requests should first read the
  1734. request using their own buffer and a suitable overload of
  1735. @ref http::read or @ref http::async_read, then call @ref accept
  1736. or @ref async_accept with the request.
  1737. @param buffers Caller provided data that has already been
  1738. received on the stream. This may be used for implementations
  1739. allowing multiple protocols on the same stream. The
  1740. buffered data will first be applied to the handshake, and
  1741. then to received WebSocket frames. The implementation will
  1742. copy the caller provided data before the function returns.
  1743. @param decorator A function object which will be called to modify
  1744. the HTTP response object delivered by the implementation. This
  1745. could be used to set the Server field, subprotocols, or other
  1746. application or HTTP specific fields. The object will be called
  1747. with this equivalent signature:
  1748. @code void decorator(
  1749. response_type& res
  1750. ); @endcode
  1751. @param handler Invoked when the operation completes.
  1752. The handler may be moved or copied as needed.
  1753. The equivalent function signature of the handler must be:
  1754. @code void handler(
  1755. error_code const& ec // Result of operation
  1756. ); @endcode
  1757. Regardless of whether the asynchronous operation completes
  1758. immediately or not, the handler will not be invoked from within
  1759. this function. Invocation of the handler will be performed in a
  1760. manner equivalent to using `boost::asio::io_context::post`.
  1761. */
  1762. template<
  1763. class ConstBufferSequence,
  1764. class ResponseDecorator,
  1765. class AcceptHandler>
  1766. #if BOOST_BEAST_DOXYGEN
  1767. void_or_deduced
  1768. #else
  1769. typename std::enable_if<
  1770. ! http::detail::is_header<ConstBufferSequence>::value,
  1771. BOOST_ASIO_INITFN_RESULT_TYPE(
  1772. AcceptHandler, void(error_code))>::type
  1773. #endif
  1774. async_accept_ex(
  1775. ConstBufferSequence const& buffers,
  1776. ResponseDecorator const& decorator,
  1777. AcceptHandler&& handler);
  1778. /** Start responding to a WebSocket HTTP Upgrade request.
  1779. This function is used to asynchronously send the HTTP response
  1780. to an HTTP request possibly containing a WebSocket Upgrade
  1781. request. The function call always returns immediately. The
  1782. asynchronous operation will continue until one of the following
  1783. conditions is true:
  1784. @li The response finishes sending.
  1785. @li An error occurs on the stream.
  1786. This operation is implemented in terms of one or more calls to
  1787. the next layer's `async_write_some` functions, and is known as
  1788. a <em>composed operation</em>. The program must ensure that the
  1789. stream performs no other operations until this operation
  1790. completes.
  1791. If the stream receives a valid HTTP WebSocket Upgrade request,
  1792. an HTTP response is sent back indicating a successful upgrade.
  1793. When the completion handler is invoked, the stream is then
  1794. ready to send and receive WebSocket protocol frames and
  1795. messages.
  1796. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1797. an HTTP response is sent indicating the reason and status code
  1798. (typically 400, "Bad Request"). This counts as a failure, and
  1799. the completion handler will be invoked with a suitable error
  1800. code set.
  1801. @param req An object containing the HTTP Upgrade request.
  1802. Ownership is not transferred, the implementation will not access
  1803. this object from other threads.
  1804. @param handler Invoked when the operation completes.
  1805. The handler may be moved or copied as needed.
  1806. The equivalent function signature of the handler must be:
  1807. @code void handler(
  1808. error_code const& ec // Result of operation
  1809. ); @endcode
  1810. Regardless of whether the asynchronous operation completes
  1811. immediately or not, the handler will not be invoked from within
  1812. this function. Invocation of the handler will be performed in a
  1813. manner equivalent to using `boost::asio::io_context::post`.
  1814. */
  1815. template<
  1816. class Body, class Allocator,
  1817. class AcceptHandler>
  1818. BOOST_ASIO_INITFN_RESULT_TYPE(
  1819. AcceptHandler, void(error_code))
  1820. async_accept(
  1821. http::request<Body,
  1822. http::basic_fields<Allocator>> const& req,
  1823. AcceptHandler&& handler);
  1824. /** Start responding to a WebSocket HTTP Upgrade request.
  1825. This function is used to asynchronously send the HTTP response
  1826. to an HTTP request possibly containing a WebSocket Upgrade
  1827. request. The function call always returns immediately. The
  1828. asynchronous operation will continue until one of the following
  1829. conditions is true:
  1830. @li The response finishes sending.
  1831. @li An error occurs on the stream.
  1832. This operation is implemented in terms of one or more calls to
  1833. the next layer's `async_write_some` functions, and is known as
  1834. a <em>composed operation</em>. The program must ensure that the
  1835. stream performs no other operations until this operation
  1836. completes.
  1837. If the stream receives a valid HTTP WebSocket Upgrade request,
  1838. an HTTP response is sent back indicating a successful upgrade.
  1839. When the completion handler is invoked, the stream is then
  1840. ready to send and receive WebSocket protocol frames and
  1841. messages.
  1842. If the HTTP Upgrade request is invalid or cannot be satisfied,
  1843. an HTTP response is sent indicating the reason and status code
  1844. (typically 400, "Bad Request"). This counts as a failure, and
  1845. the completion handler will be invoked with a suitable error
  1846. code set.
  1847. @param req An object containing the HTTP Upgrade request.
  1848. Ownership is not transferred, the implementation will not access
  1849. this object from other threads.
  1850. @param decorator A function object which will be called to modify
  1851. the HTTP response object delivered by the implementation. This
  1852. could be used to set the Server field, subprotocols, or other
  1853. application or HTTP specific fields. The object will be called
  1854. with this equivalent signature:
  1855. @code void decorator(
  1856. response_type& res
  1857. ); @endcode
  1858. @param handler Invoked when the operation completes.
  1859. The handler may be moved or copied as needed.
  1860. The equivalent function signature of the handler must be:
  1861. @code void handler(
  1862. error_code const& ec // Result of operation
  1863. ); @endcode
  1864. Regardless of whether the asynchronous operation completes
  1865. immediately or not, the handler will not be invoked from within
  1866. this function. Invocation of the handler will be performed in a
  1867. manner equivalent to using `boost::asio::io_context::post`.
  1868. */
  1869. template<
  1870. class Body, class Allocator,
  1871. class ResponseDecorator,
  1872. class AcceptHandler>
  1873. BOOST_ASIO_INITFN_RESULT_TYPE(
  1874. AcceptHandler, void(error_code))
  1875. async_accept_ex(
  1876. http::request<Body,
  1877. http::basic_fields<Allocator>> const& req,
  1878. ResponseDecorator const& decorator,
  1879. AcceptHandler&& handler);
  1880. //--------------------------------------------------------------------------
  1881. //
  1882. // Control Frames
  1883. //
  1884. //--------------------------------------------------------------------------
  1885. /** Send a WebSocket close frame.
  1886. This function is used to synchronously send a close frame on
  1887. the stream. The call blocks until one of the following is true:
  1888. @li The close frame finishes sending.
  1889. @li An error occurs on the stream.
  1890. This function is implemented in terms of one or more calls
  1891. to the next layer's `write_some` functions.
  1892. If the close reason specifies a close code other than
  1893. @ref beast::websocket::close_code::none, the close frame is
  1894. sent with the close code and optional reason string. Otherwise,
  1895. the close frame is sent with no payload.
  1896. Callers should not attempt to write WebSocket data after
  1897. initiating the close. Instead, callers should continue
  1898. reading until an error occurs. A read returning @ref error::closed
  1899. indicates a successful connection closure.
  1900. @param cr The reason for the close.
  1901. @throws system_error Thrown on failure.
  1902. */
  1903. void
  1904. close(close_reason const& cr);
  1905. /** Send a WebSocket close frame.
  1906. This function is used to synchronously send a close frame on
  1907. the stream. The call blocks until one of the following is true:
  1908. @li The close frame finishes sending.
  1909. @li An error occurs on the stream.
  1910. This function is implemented in terms of one or more calls
  1911. to the next layer's `write_some` functions.
  1912. If the close reason specifies a close code other than
  1913. @ref beast::websocket::close_code::none, the close frame is
  1914. sent with the close code and optional reason string. Otherwise,
  1915. the close frame is sent with no payload.
  1916. Callers should not attempt to write WebSocket data after
  1917. initiating the close. Instead, callers should continue
  1918. reading until an error occurs. A read returning @ref error::closed
  1919. indicates a successful connection closure.
  1920. @param cr The reason for the close.
  1921. @param ec Set to indicate what error occurred, if any.
  1922. */
  1923. void
  1924. close(close_reason const& cr, error_code& ec);
  1925. /** Start an asynchronous operation to send a WebSocket close frame.
  1926. This function is used to asynchronously send a close frame on
  1927. the stream. This function call always returns immediately. The
  1928. asynchronous operation will continue until one of the following
  1929. conditions is true:
  1930. @li The close frame finishes sending.
  1931. @li An error occurs on the stream.
  1932. This operation is implemented in terms of one or more calls to the
  1933. next layer's `async_write_some` functions, and is known as a
  1934. <em>composed operation</em>. The program must ensure that the
  1935. stream performs no other write operations (such as @ref async_ping,
  1936. @ref async_write, @ref async_write_some, or @ref async_close)
  1937. until this operation completes.
  1938. If the close reason specifies a close code other than
  1939. @ref beast::websocket::close_code::none, the close frame is
  1940. sent with the close code and optional reason string. Otherwise,
  1941. the close frame is sent with no payload.
  1942. Callers should not attempt to write WebSocket data after
  1943. initiating the close. Instead, callers should continue
  1944. reading until an error occurs. A read returning @ref error::closed
  1945. indicates a successful connection closure.
  1946. @param cr The reason for the close.
  1947. @param handler Invoked when the operation completes.
  1948. The handler may be moved or copied as needed.
  1949. The function signature of the handler must be:
  1950. @code
  1951. void handler(
  1952. error_code const& ec // Result of operation
  1953. );
  1954. @endcode
  1955. Regardless of whether the asynchronous operation completes
  1956. immediately or not, the handler will not be invoked from within
  1957. this function. Invocation of the handler will be performed in a
  1958. manner equivalent to using `boost::asio::io_context::post`.
  1959. */
  1960. template<class CloseHandler>
  1961. BOOST_ASIO_INITFN_RESULT_TYPE(
  1962. CloseHandler, void(error_code))
  1963. async_close(close_reason const& cr, CloseHandler&& handler);
  1964. /** Send a WebSocket ping frame.
  1965. This function is used to synchronously send a ping frame on
  1966. the stream. The call blocks until one of the following is true:
  1967. @li The ping frame finishes sending.
  1968. @li An error occurs on the stream.
  1969. This function is implemented in terms of one or more calls to the
  1970. next layer's `write_some` functions.
  1971. @param payload The payload of the ping message, which may be empty.
  1972. @throws system_error Thrown on failure.
  1973. */
  1974. void
  1975. ping(ping_data const& payload);
  1976. /** Send a WebSocket ping frame.
  1977. This function is used to synchronously send a ping frame on
  1978. the stream. The call blocks until one of the following is true:
  1979. @li The ping frame finishes sending.
  1980. @li An error occurs on the stream.
  1981. This function is implemented in terms of one or more calls to the
  1982. next layer's `write_some` functions.
  1983. @param payload The payload of the ping message, which may be empty.
  1984. @param ec Set to indicate what error occurred, if any.
  1985. */
  1986. void
  1987. ping(ping_data const& payload, error_code& ec);
  1988. /** Start an asynchronous operation to send a WebSocket ping frame.
  1989. This function is used to asynchronously send a ping frame to
  1990. the stream. The function call always returns immediately. The
  1991. asynchronous operation will continue until one of the following
  1992. is true:
  1993. @li The entire ping frame is sent.
  1994. @li An error occurs on the stream.
  1995. This operation is implemented in terms of one or more calls to the
  1996. next layer's `async_write_some` functions, and is known as a
  1997. <em>composed operation</em>. The program must ensure that the
  1998. stream performs no other writes until this operation completes.
  1999. If a close frame is sent or received before the ping frame is
  2000. sent, the completion handler will be called with the error
  2001. set to `boost::asio::error::operation_aborted`.
  2002. @param payload The payload of the ping message, which may be empty.
  2003. @param handler Invoked when the operation completes.
  2004. The handler may be moved or copied as needed.
  2005. The function signature of the handler must be:
  2006. @code
  2007. void handler(
  2008. error_code const& ec // Result of operation
  2009. );
  2010. @endcode
  2011. Regardless of whether the asynchronous operation completes
  2012. immediately or not, the handler will not be invoked from within
  2013. this function. Invocation of the handler will be performed in a
  2014. manner equivalent to using `boost::asio::io_context::post`.
  2015. */
  2016. template<class WriteHandler>
  2017. BOOST_ASIO_INITFN_RESULT_TYPE(
  2018. WriteHandler, void(error_code))
  2019. async_ping(ping_data const& payload, WriteHandler&& handler);
  2020. /** Send a WebSocket pong frame.
  2021. This function is used to synchronously send a pong frame on
  2022. the stream. The call blocks until one of the following is true:
  2023. @li The pong frame finishes sending.
  2024. @li An error occurs on the stream.
  2025. This function is implemented in terms of one or more calls to the
  2026. next layer's `write_some` functions.
  2027. The WebSocket protocol allows pong frames to be sent from either
  2028. end at any time. It is not necessary to first receive a ping in
  2029. order to send a pong. The remote peer may use the receipt of a
  2030. pong frame as an indication that the connection is not dead.
  2031. @param payload The payload of the pong message, which may be empty.
  2032. @throws system_error Thrown on failure.
  2033. */
  2034. void
  2035. pong(ping_data const& payload);
  2036. /** Send a WebSocket pong frame.
  2037. This function is used to synchronously send a pong frame on
  2038. the stream. The call blocks until one of the following is true:
  2039. @li The pong frame finishes sending.
  2040. @li An error occurs on the stream.
  2041. This function is implemented in terms of one or more calls to the
  2042. next layer's `write_some` functions.
  2043. The WebSocket protocol allows pong frames to be sent from either
  2044. end at any time. It is not necessary to first receive a ping in
  2045. order to send a pong. The remote peer may use the receipt of a
  2046. pong frame as an indication that the connection is not dead.
  2047. @param payload The payload of the pong message, which may be empty.
  2048. @param ec Set to indicate what error occurred, if any.
  2049. */
  2050. void
  2051. pong(ping_data const& payload, error_code& ec);
  2052. /** Start an asynchronous operation to send a WebSocket pong frame.
  2053. This function is used to asynchronously send a pong frame to
  2054. the stream. The function call always returns immediately. The
  2055. asynchronous operation will continue until one of the following
  2056. is true:
  2057. @li The entire pong frame is sent.
  2058. @li An error occurs on the stream.
  2059. This operation is implemented in terms of one or more calls to the
  2060. next layer's `async_write_some` functions, and is known as a
  2061. <em>composed operation</em>. The program must ensure that the
  2062. stream performs no other writes until this operation completes.
  2063. The WebSocket protocol allows pong frames to be sent from either
  2064. end at any time. It is not necessary to first receive a ping in
  2065. order to send a pong. The remote peer may use the receipt of a
  2066. pong frame as an indication that the connection is not dead.
  2067. If a close frame is sent or received before the pong frame is
  2068. sent, the completion handler will be called with the error
  2069. set to `boost::asio::error::operation_aborted`.
  2070. @param payload The payload of the pong message, which may be empty.
  2071. @param handler Invoked when the operation completes.
  2072. The handler may be moved or copied as needed.
  2073. The function signature of the handler must be:
  2074. @code
  2075. void handler(
  2076. error_code const& ec // Result of operation
  2077. );
  2078. @endcode
  2079. Regardless of whether the asynchronous operation completes
  2080. immediately or not, the handler will not be invoked from within
  2081. this function. Invocation of the handler will be performed in a
  2082. manner equivalent to using `boost::asio::io_context::post`.
  2083. */
  2084. template<class WriteHandler>
  2085. BOOST_ASIO_INITFN_RESULT_TYPE(
  2086. WriteHandler, void(error_code))
  2087. async_pong(ping_data const& payload, WriteHandler&& handler);
  2088. //--------------------------------------------------------------------------
  2089. //
  2090. // Reading
  2091. //
  2092. //--------------------------------------------------------------------------
  2093. /** Read a message
  2094. This function is used to synchronously read a complete
  2095. message from the stream.
  2096. The call blocks until one of the following is true:
  2097. @li A complete message is received.
  2098. @li A close frame is received. In this case the error indicated by
  2099. the function will be @ref error::closed.
  2100. @li An error occurs on the stream.
  2101. This operation is implemented in terms of one or more calls to the next
  2102. layer's `read_some` and `write_some` functions.
  2103. Received message data, if any, is appended to the input area of the
  2104. buffer. The functions @ref got_binary and @ref got_text may be used
  2105. to query the stream and determine the type of the last received message.
  2106. While this operation is active, the implementation will read incoming
  2107. control frames and handle them automatically as follows:
  2108. @li The @ref control_callback will be invoked for each control frame.
  2109. @li For each received ping frame, a pong frame will be
  2110. automatically sent.
  2111. @li If a close frame is received, the WebSocket close procedure is
  2112. performed. In this case, when the function returns, the error
  2113. @ref error::closed will be indicated.
  2114. @return The number of message payload bytes appended to the buffer.
  2115. @param buffer A dynamic buffer to hold the message data after any
  2116. masking or decompression has been applied.
  2117. @throws system_error Thrown to indicate an error. The corresponding
  2118. error code may be retrieved from the exception object for inspection.
  2119. */
  2120. template<class DynamicBuffer>
  2121. std::size_t
  2122. read(DynamicBuffer& buffer);
  2123. /** Read a message
  2124. This function is used to synchronously read a complete
  2125. message from the stream.
  2126. The call blocks until one of the following is true:
  2127. @li A complete message is received.
  2128. @li A close frame is received. In this case the error indicated by
  2129. the function will be @ref error::closed.
  2130. @li An error occurs on the stream.
  2131. This operation is implemented in terms of one or more calls to the next
  2132. layer's `read_some` and `write_some` functions.
  2133. Received message data, if any, is appended to the input area of the
  2134. buffer. The functions @ref got_binary and @ref got_text may be used
  2135. to query the stream and determine the type of the last received message.
  2136. While this operation is active, the implementation will read incoming
  2137. control frames and handle them automatically as follows:
  2138. @li The @ref control_callback will be invoked for each control frame.
  2139. @li For each received ping frame, a pong frame will be
  2140. automatically sent.
  2141. @li If a close frame is received, the WebSocket close procedure is
  2142. performed. In this case, when the function returns, the error
  2143. @ref error::closed will be indicated.
  2144. @return The number of message payload bytes appended to the buffer.
  2145. @param buffer A dynamic buffer to hold the message data after any
  2146. masking or decompression has been applied.
  2147. @param ec Set to indicate what error occurred, if any.
  2148. */
  2149. template<class DynamicBuffer>
  2150. std::size_t
  2151. read(DynamicBuffer& buffer, error_code& ec);
  2152. /** Read a message asynchronously
  2153. This function is used to asynchronously read a complete
  2154. message from the stream.
  2155. The function call always returns immediately.
  2156. The asynchronous operation will continue until one of the
  2157. following is true:
  2158. @li A complete message is received.
  2159. @li A close frame is received. In this case the error indicated by
  2160. the function will be @ref error::closed.
  2161. @li An error occurs on the stream.
  2162. This operation is implemented in terms of one or more calls to the
  2163. next layer's `async_read_some` and `async_write_some` functions,
  2164. and is known as a <em>composed operation</em>. The program must
  2165. ensure that the stream performs no other reads until this operation
  2166. completes.
  2167. Received message data, if any, is appended to the input area of the
  2168. buffer. The functions @ref got_binary and @ref got_text may be used
  2169. to query the stream and determine the type of the last received message.
  2170. While this operation is active, the implementation will read incoming
  2171. control frames and handle them automatically as follows:
  2172. @li The @ref control_callback will be invoked for each control frame.
  2173. @li For each received ping frame, a pong frame will be
  2174. automatically sent.
  2175. @li If a close frame is received, the WebSocket close procedure is
  2176. performed. In this case, when the function returns, the error
  2177. @ref error::closed will be indicated.
  2178. Because of the need to handle control frames, asynchronous read
  2179. operations can cause writes to take place. These writes are managed
  2180. transparently; callers can still have one active asynchronous
  2181. read and asynchronous write operation pending simultaneously
  2182. (a user initiated call to @ref async_close counts as a write).
  2183. @param buffer A dynamic buffer to hold the message data after
  2184. any masking or decompression has been applied. This object must
  2185. remain valid until the handler is called.
  2186. @param handler Invoked when the operation completes.
  2187. The handler may be moved or copied as needed.
  2188. The equivalent function signature of the handler must be:
  2189. @code
  2190. void handler(
  2191. error_code const& ec, // Result of operation
  2192. std::size_t bytes_written // Number of bytes appended to buffer
  2193. );
  2194. @endcode
  2195. Regardless of whether the asynchronous operation completes
  2196. immediately or not, the handler will not be invoked from within
  2197. this function. Invocation of the handler will be performed in a
  2198. manner equivalent to using `boost::asio::io_context::post`.
  2199. */
  2200. template<class DynamicBuffer, class ReadHandler>
  2201. BOOST_ASIO_INITFN_RESULT_TYPE(
  2202. ReadHandler, void(error_code, std::size_t))
  2203. async_read(
  2204. DynamicBuffer& buffer,
  2205. ReadHandler&& handler);
  2206. //--------------------------------------------------------------------------
  2207. /** Read part of a message
  2208. This function is used to synchronously read some
  2209. message data from the stream.
  2210. The call blocks until one of the following is true:
  2211. @li Some or all of the message is received.
  2212. @li A close frame is received. In this case the error indicated by
  2213. the function will be @ref error::closed.
  2214. @li An error occurs on the stream.
  2215. This operation is implemented in terms of one or more calls to the next
  2216. layer's `read_some` and `write_some` functions.
  2217. Received message data, if any, is appended to the input area of the
  2218. buffer. The functions @ref got_binary and @ref got_text may be used
  2219. to query the stream and determine the type of the last received message.
  2220. The function @ref is_message_done may be called to determine if the
  2221. message received by the last read operation is complete.
  2222. While this operation is active, the implementation will read incoming
  2223. control frames and handle them automatically as follows:
  2224. @li The @ref control_callback will be invoked for each control frame.
  2225. @li For each received ping frame, a pong frame will be
  2226. automatically sent.
  2227. @li If a close frame is received, the WebSocket close procedure is
  2228. performed. In this case, when the function returns, the error
  2229. @ref error::closed will be indicated.
  2230. @return The number of message payload bytes appended to the buffer.
  2231. @param buffer A dynamic buffer to hold the message data after any
  2232. masking or decompression has been applied.
  2233. @param limit An upper limit on the number of bytes this function
  2234. will append into the buffer. If this value is zero, then a reasonable
  2235. size will be chosen automatically.
  2236. @throws system_error Thrown to indicate an error. The corresponding
  2237. error code may be retrieved from the exception object for inspection.
  2238. */
  2239. template<class DynamicBuffer>
  2240. std::size_t
  2241. read_some(
  2242. DynamicBuffer& buffer,
  2243. std::size_t limit);
  2244. /** Read part of a message
  2245. This function is used to synchronously read some
  2246. message data from the stream.
  2247. The call blocks until one of the following is true:
  2248. @li Some or all of the message is received.
  2249. @li A close frame is received. In this case the error indicated by
  2250. the function will be @ref error::closed.
  2251. @li An error occurs on the stream.
  2252. This operation is implemented in terms of one or more calls to the next
  2253. layer's `read_some` and `write_some` functions.
  2254. Received message data, if any, is appended to the input area of the
  2255. buffer. The functions @ref got_binary and @ref got_text may be used
  2256. to query the stream and determine the type of the last received message.
  2257. The function @ref is_message_done may be called to determine if the
  2258. message received by the last read operation is complete.
  2259. While this operation is active, the implementation will read incoming
  2260. control frames and handle them automatically as follows:
  2261. @li The @ref control_callback will be invoked for each control frame.
  2262. @li For each received ping frame, a pong frame will be
  2263. automatically sent.
  2264. @li If a close frame is received, the WebSocket close procedure is
  2265. performed. In this case, when the function returns, the error
  2266. @ref error::closed will be indicated.
  2267. @return The number of message payload bytes appended to the buffer.
  2268. @param buffer A dynamic buffer to hold the message data after any
  2269. masking or decompression has been applied.
  2270. @param limit An upper limit on the number of bytes this function
  2271. will append into the buffer. If this value is zero, then a reasonable
  2272. size will be chosen automatically.
  2273. @param ec Set to indicate what error occurred, if any.
  2274. */
  2275. template<class DynamicBuffer>
  2276. std::size_t
  2277. read_some(
  2278. DynamicBuffer& buffer,
  2279. std::size_t limit,
  2280. error_code& ec);
  2281. /** Read part of a message asynchronously
  2282. This function is used to asynchronously read part of a
  2283. message from the stream.
  2284. The function call always returns immediately.
  2285. The asynchronous operation will continue until one of the
  2286. following is true:
  2287. @li Some or all of the message is received.
  2288. @li A close frame is received. In this case the error indicated by
  2289. the function will be @ref error::closed.
  2290. @li An error occurs on the stream.
  2291. This operation is implemented in terms of one or more calls to the
  2292. next layer's `async_read_some` and `async_write_some` functions,
  2293. and is known as a <em>composed operation</em>. The program must
  2294. ensure that the stream performs no other reads until this operation
  2295. completes.
  2296. Received message data, if any, is appended to the input area of the
  2297. buffer. The functions @ref got_binary and @ref got_text may be used
  2298. to query the stream and determine the type of the last received message.
  2299. The function @ref is_message_done may be called to determine if the
  2300. message received by the last read operation is complete.
  2301. While this operation is active, the implementation will read incoming
  2302. control frames and handle them automatically as follows:
  2303. @li The @ref control_callback will be invoked for each control frame.
  2304. @li For each received ping frame, a pong frame will be
  2305. automatically sent.
  2306. @li If a close frame is received, the WebSocket close procedure is
  2307. performed. In this case, when the function returns, the error
  2308. @ref error::closed will be indicated.
  2309. Because of the need to handle control frames, asynchronous read
  2310. operations can cause writes to take place. These writes are managed
  2311. transparently; callers can still have one active asynchronous
  2312. read and asynchronous write operation pending simultaneously
  2313. (a user initiated call to @ref async_close counts as a write).
  2314. @param buffer A dynamic buffer to hold the message data after
  2315. any masking or decompression has been applied. This object must
  2316. remain valid until the handler is called.
  2317. @param limit An upper limit on the number of bytes this function
  2318. will append into the buffer. If this value is zero, then a reasonable
  2319. size will be chosen automatically.
  2320. @param handler Invoked when the operation completes.
  2321. The handler may be moved or copied as needed.
  2322. The equivalent function signature of the handler must be:
  2323. @code
  2324. void handler(
  2325. error_code const& ec, // Result of operation
  2326. std::size_t bytes_written // Number of bytes appended to buffer
  2327. );
  2328. @endcode
  2329. Regardless of whether the asynchronous operation completes
  2330. immediately or not, the handler will not be invoked from within
  2331. this function. Invocation of the handler will be performed in a
  2332. manner equivalent to using `boost::asio::io_context::post`.
  2333. */
  2334. template<class DynamicBuffer, class ReadHandler>
  2335. BOOST_ASIO_INITFN_RESULT_TYPE(
  2336. ReadHandler, void(error_code, std::size_t))
  2337. async_read_some(
  2338. DynamicBuffer& buffer,
  2339. std::size_t limit,
  2340. ReadHandler&& handler);
  2341. //--------------------------------------------------------------------------
  2342. /** Read part of a message
  2343. This function is used to synchronously read some
  2344. message data from the stream.
  2345. The call blocks until one of the following is true:
  2346. @li Some or all of the message is received.
  2347. @li A close frame is received. In this case the error indicated by
  2348. the function will be @ref error::closed.
  2349. @li An error occurs on the stream.
  2350. This operation is implemented in terms of one or more calls to the next
  2351. layer's `read_some` and `write_some` functions.
  2352. Received message data, if any, is written to the buffer sequence.
  2353. The functions @ref got_binary and @ref got_text may be used
  2354. to query the stream and determine the type of the last received message.
  2355. The function @ref is_message_done may be called to determine if the
  2356. message received by the last read operation is complete.
  2357. While this operation is active, the implementation will read incoming
  2358. control frames and handle them automatically as follows:
  2359. @li The @ref control_callback will be invoked for each control frame.
  2360. @li For each received ping frame, a pong frame will be
  2361. automatically sent.
  2362. @li If a close frame is received, the WebSocket close procedure is
  2363. performed. In this case, when the function returns, the error
  2364. @ref error::closed will be indicated.
  2365. @return The number of message payload bytes written to the
  2366. buffer sequence.
  2367. @param buffers A buffer sequence to hold the message data after any
  2368. masking or decompression has been applied.
  2369. @throws system_error Thrown to indicate an error. The corresponding
  2370. error code may be retrieved from the exception object for inspection.
  2371. */
  2372. template<class MutableBufferSequence>
  2373. std::size_t
  2374. read_some(
  2375. MutableBufferSequence const& buffers);
  2376. /** Read part of a message
  2377. This function is used to synchronously read some
  2378. message data from the stream.
  2379. The call blocks until one of the following is true:
  2380. @li Some or all of the message is received.
  2381. @li A close frame is received. In this case the error indicated by
  2382. the function will be @ref error::closed.
  2383. @li An error occurs on the stream.
  2384. This operation is implemented in terms of one or more calls to the next
  2385. layer's `read_some` and `write_some` functions.
  2386. Received message data, if any, is written to the buffer sequence.
  2387. The functions @ref got_binary and @ref got_text may be used
  2388. to query the stream and determine the type of the last received message.
  2389. The function @ref is_message_done may be called to determine if the
  2390. message received by the last read operation is complete.
  2391. While this operation is active, the implementation will read incoming
  2392. control frames and handle them automatically as follows:
  2393. @li The @ref control_callback will be invoked for each control frame.
  2394. @li For each received ping frame, a pong frame will be
  2395. automatically sent.
  2396. @li If a close frame is received, the WebSocket close procedure is
  2397. performed. In this case, when the function returns, the error
  2398. @ref error::closed will be indicated.
  2399. @return The number of message payload bytes written to the
  2400. buffer sequence.
  2401. @param buffers A buffer sequence to hold the message data after any
  2402. masking or decompression has been applied.
  2403. @param ec Set to indicate what error occurred, if any.
  2404. */
  2405. template<class MutableBufferSequence>
  2406. std::size_t
  2407. read_some(
  2408. MutableBufferSequence const& buffers,
  2409. error_code& ec);
  2410. /** Read part of a message asynchronously
  2411. This function is used to asynchronously read part of a
  2412. message from the stream.
  2413. The function call always returns immediately.
  2414. The asynchronous operation will continue until one of the
  2415. following is true:
  2416. @li Some or all of the message is received.
  2417. @li A close frame is received. In this case the error indicated by
  2418. the function will be @ref error::closed.
  2419. @li An error occurs on the stream.
  2420. This operation is implemented in terms of one or more calls to the
  2421. next layer's `async_read_some` and `async_write_some` functions,
  2422. and is known as a <em>composed operation</em>. The program must
  2423. ensure that the stream performs no other reads until this operation
  2424. completes.
  2425. Received message data, if any, is written to the buffer sequence.
  2426. The functions @ref got_binary and @ref got_text may be used
  2427. to query the stream and determine the type of the last received message.
  2428. The function @ref is_message_done may be called to determine if the
  2429. message received by the last read operation is complete.
  2430. While this operation is active, the implementation will read incoming
  2431. control frames and handle them automatically as follows:
  2432. @li The @ref control_callback will be invoked for each control frame.
  2433. @li For each received ping frame, a pong frame will be
  2434. automatically sent.
  2435. @li If a close frame is received, the WebSocket close procedure is
  2436. performed. In this case, when the function returns, the error
  2437. @ref error::closed will be indicated.
  2438. Because of the need to handle control frames, asynchronous read
  2439. operations can cause writes to take place. These writes are managed
  2440. transparently; callers can still have one active asynchronous
  2441. read and asynchronous write operation pending simultaneously
  2442. (a user initiated call to @ref async_close counts as a write).
  2443. @param buffers The buffer sequence into which message data will
  2444. be placed after any masking or decompresison has been applied.
  2445. The implementation will make copies of this object as needed,
  2446. but ownership of the underlying memory is not transferred.
  2447. The caller is responsible for ensuring that the memory
  2448. locations pointed to by the buffer sequence remains valid
  2449. until the completion handler is called.
  2450. @param handler Invoked when the operation completes.
  2451. The handler may be moved or copied as needed.
  2452. The equivalent function signature of the handler must be:
  2453. @code
  2454. void handler(
  2455. error_code const& ec, // Result of operation
  2456. std::size_t bytes_written // Number of bytes written to the buffer sequence
  2457. );
  2458. @endcode
  2459. Regardless of whether the asynchronous operation completes
  2460. immediately or not, the handler will not be invoked from within
  2461. this function. Invocation of the handler will be performed in a
  2462. manner equivalent to using `boost::asio::io_context::post`.
  2463. */
  2464. template<class MutableBufferSequence, class ReadHandler>
  2465. BOOST_ASIO_INITFN_RESULT_TYPE(
  2466. ReadHandler, void(error_code, std::size_t))
  2467. async_read_some(
  2468. MutableBufferSequence const& buffers,
  2469. ReadHandler&& handler);
  2470. //--------------------------------------------------------------------------
  2471. //
  2472. // Writing
  2473. //
  2474. //--------------------------------------------------------------------------
  2475. /** Write a message to the stream.
  2476. This function is used to synchronously write a message to
  2477. the stream. The call blocks until one of the following conditions
  2478. is met:
  2479. @li The entire message is sent.
  2480. @li An error occurs.
  2481. This operation is implemented in terms of one or more calls to the
  2482. next layer's `write_some` function.
  2483. The current setting of the @ref binary option controls
  2484. whether the message opcode is set to text or binary. If the
  2485. @ref auto_fragment option is set, the message will be split
  2486. into one or more frames as necessary. The actual payload contents
  2487. sent may be transformed as per the WebSocket protocol settings.
  2488. @param buffers The buffers containing the entire message
  2489. payload. The implementation will make copies of this object
  2490. as needed, but ownership of the underlying memory is not
  2491. transferred. The caller is responsible for ensuring that
  2492. the memory locations pointed to by buffers remains valid
  2493. until the completion handler is called.
  2494. @return The number of bytes written from the buffers.
  2495. If an error occurred, this will be less than the sum
  2496. of the buffer sizes.
  2497. @throws system_error Thrown on failure.
  2498. @note This function always sends an entire message. To
  2499. send a message in fragments, use @ref write_some.
  2500. */
  2501. template<class ConstBufferSequence>
  2502. std::size_t
  2503. write(ConstBufferSequence const& buffers);
  2504. /** Write a message to the stream.
  2505. This function is used to synchronously write a message to
  2506. the stream. The call blocks until one of the following conditions
  2507. is met:
  2508. @li The entire message is sent.
  2509. @li An error occurs.
  2510. This operation is implemented in terms of one or more calls to the
  2511. next layer's `write_some` function.
  2512. The current setting of the @ref binary option controls
  2513. whether the message opcode is set to text or binary. If the
  2514. @ref auto_fragment option is set, the message will be split
  2515. into one or more frames as necessary. The actual payload contents
  2516. sent may be transformed as per the WebSocket protocol settings.
  2517. @param buffers The buffers containing the entire message
  2518. payload. The implementation will make copies of this object
  2519. as needed, but ownership of the underlying memory is not
  2520. transferred. The caller is responsible for ensuring that
  2521. the memory locations pointed to by buffers remains valid
  2522. until the completion handler is called.
  2523. @return The number of bytes written from the buffers.
  2524. If an error occurred, this will be less than the sum
  2525. of the buffer sizes.
  2526. @param ec Set to indicate what error occurred, if any.
  2527. @throws system_error Thrown on failure.
  2528. @note This function always sends an entire message. To
  2529. send a message in fragments, use @ref write_some.
  2530. */
  2531. template<class ConstBufferSequence>
  2532. std::size_t
  2533. write(ConstBufferSequence const& buffers, error_code& ec);
  2534. /** Start an asynchronous operation to write a message to the stream.
  2535. This function is used to asynchronously write a message to
  2536. the stream. The function call always returns immediately.
  2537. The asynchronous operation will continue until one of the
  2538. following conditions is true:
  2539. @li The entire message is sent.
  2540. @li An error occurs.
  2541. This operation is implemented in terms of one or more calls
  2542. to the next layer's `async_write_some` functions, and is known
  2543. as a <em>composed operation</em>. The program must ensure that
  2544. the stream performs no other write operations (such as
  2545. @ref async_write, @ref async_write_some, or
  2546. @ref async_close).
  2547. The current setting of the @ref binary option controls
  2548. whether the message opcode is set to text or binary. If the
  2549. @ref auto_fragment option is set, the message will be split
  2550. into one or more frames as necessary. The actual payload contents
  2551. sent may be transformed as per the WebSocket protocol settings.
  2552. @param buffers The buffers containing the entire message
  2553. payload. The implementation will make copies of this object
  2554. as needed, but ownership of the underlying memory is not
  2555. transferred. The caller is responsible for ensuring that
  2556. the memory locations pointed to by buffers remains valid
  2557. until the completion handler is called.
  2558. @param handler Invoked when the operation completes.
  2559. The handler may be moved or copied as needed.
  2560. The function signature of the handler must be:
  2561. @code
  2562. void handler(
  2563. error_code const& ec, // Result of operation
  2564. std::size_t bytes_transferred // Number of bytes written from the
  2565. // buffers. If an error occurred,
  2566. // this will be less than the sum
  2567. // of the buffer sizes.
  2568. );
  2569. @endcode
  2570. Regardless of whether the asynchronous operation completes
  2571. immediately or not, the handler will not be invoked from within
  2572. this function. Invocation of the handler will be performed in a
  2573. manner equivalent to using `boost::asio::io_context::post`.
  2574. */
  2575. template<
  2576. class ConstBufferSequence,
  2577. class WriteHandler>
  2578. BOOST_ASIO_INITFN_RESULT_TYPE(
  2579. WriteHandler, void(error_code, std::size_t))
  2580. async_write(
  2581. ConstBufferSequence const& buffers,
  2582. WriteHandler&& handler);
  2583. /** Write partial message data on the stream.
  2584. This function is used to write some or all of a message's
  2585. payload to the stream. The call will block until one of the
  2586. following conditions is true:
  2587. @li A frame is sent.
  2588. @li Message data is transferred to the write buffer.
  2589. @li An error occurs.
  2590. This operation is implemented in terms of one or more calls
  2591. to the stream's `write_some` function.
  2592. If this is the beginning of a new message, the message opcode
  2593. will be set to text or binary as per the current setting of
  2594. the @ref binary option. The actual payload sent may be
  2595. transformed as per the WebSocket protocol settings.
  2596. @param fin `true` if this is the last part of the message.
  2597. @param buffers The input buffer sequence holding the data to write.
  2598. @return The number of bytes written from the buffers.
  2599. If an error occurred, this will be less than the sum
  2600. of the buffer sizes.
  2601. @throws system_error Thrown on failure.
  2602. */
  2603. template<class ConstBufferSequence>
  2604. std::size_t
  2605. write_some(bool fin, ConstBufferSequence const& buffers);
  2606. /** Write partial message data on the stream.
  2607. This function is used to write some or all of a message's
  2608. payload to the stream. The call will block until one of the
  2609. following conditions is true:
  2610. @li A frame is sent.
  2611. @li Message data is transferred to the write buffer.
  2612. @li An error occurs.
  2613. This operation is implemented in terms of one or more calls
  2614. to the stream's `write_some` function.
  2615. If this is the beginning of a new message, the message opcode
  2616. will be set to text or binary as per the current setting of
  2617. the @ref binary option. The actual payload sent may be
  2618. transformed as per the WebSocket protocol settings.
  2619. @param fin `true` if this is the last part of the message.
  2620. @param buffers The input buffer sequence holding the data to write.
  2621. @param ec Set to indicate what error occurred, if any.
  2622. @return The number of bytes written from the buffers.
  2623. If an error occurred, this will be less than the sum
  2624. of the buffer sizes.
  2625. @return The number of bytes consumed in the input buffers.
  2626. */
  2627. template<class ConstBufferSequence>
  2628. std::size_t
  2629. write_some(bool fin,
  2630. ConstBufferSequence const& buffers, error_code& ec);
  2631. /** Start an asynchronous operation to send a message frame on the stream.
  2632. This function is used to asynchronously write a message frame
  2633. on the stream. This function call always returns immediately.
  2634. The asynchronous operation will continue until one of the following
  2635. conditions is true:
  2636. @li The entire frame is sent.
  2637. @li An error occurs.
  2638. This operation is implemented in terms of one or more calls
  2639. to the next layer's `async_write_some` functions, and is known
  2640. as a <em>composed operation</em>. The actual payload sent
  2641. may be transformed as per the WebSocket protocol settings. The
  2642. program must ensure that the stream performs no other write
  2643. operations (such as @ref async_write, @ref async_write_some,
  2644. or @ref async_close).
  2645. If this is the beginning of a new message, the message opcode
  2646. will be set to text or binary as per the current setting of
  2647. the @ref binary option. The actual payload sent may be
  2648. transformed as per the WebSocket protocol settings.
  2649. @param fin `true` if this is the last part of the message.
  2650. @param buffers A object meeting the requirements of
  2651. ConstBufferSequence which holds the payload data before any
  2652. masking or compression. Although the buffers object may be copied
  2653. as necessary, ownership of the underlying buffers is retained by
  2654. the caller, which must guarantee that they remain valid until
  2655. the handler is called.
  2656. @param handler Invoked when the operation completes.
  2657. The handler may be moved or copied as needed.
  2658. The equivalent function signature of the handler must be:
  2659. @code void handler(
  2660. error_code const& ec, // Result of operation
  2661. std::size_t bytes_transferred // Number of bytes written from the
  2662. // buffers. If an error occurred,
  2663. // this will be less than the sum
  2664. // of the buffer sizes.
  2665. ); @endcode
  2666. */
  2667. template<class ConstBufferSequence, class WriteHandler>
  2668. BOOST_ASIO_INITFN_RESULT_TYPE(
  2669. WriteHandler, void(error_code, std::size_t))
  2670. async_write_some(bool fin,
  2671. ConstBufferSequence const& buffers, WriteHandler&& handler);
  2672. private:
  2673. template<class, class> class accept_op;
  2674. template<class> class close_op;
  2675. template<class> class handshake_op;
  2676. template<class> class ping_op;
  2677. template<class, class> class read_some_op;
  2678. template<class, class> class read_op;
  2679. template<class> class response_op;
  2680. template<class, class> class write_some_op;
  2681. template<class, class> class write_op;
  2682. static void default_decorate_req(request_type&) {}
  2683. static void default_decorate_res(response_type&) {}
  2684. void
  2685. set_option(permessage_deflate const& o, std::true_type);
  2686. void
  2687. set_option(permessage_deflate const&, std::false_type);
  2688. void
  2689. get_option(permessage_deflate& o, std::true_type)
  2690. {
  2691. o = this->pmd_opts_;
  2692. }
  2693. void
  2694. get_option(permessage_deflate& o, std::false_type)
  2695. {
  2696. o = {};
  2697. o.client_enable = false;
  2698. o.server_enable = false;
  2699. }
  2700. void open(role_type role);
  2701. void open_pmd(std::true_type);
  2702. void open_pmd(std::false_type)
  2703. {
  2704. }
  2705. void close();
  2706. void close_pmd(std::true_type)
  2707. {
  2708. this->pmd_.reset();
  2709. }
  2710. void close_pmd(std::false_type)
  2711. {
  2712. }
  2713. void reset();
  2714. void begin_msg()
  2715. {
  2716. begin_msg(is_deflate_supported{});
  2717. }
  2718. void begin_msg(std::true_type);
  2719. void begin_msg(std::false_type);
  2720. std::size_t
  2721. read_size_hint(
  2722. std::size_t initial_size,
  2723. std::true_type) const;
  2724. std::size_t
  2725. read_size_hint(
  2726. std::size_t initial_size,
  2727. std::false_type) const;
  2728. bool
  2729. check_open(error_code& ec)
  2730. {
  2731. if(status_ != status::open)
  2732. {
  2733. ec = boost::asio::error::operation_aborted;
  2734. return false;
  2735. }
  2736. ec.assign(0, ec.category());
  2737. return true;
  2738. }
  2739. bool
  2740. check_ok(error_code& ec)
  2741. {
  2742. if(ec)
  2743. {
  2744. if(status_ != status::closed)
  2745. status_ = status::failed;
  2746. return false;
  2747. }
  2748. return true;
  2749. }
  2750. template<class DynamicBuffer>
  2751. bool
  2752. parse_fh(
  2753. detail::frame_header& fh,
  2754. DynamicBuffer& b,
  2755. error_code& ec);
  2756. template<class DynamicBuffer>
  2757. void
  2758. write_close(DynamicBuffer& b, close_reason const& rc);
  2759. template<class DynamicBuffer>
  2760. void
  2761. write_ping(DynamicBuffer& b,
  2762. detail::opcode op, ping_data const& data);
  2763. //
  2764. // upgrade
  2765. //
  2766. template<class Decorator>
  2767. request_type
  2768. build_request(detail::sec_ws_key_type& key,
  2769. string_view host,
  2770. string_view target,
  2771. Decorator const& decorator);
  2772. void
  2773. build_request_pmd(request_type& req, std::true_type);
  2774. void
  2775. build_request_pmd(request_type&, std::false_type)
  2776. {
  2777. }
  2778. template<
  2779. class Body, class Allocator, class Decorator>
  2780. response_type
  2781. build_response(
  2782. http::request<Body,
  2783. http::basic_fields<Allocator>> const& req,
  2784. Decorator const& decorator,
  2785. error_code& ec);
  2786. template<class Body, class Allocator>
  2787. void
  2788. build_response_pmd(
  2789. response_type& res,
  2790. http::request<Body,
  2791. http::basic_fields<Allocator>> const& req,
  2792. std::true_type);
  2793. template<class Body, class Allocator>
  2794. void
  2795. build_response_pmd(
  2796. response_type&,
  2797. http::request<Body,
  2798. http::basic_fields<Allocator>> const&,
  2799. std::false_type)
  2800. {
  2801. }
  2802. void
  2803. on_response(
  2804. response_type const& res,
  2805. detail::sec_ws_key_type const& key,
  2806. error_code& ec);
  2807. void
  2808. on_response_pmd(
  2809. response_type const& res,
  2810. std::true_type);
  2811. void
  2812. on_response_pmd(
  2813. response_type const&,
  2814. std::false_type)
  2815. {
  2816. }
  2817. //
  2818. // accept / handshake
  2819. //
  2820. template<class Allocator>
  2821. void
  2822. do_pmd_config(
  2823. http::basic_fields<Allocator> const& h,
  2824. std::true_type)
  2825. {
  2826. pmd_read(this->pmd_config_, h);
  2827. }
  2828. template<class Allocator>
  2829. void
  2830. do_pmd_config(
  2831. http::basic_fields<Allocator> const&,
  2832. std::false_type)
  2833. {
  2834. }
  2835. template<class Decorator>
  2836. void
  2837. do_accept(
  2838. Decorator const& decorator,
  2839. error_code& ec);
  2840. template<
  2841. class Body, class Allocator,
  2842. class Decorator>
  2843. void
  2844. do_accept(
  2845. http::request<Body,
  2846. http::basic_fields<Allocator>> const& req,
  2847. Decorator const& decorator,
  2848. error_code& ec);
  2849. template<class RequestDecorator>
  2850. void
  2851. do_handshake(response_type* res_p,
  2852. string_view host, string_view target,
  2853. RequestDecorator const& decorator,
  2854. error_code& ec);
  2855. //
  2856. // fail
  2857. //
  2858. void
  2859. do_fail(
  2860. std::uint16_t code,
  2861. error_code ev,
  2862. error_code& ec);
  2863. };
  2864. /** Manually provide a one-time seed to initialize the PRNG
  2865. This function invokes the specified seed sequence to produce a seed
  2866. suitable for use with the pseudo-random number generator used to
  2867. create masks and perform WebSocket protocol handshakes.
  2868. If a seed is not manually provided, the implementation will
  2869. perform a one-time seed generation using `std::random_device`. This
  2870. function may be used when the application runs in an environment
  2871. where the random device is unreliable or does not provide sufficient
  2872. entropy.
  2873. @par Preconditions
  2874. This function may not be called after any websocket @ref stream objects
  2875. have been constructed.
  2876. @param ss A reference to a `std::seed_seq` which will be used to seed
  2877. the pseudo-random number generator. The seed sequence should have at
  2878. least 256 bits of entropy.
  2879. @see stream::secure_prng
  2880. */
  2881. inline
  2882. void
  2883. seed_prng(std::seed_seq& ss)
  2884. {
  2885. detail::stream_prng::seed(&ss);
  2886. }
  2887. } // websocket
  2888. } // beast
  2889. } // boost
  2890. #include <boost/beast/websocket/impl/accept.ipp>
  2891. #include <boost/beast/websocket/impl/close.ipp>
  2892. #include <boost/beast/websocket/impl/handshake.ipp>
  2893. #include <boost/beast/websocket/impl/ping.ipp>
  2894. #include <boost/beast/websocket/impl/read.ipp>
  2895. #include <boost/beast/websocket/impl/stream.ipp>
  2896. #include <boost/beast/websocket/impl/write.ipp>
  2897. #endif