Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 08:29:34

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_WEBSOCKET_IMPL_STREAM_HPP
0011 #define BOOST_BEAST_WEBSOCKET_IMPL_STREAM_HPP
0012 
0013 #include <boost/beast/core/buffer_traits.hpp>
0014 #include <boost/beast/websocket/rfc6455.hpp>
0015 #include <boost/beast/websocket/teardown.hpp>
0016 #include <boost/beast/websocket/detail/hybi13.hpp>
0017 #include <boost/beast/websocket/detail/mask.hpp>
0018 #include <boost/beast/websocket/impl/stream_impl.hpp>
0019 #include <boost/beast/version.hpp>
0020 #include <boost/beast/http/read.hpp>
0021 #include <boost/beast/http/write.hpp>
0022 #include <boost/beast/http/rfc7230.hpp>
0023 #include <boost/beast/core/buffers_cat.hpp>
0024 #include <boost/beast/core/buffers_prefix.hpp>
0025 #include <boost/beast/core/buffers_suffix.hpp>
0026 #include <boost/beast/core/flat_static_buffer.hpp>
0027 #include <boost/beast/core/detail/clamp.hpp>
0028 #include <boost/asio/steady_timer.hpp>
0029 #include <boost/assert.hpp>
0030 #include <boost/make_shared.hpp>
0031 #include <boost/throw_exception.hpp>
0032 #include <algorithm>
0033 #include <chrono>
0034 #include <memory>
0035 #include <stdexcept>
0036 #include <utility>
0037 
0038 namespace boost {
0039 namespace beast {
0040 namespace websocket {
0041 
0042 template<class NextLayer, bool deflateSupported>
0043 stream<NextLayer, deflateSupported>::
0044 ~stream()
0045 {
0046     if(impl_)
0047         impl_->remove();
0048 }
0049 
0050 template<class NextLayer, bool deflateSupported>
0051 template<class... Args>
0052 stream<NextLayer, deflateSupported>::
0053 stream(Args&&... args)
0054     : impl_(boost::make_shared<impl_type>(
0055         std::forward<Args>(args)...))
0056 {
0057     BOOST_ASSERT(impl_->rd_buf.max_size() >=
0058         max_control_frame_size);
0059 }
0060 
0061 template<class NextLayer, bool deflateSupported>
0062 template<class Other>
0063 stream<NextLayer, deflateSupported>::
0064 stream(stream<Other> && other)
0065     : impl_(boost::make_shared<impl_type>(std::move(other.next_layer())))
0066 {
0067 }
0068 
0069 
0070 template<class NextLayer, bool deflateSupported>
0071 auto
0072 stream<NextLayer, deflateSupported>::
0073 get_executor() noexcept ->
0074     executor_type
0075 {
0076     return impl_->stream().get_executor();
0077 }
0078 
0079 template<class NextLayer, bool deflateSupported>
0080 auto
0081 stream<NextLayer, deflateSupported>::
0082 next_layer() noexcept ->
0083     next_layer_type&
0084 {
0085     return impl_->stream();
0086 }
0087 
0088 template<class NextLayer, bool deflateSupported>
0089 auto
0090 stream<NextLayer, deflateSupported>::
0091 next_layer() const noexcept ->
0092     next_layer_type const&
0093 {
0094     return impl_->stream();
0095 }
0096 
0097 template<class NextLayer, bool deflateSupported>
0098 bool
0099 stream<NextLayer, deflateSupported>::
0100 is_open() const noexcept
0101 {
0102     return impl_->status_ == status::open;
0103 }
0104 
0105 template<class NextLayer, bool deflateSupported>
0106 bool
0107 stream<NextLayer, deflateSupported>::
0108 got_binary() const noexcept
0109 {
0110     return impl_->rd_op == detail::opcode::binary;
0111 }
0112 
0113 template<class NextLayer, bool deflateSupported>
0114 bool
0115 stream<NextLayer, deflateSupported>::
0116 is_message_done() const noexcept
0117 {
0118     return impl_->rd_done;
0119 }
0120 
0121 template<class NextLayer, bool deflateSupported>
0122 close_reason const&
0123 stream<NextLayer, deflateSupported>::
0124 reason() const noexcept
0125 {
0126     return impl_->cr;
0127 }
0128 
0129 template<class NextLayer, bool deflateSupported>
0130 std::size_t
0131 stream<NextLayer, deflateSupported>::
0132 read_size_hint(
0133     std::size_t initial_size) const
0134 {
0135     return impl_->read_size_hint_pmd(
0136         initial_size, impl_->rd_done, impl_->rd_msg_max,
0137         impl_->rd_remain, impl_->rd_fh);
0138 }
0139 
0140 template<class NextLayer, bool deflateSupported>
0141 template<class DynamicBuffer, class>
0142 std::size_t
0143 stream<NextLayer, deflateSupported>::
0144 read_size_hint(DynamicBuffer& buffer) const
0145 {
0146     static_assert(
0147         net::is_dynamic_buffer<DynamicBuffer>::value,
0148         "DynamicBuffer type requirements not met");
0149     return impl_->read_size_hint_db(buffer);
0150 }
0151 
0152 //------------------------------------------------------------------------------
0153 //
0154 // Settings
0155 //
0156 //------------------------------------------------------------------------------
0157 
0158 // decorator
0159 
0160 template<class NextLayer, bool deflateSupported>
0161 void
0162 stream<NextLayer, deflateSupported>::
0163 set_option(decorator opt)
0164 {
0165     impl_->decorator_opt = std::move(opt.d_);
0166 }
0167 
0168 // timeout
0169 
0170 template<class NextLayer, bool deflateSupported>
0171 void
0172 stream<NextLayer, deflateSupported>::
0173 get_option(timeout& opt)
0174 {
0175     opt = impl_->timeout_opt;
0176 }
0177 
0178 template <class NextLayer, bool deflateSupported>
0179 void
0180 stream<NextLayer, deflateSupported>::
0181 get_status(permessage_deflate_status &status) const noexcept
0182 {
0183     detail::pmd_offer pmd;
0184     impl_->get_config_pmd(pmd);
0185     status.active               = pmd.accept;
0186     status.client_window_bits   = pmd.client_max_window_bits;
0187     status.server_window_bits   = pmd.server_max_window_bits;
0188 }
0189 
0190 template<class NextLayer, bool deflateSupported>
0191 void
0192 stream<NextLayer, deflateSupported>::
0193 set_option(timeout const& opt)
0194 {
0195     impl_->set_option(opt);
0196 }
0197 
0198 //
0199 
0200 template<class NextLayer, bool deflateSupported>
0201 void
0202 stream<NextLayer, deflateSupported>::
0203 set_option(permessage_deflate const& o)
0204 {
0205     impl_->set_option_pmd(o);
0206 }
0207 
0208 template<class NextLayer, bool deflateSupported>
0209 void
0210 stream<NextLayer, deflateSupported>::
0211 get_option(permessage_deflate& o)
0212 {
0213     impl_->get_option_pmd(o);
0214 }
0215 
0216 template<class NextLayer, bool deflateSupported>
0217 void
0218 stream<NextLayer, deflateSupported>::
0219 auto_fragment(bool value)
0220 {
0221     impl_->wr_frag_opt = value;
0222 }
0223 
0224 template<class NextLayer, bool deflateSupported>
0225 bool
0226 stream<NextLayer, deflateSupported>::
0227 auto_fragment() const
0228 {
0229     return impl_->wr_frag_opt;
0230 }
0231 
0232 template<class NextLayer, bool deflateSupported>
0233 void
0234 stream<NextLayer, deflateSupported>::
0235 binary(bool value)
0236 {
0237     impl_->wr_opcode = value ?
0238         detail::opcode::binary :
0239         detail::opcode::text;
0240 }
0241 
0242 template<class NextLayer, bool deflateSupported>
0243 bool
0244 stream<NextLayer, deflateSupported>::
0245 binary() const
0246 {
0247     return impl_->wr_opcode == detail::opcode::binary;
0248 }
0249 
0250 template<class NextLayer, bool deflateSupported>
0251 void
0252 stream<NextLayer, deflateSupported>::
0253 control_callback(std::function<
0254     void(frame_type, string_view)> cb)
0255 {
0256     impl_->ctrl_cb = std::move(cb);
0257 }
0258 
0259 template<class NextLayer, bool deflateSupported>
0260 void
0261 stream<NextLayer, deflateSupported>::
0262 control_callback()
0263 {
0264     impl_->ctrl_cb = {};
0265 }
0266 
0267 template<class NextLayer, bool deflateSupported>
0268 void
0269 stream<NextLayer, deflateSupported>::
0270 read_message_max(std::size_t amount)
0271 {
0272     impl_->rd_msg_max = amount;
0273 }
0274 
0275 template<class NextLayer, bool deflateSupported>
0276 std::size_t
0277 stream<NextLayer, deflateSupported>::
0278 read_message_max() const
0279 {
0280     return impl_->rd_msg_max;
0281 }
0282 
0283 template<class NextLayer, bool deflateSupported>
0284 void
0285 stream<NextLayer, deflateSupported>::
0286 secure_prng(bool value)
0287 {
0288     this->impl_->secure_prng_ = value;
0289 }
0290 
0291 template<class NextLayer, bool deflateSupported>
0292 void
0293 stream<NextLayer, deflateSupported>::
0294 write_buffer_bytes(std::size_t amount)
0295 {
0296     if(amount < 8)
0297         BOOST_THROW_EXCEPTION(std::invalid_argument{
0298             "write buffer size underflow"});
0299     impl_->wr_buf_opt = amount;
0300 }
0301 
0302 template<class NextLayer, bool deflateSupported>
0303 std::size_t
0304 stream<NextLayer, deflateSupported>::
0305 write_buffer_bytes() const
0306 {
0307     return impl_->wr_buf_opt;
0308 }
0309 
0310 template<class NextLayer, bool deflateSupported>
0311 void
0312 stream<NextLayer, deflateSupported>::
0313 text(bool value)
0314 {
0315     impl_->wr_opcode = value ?
0316         detail::opcode::text :
0317         detail::opcode::binary;
0318 }
0319 
0320 template<class NextLayer, bool deflateSupported>
0321 bool
0322 stream<NextLayer, deflateSupported>::
0323 text() const
0324 {
0325     return impl_->wr_opcode == detail::opcode::text;
0326 }
0327 
0328 template<class NextLayer, bool deflateSupported>
0329 void
0330 stream<NextLayer, deflateSupported>::
0331 compress(bool value)
0332 {
0333     impl_->wr_compress_opt = value;
0334 }
0335 
0336 template<class NextLayer, bool deflateSupported>
0337 bool
0338 stream<NextLayer, deflateSupported>::
0339 compress() const
0340 {
0341     return impl_->wr_compress_opt;
0342 }
0343 
0344 //------------------------------------------------------------------------------
0345 
0346 // _Fail the WebSocket Connection_
0347 template<class NextLayer, bool deflateSupported>
0348 void
0349 stream<NextLayer, deflateSupported>::
0350 do_fail(
0351     std::uint16_t code,         // if set, send a close frame first
0352     error_code ev,              // error code to use upon success
0353     error_code& ec)             // set to the error, else set to ev
0354 {
0355     BOOST_ASSERT(ev);
0356     impl_->change_status(status::closing);
0357     if(code != close_code::none && ! impl_->wr_close)
0358     {
0359         impl_->wr_close = true;
0360         detail::frame_buffer fb;
0361         impl_->template write_close<
0362             flat_static_buffer_base>(fb, code);
0363         net::write(impl_->stream(), fb.data(), ec);
0364         if(impl_->check_stop_now(ec))
0365             return;
0366     }
0367     using beast::websocket::teardown;
0368     teardown(impl_->role, impl_->stream(), ec);
0369     if(ec == net::error::eof)
0370     {
0371         // Rationale:
0372         // http://stackoverflow.com/questions/25587403/boost-asio-ssl-async-shutdown-always-finishes-with-an-error
0373         ec = {};
0374     }
0375     if(! ec)
0376     {
0377         BOOST_BEAST_ASSIGN_EC(ec, ev);
0378     }
0379     if(ec && ec != error::closed)
0380         impl_->change_status(status::failed);
0381     else
0382         impl_->change_status(status::closed);
0383     impl_->close();
0384 }
0385 
0386 } // websocket
0387 } // beast
0388 } // boost
0389 
0390 #endif