hybi13.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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_DETAIL_HYBI13_HPP
  10. #define BOOST_BEAST_WEBSOCKET_DETAIL_HYBI13_HPP
  11. #include <boost/beast/core/static_string.hpp>
  12. #include <boost/beast/core/string.hpp>
  13. #include <boost/beast/core/detail/base64.hpp>
  14. #include <boost/beast/core/detail/sha1.hpp>
  15. #include <boost/beast/websocket/detail/stream_base.hpp>
  16. #include <boost/assert.hpp>
  17. #include <array>
  18. #include <cstdint>
  19. #include <string>
  20. #include <type_traits>
  21. namespace boost {
  22. namespace beast {
  23. namespace websocket {
  24. namespace detail {
  25. using sec_ws_key_type = static_string<
  26. beast::detail::base64::encoded_size(16)>;
  27. using sec_ws_accept_type = static_string<
  28. beast::detail::base64::encoded_size(20)>;
  29. inline
  30. void
  31. make_sec_ws_key(sec_ws_key_type& key)
  32. {
  33. auto p = stream_prng::prng();
  34. char a[16];
  35. for(int i = 0; i < 16; i += 4)
  36. {
  37. auto const v = p->secure();
  38. a[i ] = v & 0xff;
  39. a[i+1] = (v >> 8) & 0xff;
  40. a[i+2] = (v >> 16) & 0xff;
  41. a[i+3] = (v >> 24) & 0xff;
  42. }
  43. key.resize(key.max_size());
  44. key.resize(beast::detail::base64::encode(
  45. key.data(), &a[0], 16));
  46. }
  47. template<class = void>
  48. void
  49. make_sec_ws_accept(sec_ws_accept_type& accept,
  50. string_view key)
  51. {
  52. BOOST_ASSERT(key.size() <= sec_ws_key_type::max_size_n);
  53. static_string<sec_ws_key_type::max_size_n + 36> m(key);
  54. m.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
  55. beast::detail::sha1_context ctx;
  56. beast::detail::init(ctx);
  57. beast::detail::update(ctx, m.data(), m.size());
  58. char digest[beast::detail::sha1_context::digest_size];
  59. beast::detail::finish(ctx, &digest[0]);
  60. accept.resize(accept.max_size());
  61. accept.resize(beast::detail::base64::encode(
  62. accept.data(), &digest[0], sizeof(digest)));
  63. }
  64. } // detail
  65. } // websocket
  66. } // beast
  67. } // boost
  68. #endif