02_handshaking.qbk 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. [/
  2. Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. Official repository: https://github.com/boostorg/beast
  6. ]
  7. [section Handshaking]
  8. [/-----------------------------------------------------------------------------]
  9. [heading Client Role]
  10. A WebSocket session begins when a client sends the HTTP/1.1
  11. [@https://tools.ietf.org/html/rfc7230#section-6.7 Upgrade]
  12. request for
  13. [@https://tools.ietf.org/html/rfc6455#section-1.3 WebSocket]
  14. on an established connection, and the server sends an appropriate response
  15. indicating that the request was accepted and that the connection has been
  16. upgraded. The Upgrade request must include the
  17. [@https://tools.ietf.org/html/rfc7230#section-5.4 Host]
  18. field, and the
  19. [@https://tools.ietf.org/html/rfc7230#section-5.3 target]
  20. of the resource to request.
  21. A typical HTTP Upgrade request created and sent by the implementation
  22. will look like this:
  23. [table WebSocket HTTP Upgrade Request
  24. [[Wire Format][Description]]
  25. [[
  26. ```
  27. GET / HTTP/1.1
  28. Host: www.example.com
  29. Upgrade: websocket
  30. Connection: upgrade
  31. Sec-WebSocket-Key: 2pGeTR0DsE4dfZs2pH+8MA==
  32. Sec-WebSocket-Version: 13
  33. User-Agent: Boost.Beast/216
  34. ```
  35. ][
  36. The host and target parameters become part of the Host field
  37. and request-target in the resulting HTTP request. The key is
  38. generated by the implementation. Callers who wish to add,
  39. modify, or inspect fields may set the ['decorator] option
  40. on the stream (described later).
  41. ]]]
  42. The
  43. [link beast.ref.boost__beast__websocket__stream `websocket::stream`]
  44. member functions
  45. [link beast.ref.boost__beast__websocket__stream.handshake `handshake`] and
  46. [link beast.ref.boost__beast__websocket__stream.async_handshake `async_handshake`]
  47. are used to send the request with the required host and target strings. This
  48. code connects to the IP address returned from a hostname lookup, then performs
  49. the WebSocket handshake in the client role.
  50. [code_websocket_2_1]
  51. When a client receives an HTTP Upgrade response from the server indicating
  52. a successful upgrade, the caller may wish to perform additional validation
  53. on the received HTTP response message. For example, to check that the
  54. response to a basic authentication challenge is valid. To achieve this,
  55. overloads of the handshake member function allow the caller to store the
  56. received HTTP message in an output reference argument of type
  57. [link beast.ref.boost__beast__websocket__response_type `response_type`]
  58. as follows:
  59. [code_websocket_2_2]
  60. [/-----------------------------------------------------------------------------]
  61. [heading Server Role]
  62. For servers accepting incoming connections, the
  63. [link beast.ref.boost__beast__websocket__stream `websocket::stream`]
  64. can read the incoming upgrade request and automatically reply. If the handshake
  65. meets the requirements, the stream sends back the upgrade response with a
  66. [@https://tools.ietf.org/html/rfc6455#section-4.2.2 ['101 Switching Protocols]]
  67. status code. If the handshake does not meet the requirements, or falls outside
  68. the range of allowed parameters specified by stream options set previously by
  69. the caller, the stream sends back an HTTP response with a status code indicating
  70. an error. Depending on the keep alive setting, the connection may remain open
  71. for a subsequent handshake attempt. A typical HTTP Upgrade response created and
  72. sent by the implementation upon receiving an upgrade request handshake will
  73. look like this:
  74. [table WebSocket Upgrade HTTP Response
  75. [[Wire Format][Description]]
  76. [[
  77. ```
  78. HTTP/1.1 101 Switching Protocols
  79. Upgrade: websocket
  80. Connection: upgrade
  81. Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
  82. Server: Boost.Beast
  83. ```
  84. ][
  85. The
  86. [@https://tools.ietf.org/html/rfc6455#section-11.3.3 ['Sec-WebSocket-Accept]]
  87. field value is generated from the request in a fashion specified by
  88. the WebSocket protocol.
  89. ]]]
  90. The
  91. [link beast.ref.boost__beast__websocket__stream `stream`]
  92. member functions
  93. [link beast.ref.boost__beast__websocket__stream.accept `accept`] and
  94. [link beast.ref.boost__beast__websocket__stream.async_accept `async_accept`]
  95. are used to read the WebSocket HTTP Upgrade request handshake from a stream
  96. already connected to an incoming peer, and then send the WebSocket HTTP
  97. Upgrade response, as shown:
  98. [code_websocket_2_3]
  99. [heading Handshake Buffering]
  100. It is possible for servers to read data from the stream and decide later
  101. that the buffered bytes should be interpreted as a WebSocket upgrade
  102. request. To address this usage, overloads of
  103. [link beast.ref.boost__beast__websocket__stream.accept `accept`] and
  104. [link beast.ref.boost__beast__websocket__stream.async_accept `async_accept`]
  105. which accept an additional buffer sequence parameter are provided.
  106. In this example, the server reads the initial HTTP request header into a
  107. dynamic buffer, then later uses the buffered data to attempt a websocket
  108. upgrade.
  109. [code_websocket_2_4]
  110. [heading Inspecting HTTP Requests]
  111. When implementing an HTTP server that also supports WebSocket, the
  112. server usually reads the HTTP request from the client. To detect when
  113. the incoming HTTP request is a WebSocket Upgrade request, the function
  114. [link beast.ref.boost__beast__websocket__is_upgrade `is_upgrade`] may be used.
  115. Once the caller determines that the HTTP request is a WebSocket Upgrade,
  116. additional overloads of
  117. [link beast.ref.boost__beast__websocket__stream.accept `accept`] and
  118. [link beast.ref.boost__beast__websocket__stream.async_accept `async_accept`]
  119. are provided which receive the entire HTTP request header as an object
  120. to perform the handshake. By reading the request manually, the program
  121. can handle normal HTTP requests as well as upgrades. The program may
  122. also enforce policies based on the HTTP fields, such as Basic
  123. Authentication. In this example, the request is first read in
  124. using the HTTP algorithms, and then passed to a newly constructed
  125. stream:
  126. [code_websocket_2_5]
  127. [/-----------------------------------------------------------------------------]
  128. [endsect]