File indexing completed on 2025-01-18 09:29:34
0001
0002
0003
0004
0005
0006
0007
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
0155
0156
0157
0158
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
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
0335 template<class NextLayer, bool deflateSupported>
0336 void
0337 stream<NextLayer, deflateSupported>::
0338 do_fail(
0339 std::uint16_t code,
0340 error_code ev,
0341 error_code& ec)
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
0360
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 }
0375 }
0376 }
0377
0378 #endif