websocket_2_handshaking.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //
  2. // Copyright (c) 2016-2019 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. #include <boost/beast/_experimental/unit_test/suite.hpp>
  10. #ifdef BOOST_MSVC
  11. #pragma warning(push)
  12. #pragma warning(disable: 4459) // declaration hides global declaration
  13. #endif
  14. #include <boost/beast.hpp>
  15. #include <boost/beast/ssl.hpp>
  16. #include <boost/asio.hpp>
  17. #include <boost/asio/ssl.hpp>
  18. namespace {
  19. #include "websocket_common.ipp"
  20. void
  21. snippets()
  22. {
  23. {
  24. //[code_websocket_2_1
  25. stream<tcp_stream> ws(ioc);
  26. net::ip::tcp::resolver resolver(ioc);
  27. get_lowest_layer(ws).connect(resolver.resolve("www.example.com", "ws"));
  28. // Do the websocket handshake in the client role, on the connected stream.
  29. // The implementation only uses the Host parameter to set the HTTP "Host" field,
  30. // it does not perform any DNS lookup. That must be done first, as shown above.
  31. ws.handshake(
  32. "www.example.com", // The Host field
  33. "/" // The request-target
  34. );
  35. //]
  36. }
  37. {
  38. stream<tcp_stream> ws(ioc);
  39. {
  40. //[code_websocket_2_2
  41. // This variable will receive the HTTP response from the server
  42. response_type res;
  43. // Perform the websocket handshake in the client role.
  44. // On success, `res` will hold the complete HTTP response received.
  45. ws.handshake(
  46. res, // Receives the HTTP response
  47. "www.example.com", // The Host field
  48. "/" // The request-target
  49. );
  50. //]
  51. }
  52. //--------------------------------------------------------------------------
  53. {
  54. //[code_websocket_2_3
  55. // Perform the websocket handshake in the server role.
  56. // The stream must already be connected to the peer.
  57. ws.accept();
  58. //]
  59. }
  60. {
  61. //[code_websocket_2_4
  62. // This buffer will hold the HTTP request as raw characters
  63. std::string s;
  64. // Read into our buffer until we reach the end of the HTTP request.
  65. // No parsing takes place here, we are just accumulating data.
  66. net::read_until(sock, net::dynamic_buffer(s), "\r\n\r\n");
  67. // Now accept the connection, using the buffered data.
  68. ws.accept(net::buffer(s));
  69. //]
  70. }
  71. }
  72. {
  73. //[code_websocket_2_5
  74. // This buffer is required for reading HTTP messages
  75. flat_buffer buffer;
  76. // Read the HTTP request ourselves
  77. http::request<http::string_body> req;
  78. http::read(sock, buffer, req);
  79. // See if its a WebSocket upgrade request
  80. if(websocket::is_upgrade(req))
  81. {
  82. // Construct the stream, transferring ownership of the socket
  83. stream<tcp_stream> ws(std::move(sock));
  84. // Clients SHOULD NOT begin sending WebSocket
  85. // frames until the server has provided a response.
  86. BOOST_ASSERT(buffer.size() == 0);
  87. // Accept the upgrade request
  88. ws.accept(req);
  89. }
  90. else
  91. {
  92. // Its not a WebSocket upgrade, so
  93. // handle it like a normal HTTP request.
  94. }
  95. //]
  96. }
  97. }
  98. struct websocket_2_test
  99. : public boost::beast::unit_test::suite
  100. {
  101. void
  102. run() override
  103. {
  104. BEAST_EXPECT(&snippets);
  105. }
  106. };
  107. BEAST_DEFINE_TESTSUITE(beast,doc,websocket_2);
  108. } // (anon)
  109. #ifdef BOOST_MSVC
  110. #pragma warning(pop)
  111. #endif