Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09: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,
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 set_option(timeout const& opt)
0182 {
0183     impl_->set_option(opt);
0184 }
0185 
0186 //
0187 
0188 template<class NextLayer, bool deflateSupported>
0189 void
0190 stream<NextLayer, deflateSupported>::
0191 set_option(permessage_deflate const& o)
0192 {
0193     impl_->set_option_pmd(o);
0194 }
0195 
0196 template<class NextLayer, bool deflateSupported>
0197 void
0198 stream<NextLayer, deflateSupported>::
0199 get_option(permessage_deflate& o)
0200 {
0201     impl_->get_option_pmd(o);
0202 }
0203 
0204 template<class NextLayer, bool deflateSupported>
0205 void
0206 stream<NextLayer, deflateSupported>::
0207 auto_fragment(bool value)
0208 {
0209     impl_->wr_frag_opt = value;
0210 }
0211 
0212 template<class NextLayer, bool deflateSupported>
0213 bool
0214 stream<NextLayer, deflateSupported>::
0215 auto_fragment() const
0216 {
0217     return impl_->wr_frag_opt;
0218 }
0219 
0220 template<class NextLayer, bool deflateSupported>
0221 void
0222 stream<NextLayer, deflateSupported>::
0223 binary(bool value)
0224 {
0225     impl_->wr_opcode = value ?
0226         detail::opcode::binary :
0227         detail::opcode::text;
0228 }
0229 
0230 template<class NextLayer, bool deflateSupported>
0231 bool
0232 stream<NextLayer, deflateSupported>::
0233 binary() const
0234 {
0235     return impl_->wr_opcode == detail::opcode::binary;
0236 }
0237 
0238 template<class NextLayer, bool deflateSupported>
0239 void
0240 stream<NextLayer, deflateSupported>::
0241 control_callback(std::function<
0242     void(frame_type, string_view)> cb)
0243 {
0244     impl_->ctrl_cb = std::move(cb);
0245 }
0246 
0247 template<class NextLayer, bool deflateSupported>
0248 void
0249 stream<NextLayer, deflateSupported>::
0250 control_callback()
0251 {
0252     impl_->ctrl_cb = {};
0253 }
0254 
0255 template<class NextLayer, bool deflateSupported>
0256 void
0257 stream<NextLayer, deflateSupported>::
0258 read_message_max(std::size_t amount)
0259 {
0260     impl_->rd_msg_max = amount;
0261 }
0262 
0263 template<class NextLayer, bool deflateSupported>
0264 std::size_t
0265 stream<NextLayer, deflateSupported>::
0266 read_message_max() const
0267 {
0268     return impl_->rd_msg_max;
0269 }
0270 
0271 template<class NextLayer, bool deflateSupported>
0272 void
0273 stream<NextLayer, deflateSupported>::
0274 secure_prng(bool value)
0275 {
0276     this->impl_->secure_prng_ = value;
0277 }
0278 
0279 template<class NextLayer, bool deflateSupported>
0280 void
0281 stream<NextLayer, deflateSupported>::
0282 write_buffer_bytes(std::size_t amount)
0283 {
0284     if(amount < 8)
0285         BOOST_THROW_EXCEPTION(std::invalid_argument{
0286             "write buffer size underflow"});
0287     impl_->wr_buf_opt = amount;
0288 }
0289 
0290 template<class NextLayer, bool deflateSupported>
0291 std::size_t
0292 stream<NextLayer, deflateSupported>::
0293 write_buffer_bytes() const
0294 {
0295     return impl_->wr_buf_opt;
0296 }
0297 
0298 template<class NextLayer, bool deflateSupported>
0299 void
0300 stream<NextLayer, deflateSupported>::
0301 text(bool value)
0302 {
0303     impl_->wr_opcode = value ?
0304         detail::opcode::text :
0305         detail::opcode::binary;
0306 }
0307 
0308 template<class NextLayer, bool deflateSupported>
0309 bool
0310 stream<NextLayer, deflateSupported>::
0311 text() const
0312 {
0313     return impl_->wr_opcode == detail::opcode::text;
0314 }
0315 
0316 template<class NextLayer, bool deflateSupported>
0317 void
0318 stream<NextLayer, deflateSupported>::
0319 compress(bool value)
0320 {
0321     impl_->wr_compress_opt = value;
0322 }
0323 
0324 template<class NextLayer, bool deflateSupported>
0325 bool
0326 stream<NextLayer, deflateSupported>::
0327 compress() const
0328 {
0329     return impl_->wr_compress_opt;
0330 }
0331 
0332 //------------------------------------------------------------------------------
0333 
0334 // _Fail the WebSocket Connection_
0335 template<class NextLayer, bool deflateSupported>
0336 void
0337 stream<NextLayer, deflateSupported>::
0338 do_fail(
0339     std::uint16_t code,         // if set, send a close frame first
0340     error_code ev,              // error code to use upon success
0341     error_code& ec)             // set to the error, else set to ev
0342 {
0343     BOOST_ASSERT(ev);
0344     impl_->change_status(status::closing);
0345     if(code != close_code::none && ! impl_->wr_close)
0346     {
0347         impl_->wr_close = true;
0348         detail::frame_buffer fb;
0349         impl_->template write_close<
0350             flat_static_buffer_base>(fb, code);
0351         net::write(impl_->stream(), fb.data(), ec);
0352         if(impl_->check_stop_now(ec))
0353             return;
0354     }
0355     using beast::websocket::teardown;
0356     teardown(impl_->role, impl_->stream(), ec);
0357     if(ec == net::error::eof)
0358     {
0359         // Rationale:
0360         // http://stackoverflow.com/questions/25587403/boost-asio-ssl-async-shutdown-always-finishes-with-an-error
0361         ec = {};
0362     }
0363     if(! ec)
0364     {
0365         BOOST_BEAST_ASSIGN_EC(ec, ev);
0366     }
0367     if(ec && ec != error::closed)
0368         impl_->change_status(status::failed);
0369     else
0370         impl_->change_status(status::closed);
0371     impl_->close();
0372 }
0373 
0374 } // websocket
0375 } // beast
0376 } // boost
0377 
0378 #endif