pmd_extension.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. #ifndef BOOST_BEAST_WEBSOCKET_DETAIL_PMD_EXTENSION_HPP
  10. #define BOOST_BEAST_WEBSOCKET_DETAIL_PMD_EXTENSION_HPP
  11. #include <boost/beast/core/error.hpp>
  12. #include <boost/beast/websocket/option.hpp>
  13. #include <boost/beast/http/rfc7230.hpp>
  14. #include <utility>
  15. #include <type_traits>
  16. namespace boost {
  17. namespace beast {
  18. namespace websocket {
  19. namespace detail {
  20. // permessage-deflate offer parameters
  21. //
  22. // "context takeover" means:
  23. // preserve sliding window across messages
  24. //
  25. struct pmd_offer
  26. {
  27. bool accept;
  28. // 0 = absent, or 8..15
  29. int server_max_window_bits;
  30. // -1 = present, 0 = absent, or 8..15
  31. int client_max_window_bits;
  32. // `true` if server_no_context_takeover offered
  33. bool server_no_context_takeover;
  34. // `true` if client_no_context_takeover offered
  35. bool client_no_context_takeover;
  36. };
  37. BOOST_BEAST_DECL
  38. int
  39. parse_bits(string_view s);
  40. BOOST_BEAST_DECL
  41. void
  42. pmd_read_impl(pmd_offer& offer, http::ext_list const& list);
  43. BOOST_BEAST_DECL
  44. static_string<512>
  45. pmd_write_impl(pmd_offer const& offer);
  46. BOOST_BEAST_DECL
  47. static_string<512>
  48. pmd_negotiate_impl(
  49. pmd_offer& config,
  50. pmd_offer const& offer,
  51. permessage_deflate const& o);
  52. // Parse permessage-deflate request fields
  53. //
  54. template<class Allocator>
  55. void
  56. pmd_read(pmd_offer& offer,
  57. http::basic_fields<Allocator> const& fields)
  58. {
  59. http::ext_list list{
  60. fields["Sec-WebSocket-Extensions"]};
  61. detail::pmd_read_impl(offer, list);
  62. }
  63. // Set permessage-deflate fields for a client offer
  64. //
  65. template<class Allocator>
  66. void
  67. pmd_write(http::basic_fields<Allocator>& fields,
  68. pmd_offer const& offer)
  69. {
  70. auto s = detail::pmd_write_impl(offer);
  71. fields.set(http::field::sec_websocket_extensions, s);
  72. }
  73. // Negotiate a permessage-deflate client offer
  74. //
  75. template<class Allocator>
  76. void
  77. pmd_negotiate(
  78. http::basic_fields<Allocator>& fields,
  79. pmd_offer& config,
  80. pmd_offer const& offer,
  81. permessage_deflate const& o)
  82. {
  83. if(! (offer.accept && o.server_enable))
  84. {
  85. config.accept = false;
  86. return;
  87. }
  88. config.accept = true;
  89. auto s = detail::pmd_negotiate_impl(config, offer, o);
  90. if(config.accept)
  91. fields.set(http::field::sec_websocket_extensions, s);
  92. }
  93. // Normalize the server's response
  94. //
  95. BOOST_BEAST_DECL
  96. void
  97. pmd_normalize(pmd_offer& offer);
  98. } // detail
  99. } // websocket
  100. } // beast
  101. } // boost
  102. #if BOOST_BEAST_HEADER_ONLY
  103. #include <boost/beast/websocket/detail/pmd_extension.ipp>
  104. #endif
  105. #endif