]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/beast/websocket/impl/accept.ipp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / beast / websocket / impl / accept.ipp
CommitLineData
b32b8144
FG
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
10#ifndef BOOST_BEAST_WEBSOCKET_IMPL_ACCEPT_IPP
11#define BOOST_BEAST_WEBSOCKET_IMPL_ACCEPT_IPP
12
13#include <boost/beast/websocket/detail/type_traits.hpp>
14#include <boost/beast/http/empty_body.hpp>
15#include <boost/beast/http/parser.hpp>
16#include <boost/beast/http/read.hpp>
17#include <boost/beast/http/string_body.hpp>
18#include <boost/beast/http/write.hpp>
19#include <boost/beast/core/buffers_prefix.hpp>
20#include <boost/beast/core/handler_ptr.hpp>
21#include <boost/beast/core/detail/type_traits.hpp>
22#include <boost/asio/coroutine.hpp>
23#include <boost/asio/associated_allocator.hpp>
24#include <boost/asio/associated_executor.hpp>
25#include <boost/asio/handler_continuation_hook.hpp>
11fdf7f2 26#include <boost/asio/handler_invoke_hook.hpp>
b32b8144
FG
27#include <boost/asio/post.hpp>
28#include <boost/assert.hpp>
29#include <boost/throw_exception.hpp>
30#include <memory>
31#include <type_traits>
32
33namespace boost {
34namespace beast {
35namespace websocket {
36
37// Respond to an upgrade HTTP request
11fdf7f2 38template<class NextLayer, bool deflateSupported>
b32b8144 39template<class Handler>
11fdf7f2 40class stream<NextLayer, deflateSupported>::response_op
b32b8144
FG
41 : public boost::asio::coroutine
42{
43 struct data
44 {
11fdf7f2
TL
45 stream<NextLayer, deflateSupported>& ws;
46 error_code result;
b32b8144
FG
47 response_type res;
48
49 template<class Body, class Allocator, class Decorator>
11fdf7f2
TL
50 data(
51 Handler const&,
52 stream<NextLayer, deflateSupported>& ws_,
53 http::request<Body,
54 http::basic_fields<Allocator>> const& req,
55 Decorator const& decorator)
b32b8144 56 : ws(ws_)
11fdf7f2 57 , res(ws_.build_response(req, decorator, result))
b32b8144
FG
58 {
59 }
60 };
61
62 handler_ptr<data, Handler> d_;
63
64public:
65 response_op(response_op&&) = default;
11fdf7f2 66 response_op(response_op const&) = delete;
b32b8144
FG
67
68 template<class DeducedHandler, class... Args>
69 response_op(DeducedHandler&& h,
11fdf7f2 70 stream<NextLayer, deflateSupported>& ws, Args&&... args)
b32b8144
FG
71 : d_(std::forward<DeducedHandler>(h),
72 ws, std::forward<Args>(args)...)
73 {
74 }
75
76 using allocator_type =
77 boost::asio::associated_allocator_t<Handler>;
78
79 allocator_type
80 get_allocator() const noexcept
81 {
11fdf7f2 82 return (boost::asio::get_associated_allocator)(d_.handler());
b32b8144
FG
83 }
84
85 using executor_type = boost::asio::associated_executor_t<
11fdf7f2
TL
86 Handler, decltype(std::declval<
87 stream<NextLayer, deflateSupported>&>().get_executor())>;
b32b8144
FG
88
89 executor_type
90 get_executor() const noexcept
91 {
11fdf7f2 92 return (boost::asio::get_associated_executor)(
b32b8144
FG
93 d_.handler(), d_->ws.get_executor());
94 }
95
96 void operator()(
97 error_code ec = {},
98 std::size_t bytes_transferred = 0);
99
100 friend
101 bool asio_handler_is_continuation(response_op* op)
102 {
103 using boost::asio::asio_handler_is_continuation;
104 return asio_handler_is_continuation(
105 std::addressof(op->d_.handler()));
106 }
11fdf7f2
TL
107
108 template<class Function>
109 friend
110 void asio_handler_invoke(Function&& f, response_op* op)
111 {
112 using boost::asio::asio_handler_invoke;
113 asio_handler_invoke(f, std::addressof(op->d_.handler()));
114 }
b32b8144
FG
115};
116
11fdf7f2 117template<class NextLayer, bool deflateSupported>
b32b8144
FG
118template<class Handler>
119void
11fdf7f2 120stream<NextLayer, deflateSupported>::
b32b8144
FG
121response_op<Handler>::
122operator()(
123 error_code ec,
124 std::size_t)
125{
126 auto& d = *d_;
127 BOOST_ASIO_CORO_REENTER(*this)
128 {
129 // Send response
130 BOOST_ASIO_CORO_YIELD
131 http::async_write(d.ws.next_layer(),
132 d.res, std::move(*this));
11fdf7f2
TL
133 if(! ec)
134 ec = d.result;
b32b8144
FG
135 if(! ec)
136 {
11fdf7f2 137 d.ws.do_pmd_config(d.res, is_deflate_supported{});
b32b8144
FG
138 d.ws.open(role_type::server);
139 }
140 d_.invoke(ec);
141 }
142}
143
144//------------------------------------------------------------------------------
145
146// read and respond to an upgrade request
147//
11fdf7f2 148template<class NextLayer, bool deflateSupported>
b32b8144 149template<class Decorator, class Handler>
11fdf7f2 150class stream<NextLayer, deflateSupported>::accept_op
b32b8144
FG
151 : public boost::asio::coroutine
152{
153 struct data
154 {
11fdf7f2 155 stream<NextLayer, deflateSupported>& ws;
b32b8144
FG
156 Decorator decorator;
157 http::request_parser<http::empty_body> p;
11fdf7f2
TL
158 data(
159 Handler const&,
160 stream<NextLayer, deflateSupported>& ws_,
161 Decorator const& decorator_)
b32b8144
FG
162 : ws(ws_)
163 , decorator(decorator_)
164 {
165 }
166 };
167
168 handler_ptr<data, Handler> d_;
169
170public:
171 accept_op(accept_op&&) = default;
11fdf7f2 172 accept_op(accept_op const&) = delete;
b32b8144
FG
173
174 template<class DeducedHandler, class... Args>
175 accept_op(DeducedHandler&& h,
11fdf7f2 176 stream<NextLayer, deflateSupported>& ws, Args&&... args)
b32b8144
FG
177 : d_(std::forward<DeducedHandler>(h),
178 ws, std::forward<Args>(args)...)
179 {
180 }
181
182 using allocator_type =
183 boost::asio::associated_allocator_t<Handler>;
184
185 allocator_type
186 get_allocator() const noexcept
187 {
11fdf7f2 188 return (boost::asio::get_associated_allocator)(d_.handler());
b32b8144
FG
189 }
190
191 using executor_type = boost::asio::associated_executor_t<
11fdf7f2 192 Handler, decltype(std::declval<stream<NextLayer, deflateSupported>&>().get_executor())>;
b32b8144
FG
193
194 executor_type
195 get_executor() const noexcept
196 {
11fdf7f2 197 return (boost::asio::get_associated_executor)(
b32b8144
FG
198 d_.handler(), d_->ws.get_executor());
199 }
200
201 template<class Buffers>
202 void run(Buffers const& buffers);
203
204 void operator()(
205 error_code ec = {},
206 std::size_t bytes_used = 0);
207
208 friend
209 bool asio_handler_is_continuation(accept_op* op)
210 {
211 using boost::asio::asio_handler_is_continuation;
212 return asio_handler_is_continuation(
213 std::addressof(op->d_.handler()));
214 }
11fdf7f2
TL
215
216 template<class Function>
217 friend
218 void asio_handler_invoke(Function&& f, accept_op* op)
219 {
220 using boost::asio::asio_handler_invoke;
221 asio_handler_invoke(f, std::addressof(op->d_.handler()));
222 }
b32b8144
FG
223};
224
11fdf7f2 225template<class NextLayer, bool deflateSupported>
b32b8144
FG
226template<class Decorator, class Handler>
227template<class Buffers>
228void
11fdf7f2 229stream<NextLayer, deflateSupported>::
b32b8144
FG
230accept_op<Decorator, Handler>::
231run(Buffers const& buffers)
232{
233 using boost::asio::buffer_copy;
234 using boost::asio::buffer_size;
235 auto& d = *d_;
236 error_code ec;
237 boost::optional<typename
238 static_buffer_base::mutable_buffers_type> mb;
239 auto const len = buffer_size(buffers);
240 try
241 {
242 mb.emplace(d.ws.rd_buf_.prepare(len));
243 }
244 catch(std::length_error const&)
245 {
246 ec = error::buffer_overflow;
247 return (*this)(ec);
248 }
249 d.ws.rd_buf_.commit(
250 buffer_copy(*mb, buffers));
251 (*this)(ec);
252}
253
11fdf7f2 254template<class NextLayer, bool deflateSupported>
b32b8144
FG
255template<class Decorator, class Handler>
256void
11fdf7f2 257stream<NextLayer, deflateSupported>::
b32b8144
FG
258accept_op<Decorator, Handler>::
259operator()(error_code ec, std::size_t)
260{
261 auto& d = *d_;
262 BOOST_ASIO_CORO_REENTER(*this)
263 {
264 if(ec)
265 {
266 BOOST_ASIO_CORO_YIELD
267 boost::asio::post(
268 d.ws.get_executor(),
269 bind_handler(std::move(*this), ec));
270 }
271 else
272 {
273 BOOST_ASIO_CORO_YIELD
274 http::async_read(
275 d.ws.next_layer(), d.ws.rd_buf_,
276 d.p, std::move(*this));
277 if(ec == http::error::end_of_stream)
278 ec = error::closed;
279 if(! ec)
280 {
281 // Arguments from our state must be
282 // moved to the stack before releasing
283 // the handler.
284 auto& ws = d.ws;
285 auto const req = d.p.release();
286 auto const decorator = d.decorator;
287 #if 1
288 return response_op<Handler>{
289 d_.release_handler(),
290 ws, req, decorator}(ec);
291 #else
292 // VFALCO This *should* work but breaks
293 // coroutine invariants in the unit test.
294 // Also it calls reset() when it shouldn't.
295 return ws.async_accept_ex(
296 req, decorator, d_.release_handler());
297 #endif
298 }
299 }
300 d_.invoke(ec);
301 }
302}
303
304//------------------------------------------------------------------------------
305
11fdf7f2 306template<class NextLayer, bool deflateSupported>
b32b8144 307void
11fdf7f2 308stream<NextLayer, deflateSupported>::
b32b8144
FG
309accept()
310{
311 static_assert(is_sync_stream<next_layer_type>::value,
312 "SyncStream requirements not met");
313 error_code ec;
314 accept(ec);
315 if(ec)
316 BOOST_THROW_EXCEPTION(system_error{ec});
317}
318
11fdf7f2 319template<class NextLayer, bool deflateSupported>
b32b8144
FG
320template<class ResponseDecorator>
321void
11fdf7f2 322stream<NextLayer, deflateSupported>::
b32b8144
FG
323accept_ex(ResponseDecorator const& decorator)
324{
325 static_assert(is_sync_stream<next_layer_type>::value,
326 "SyncStream requirements not met");
11fdf7f2 327 static_assert(detail::is_response_decorator<
b32b8144
FG
328 ResponseDecorator>::value,
329 "ResponseDecorator requirements not met");
330 error_code ec;
331 accept_ex(decorator, ec);
332 if(ec)
333 BOOST_THROW_EXCEPTION(system_error{ec});
334}
335
11fdf7f2 336template<class NextLayer, bool deflateSupported>
b32b8144 337void
11fdf7f2 338stream<NextLayer, deflateSupported>::
b32b8144
FG
339accept(error_code& ec)
340{
341 static_assert(is_sync_stream<next_layer_type>::value,
342 "SyncStream requirements not met");
343 reset();
344 do_accept(&default_decorate_res, ec);
345}
346
11fdf7f2 347template<class NextLayer, bool deflateSupported>
b32b8144
FG
348template<class ResponseDecorator>
349void
11fdf7f2 350stream<NextLayer, deflateSupported>::
b32b8144
FG
351accept_ex(ResponseDecorator const& decorator, error_code& ec)
352{
353 static_assert(is_sync_stream<next_layer_type>::value,
354 "SyncStream requirements not met");
11fdf7f2 355 static_assert(detail::is_response_decorator<
b32b8144
FG
356 ResponseDecorator>::value,
357 "ResponseDecorator requirements not met");
358 reset();
359 do_accept(decorator, ec);
360}
361
11fdf7f2 362template<class NextLayer, bool deflateSupported>
b32b8144
FG
363template<class ConstBufferSequence>
364typename std::enable_if<! http::detail::is_header<
365 ConstBufferSequence>::value>::type
11fdf7f2 366stream<NextLayer, deflateSupported>::
b32b8144
FG
367accept(ConstBufferSequence const& buffers)
368{
369 static_assert(is_sync_stream<next_layer_type>::value,
370 "SyncStream requirements not met");
371 static_assert(boost::asio::is_const_buffer_sequence<
372 ConstBufferSequence>::value,
373 "ConstBufferSequence requirements not met");
374 error_code ec;
375 accept(buffers, ec);
376 if(ec)
377 BOOST_THROW_EXCEPTION(system_error{ec});
378}
379
11fdf7f2 380template<class NextLayer, bool deflateSupported>
b32b8144
FG
381template<
382 class ConstBufferSequence,
383 class ResponseDecorator>
384typename std::enable_if<! http::detail::is_header<
385 ConstBufferSequence>::value>::type
11fdf7f2 386stream<NextLayer, deflateSupported>::
b32b8144
FG
387accept_ex(
388 ConstBufferSequence const& buffers,
389 ResponseDecorator const &decorator)
390{
391 static_assert(is_sync_stream<next_layer_type>::value,
392 "SyncStream requirements not met");
393 static_assert(boost::asio::is_const_buffer_sequence<
394 ConstBufferSequence>::value,
395 "ConstBufferSequence requirements not met");
11fdf7f2 396 static_assert(detail::is_response_decorator<
b32b8144
FG
397 ResponseDecorator>::value,
398 "ResponseDecorator requirements not met");
399 error_code ec;
400 accept_ex(buffers, decorator, ec);
401 if(ec)
402 BOOST_THROW_EXCEPTION(system_error{ec});
403}
404
11fdf7f2 405template<class NextLayer, bool deflateSupported>
b32b8144
FG
406template<class ConstBufferSequence>
407typename std::enable_if<! http::detail::is_header<
408 ConstBufferSequence>::value>::type
11fdf7f2 409stream<NextLayer, deflateSupported>::
b32b8144
FG
410accept(
411 ConstBufferSequence const& buffers, error_code& ec)
412{
413 static_assert(is_sync_stream<next_layer_type>::value,
414 "SyncStream requirements not met");
415 static_assert(boost::asio::is_const_buffer_sequence<
416 ConstBufferSequence>::value,
417 "ConstBufferSequence requirements not met");
418 using boost::asio::buffer_copy;
419 using boost::asio::buffer_size;
420 reset();
421 boost::optional<typename
422 static_buffer_base::mutable_buffers_type> mb;
423 try
424 {
425 mb.emplace(rd_buf_.prepare(
426 buffer_size(buffers)));
427 }
428 catch(std::length_error const&)
429 {
430 ec = error::buffer_overflow;
431 return;
432 }
433 rd_buf_.commit(
434 buffer_copy(*mb, buffers));
435 do_accept(&default_decorate_res, ec);
436}
437
11fdf7f2 438template<class NextLayer, bool deflateSupported>
b32b8144
FG
439template<
440 class ConstBufferSequence,
441 class ResponseDecorator>
442typename std::enable_if<! http::detail::is_header<
443 ConstBufferSequence>::value>::type
11fdf7f2 444stream<NextLayer, deflateSupported>::
b32b8144
FG
445accept_ex(
446 ConstBufferSequence const& buffers,
447 ResponseDecorator const& decorator,
448 error_code& ec)
449{
450 static_assert(is_sync_stream<next_layer_type>::value,
451 "SyncStream requirements not met");
452 static_assert(boost::asio::is_const_buffer_sequence<
453 ConstBufferSequence>::value,
454 "ConstBufferSequence requirements not met");
455 static_assert(boost::asio::is_const_buffer_sequence<
456 ConstBufferSequence>::value,
457 "ConstBufferSequence requirements not met");
458 using boost::asio::buffer_copy;
459 using boost::asio::buffer_size;
460 reset();
461 boost::optional<typename
462 static_buffer_base::mutable_buffers_type> mb;
463 try
464 {
465 mb.emplace(rd_buf_.prepare(
466 buffer_size(buffers)));
467 }
468 catch(std::length_error const&)
469 {
470 ec = error::buffer_overflow;
471 return;
472 }
473 rd_buf_.commit(buffer_copy(*mb, buffers));
474 do_accept(decorator, ec);
475}
476
11fdf7f2 477template<class NextLayer, bool deflateSupported>
b32b8144
FG
478template<class Body, class Allocator>
479void
11fdf7f2 480stream<NextLayer, deflateSupported>::
b32b8144
FG
481accept(
482 http::request<Body,
483 http::basic_fields<Allocator>> const& req)
484{
485 static_assert(is_sync_stream<next_layer_type>::value,
486 "SyncStream requirements not met");
487 error_code ec;
488 accept(req, ec);
489 if(ec)
490 BOOST_THROW_EXCEPTION(system_error{ec});
491}
492
11fdf7f2 493template<class NextLayer, bool deflateSupported>
b32b8144
FG
494template<
495 class Body, class Allocator,
496 class ResponseDecorator>
497void
11fdf7f2 498stream<NextLayer, deflateSupported>::
b32b8144
FG
499accept_ex(
500 http::request<Body,
501 http::basic_fields<Allocator>> const& req,
502 ResponseDecorator const& decorator)
503{
504 static_assert(is_sync_stream<next_layer_type>::value,
505 "SyncStream requirements not met");
11fdf7f2 506 static_assert(detail::is_response_decorator<
b32b8144
FG
507 ResponseDecorator>::value,
508 "ResponseDecorator requirements not met");
509 error_code ec;
510 accept_ex(req, decorator, ec);
511 if(ec)
512 BOOST_THROW_EXCEPTION(system_error{ec});
513}
514
11fdf7f2 515template<class NextLayer, bool deflateSupported>
b32b8144
FG
516template<class Body, class Allocator>
517void
11fdf7f2 518stream<NextLayer, deflateSupported>::
b32b8144
FG
519accept(
520 http::request<Body,
521 http::basic_fields<Allocator>> const& req,
522 error_code& ec)
523{
524 static_assert(is_sync_stream<next_layer_type>::value,
525 "SyncStream requirements not met");
526 reset();
527 do_accept(req, &default_decorate_res, ec);
528}
529
11fdf7f2 530template<class NextLayer, bool deflateSupported>
b32b8144
FG
531template<
532 class Body, class Allocator,
533 class ResponseDecorator>
534void
11fdf7f2 535stream<NextLayer, deflateSupported>::
b32b8144
FG
536accept_ex(
537 http::request<Body,
538 http::basic_fields<Allocator>> const& req,
539 ResponseDecorator const& decorator,
540 error_code& ec)
541{
542 static_assert(is_sync_stream<next_layer_type>::value,
543 "SyncStream requirements not met");
11fdf7f2 544 static_assert(detail::is_response_decorator<
b32b8144
FG
545 ResponseDecorator>::value,
546 "ResponseDecorator requirements not met");
547 reset();
548 do_accept(req, decorator, ec);
549}
550
551//------------------------------------------------------------------------------
552
11fdf7f2 553template<class NextLayer, bool deflateSupported>
b32b8144
FG
554template<
555 class AcceptHandler>
556BOOST_ASIO_INITFN_RESULT_TYPE(
557 AcceptHandler, void(error_code))
11fdf7f2 558stream<NextLayer, deflateSupported>::
b32b8144
FG
559async_accept(
560 AcceptHandler&& handler)
561{
562 static_assert(is_async_stream<next_layer_type>::value,
11fdf7f2
TL
563 "AsyncStream requirements not met");
564 BOOST_BEAST_HANDLER_INIT(
565 AcceptHandler, void(error_code));
b32b8144
FG
566 reset();
567 accept_op<
568 decltype(&default_decorate_res),
569 BOOST_ASIO_HANDLER_TYPE(
570 AcceptHandler, void(error_code))>{
11fdf7f2 571 std::move(init.completion_handler),
b32b8144
FG
572 *this,
573 &default_decorate_res}({});
574 return init.result.get();
575}
576
11fdf7f2 577template<class NextLayer, bool deflateSupported>
b32b8144
FG
578template<
579 class ResponseDecorator,
580 class AcceptHandler>
581BOOST_ASIO_INITFN_RESULT_TYPE(
582 AcceptHandler, void(error_code))
11fdf7f2 583stream<NextLayer, deflateSupported>::
b32b8144
FG
584async_accept_ex(
585 ResponseDecorator const& decorator,
586 AcceptHandler&& handler)
587{
588 static_assert(is_async_stream<next_layer_type>::value,
11fdf7f2
TL
589 "AsyncStream requirements not met");
590 static_assert(detail::is_response_decorator<
b32b8144
FG
591 ResponseDecorator>::value,
592 "ResponseDecorator requirements not met");
11fdf7f2
TL
593 BOOST_BEAST_HANDLER_INIT(
594 AcceptHandler, void(error_code));
b32b8144
FG
595 reset();
596 accept_op<
597 ResponseDecorator,
598 BOOST_ASIO_HANDLER_TYPE(
599 AcceptHandler, void(error_code))>{
11fdf7f2 600 std::move(init.completion_handler),
b32b8144
FG
601 *this,
602 decorator}({});
603 return init.result.get();
604}
605
11fdf7f2 606template<class NextLayer, bool deflateSupported>
b32b8144
FG
607template<
608 class ConstBufferSequence,
609 class AcceptHandler>
610typename std::enable_if<
611 ! http::detail::is_header<ConstBufferSequence>::value,
612 BOOST_ASIO_INITFN_RESULT_TYPE(
613 AcceptHandler, void(error_code))>::type
11fdf7f2 614stream<NextLayer, deflateSupported>::
b32b8144
FG
615async_accept(
616 ConstBufferSequence const& buffers,
617 AcceptHandler&& handler)
618{
619 static_assert(is_async_stream<next_layer_type>::value,
11fdf7f2 620 "AsyncStream requirements not met");
b32b8144
FG
621 static_assert(boost::asio::is_const_buffer_sequence<
622 ConstBufferSequence>::value,
623 "ConstBufferSequence requirements not met");
11fdf7f2
TL
624 BOOST_BEAST_HANDLER_INIT(
625 AcceptHandler, void(error_code));
b32b8144
FG
626 reset();
627 accept_op<
628 decltype(&default_decorate_res),
629 BOOST_ASIO_HANDLER_TYPE(
630 AcceptHandler, void(error_code))>{
11fdf7f2 631 std::move(init.completion_handler),
b32b8144
FG
632 *this,
633 &default_decorate_res}.run(buffers);
634 return init.result.get();
635}
636
11fdf7f2 637template<class NextLayer, bool deflateSupported>
b32b8144
FG
638template<
639 class ConstBufferSequence,
640 class ResponseDecorator,
641 class AcceptHandler>
642typename std::enable_if<
643 ! http::detail::is_header<ConstBufferSequence>::value,
644 BOOST_ASIO_INITFN_RESULT_TYPE(
645 AcceptHandler, void(error_code))>::type
11fdf7f2 646stream<NextLayer, deflateSupported>::
b32b8144
FG
647async_accept_ex(
648 ConstBufferSequence const& buffers,
649 ResponseDecorator const& decorator,
650 AcceptHandler&& handler)
651{
652 static_assert(is_async_stream<next_layer_type>::value,
11fdf7f2 653 "AsyncStream requirements not met");
b32b8144
FG
654 static_assert(boost::asio::is_const_buffer_sequence<
655 ConstBufferSequence>::value,
656 "ConstBufferSequence requirements not met");
11fdf7f2 657 static_assert(detail::is_response_decorator<
b32b8144
FG
658 ResponseDecorator>::value,
659 "ResponseDecorator requirements not met");
11fdf7f2
TL
660 BOOST_BEAST_HANDLER_INIT(
661 AcceptHandler, void(error_code));
b32b8144
FG
662 reset();
663 accept_op<
664 ResponseDecorator,
665 BOOST_ASIO_HANDLER_TYPE(
666 AcceptHandler, void(error_code))>{
11fdf7f2 667 std::move(init.completion_handler),
b32b8144
FG
668 *this,
669 decorator}.run(buffers);
670 return init.result.get();
671}
672
11fdf7f2 673template<class NextLayer, bool deflateSupported>
b32b8144
FG
674template<
675 class Body, class Allocator,
676 class AcceptHandler>
677BOOST_ASIO_INITFN_RESULT_TYPE(
678 AcceptHandler, void(error_code))
11fdf7f2 679stream<NextLayer, deflateSupported>::
b32b8144
FG
680async_accept(
681 http::request<Body, http::basic_fields<Allocator>> const& req,
682 AcceptHandler&& handler)
683{
684 static_assert(is_async_stream<next_layer_type>::value,
11fdf7f2
TL
685 "AsyncStream requirements not met");
686 BOOST_BEAST_HANDLER_INIT(
687 AcceptHandler, void(error_code));
b32b8144
FG
688 reset();
689 using boost::asio::asio_handler_is_continuation;
690 response_op<
691 BOOST_ASIO_HANDLER_TYPE(
692 AcceptHandler, void(error_code))>{
11fdf7f2 693 std::move(init.completion_handler),
b32b8144
FG
694 *this,
695 req,
696 &default_decorate_res}();
697 return init.result.get();
698}
699
11fdf7f2 700template<class NextLayer, bool deflateSupported>
b32b8144
FG
701template<
702 class Body, class Allocator,
703 class ResponseDecorator,
704 class AcceptHandler>
705BOOST_ASIO_INITFN_RESULT_TYPE(
706 AcceptHandler, void(error_code))
11fdf7f2 707stream<NextLayer, deflateSupported>::
b32b8144
FG
708async_accept_ex(
709 http::request<Body, http::basic_fields<Allocator>> const& req,
710 ResponseDecorator const& decorator,
711 AcceptHandler&& handler)
712{
713 static_assert(is_async_stream<next_layer_type>::value,
11fdf7f2
TL
714 "AsyncStream requirements not met");
715 static_assert(detail::is_response_decorator<
b32b8144
FG
716 ResponseDecorator>::value,
717 "ResponseDecorator requirements not met");
11fdf7f2
TL
718 BOOST_BEAST_HANDLER_INIT(
719 AcceptHandler, void(error_code));
b32b8144
FG
720 reset();
721 using boost::asio::asio_handler_is_continuation;
722 response_op<
723 BOOST_ASIO_HANDLER_TYPE(
724 AcceptHandler, void(error_code))>{
11fdf7f2 725 std::move(init.completion_handler),
b32b8144
FG
726 *this,
727 req,
728 decorator}();
729 return init.result.get();
730}
731
732//------------------------------------------------------------------------------
733
11fdf7f2 734template<class NextLayer, bool deflateSupported>
b32b8144
FG
735template<class Decorator>
736void
11fdf7f2 737stream<NextLayer, deflateSupported>::
b32b8144
FG
738do_accept(
739 Decorator const& decorator,
740 error_code& ec)
741{
742 http::request_parser<http::empty_body> p;
743 http::read(next_layer(), rd_buf_, p, ec);
744 if(ec == http::error::end_of_stream)
745 ec = error::closed;
746 if(ec)
747 return;
748 do_accept(p.get(), decorator, ec);
749}
750
11fdf7f2 751template<class NextLayer, bool deflateSupported>
b32b8144
FG
752template<class Body, class Allocator,
753 class Decorator>
754void
11fdf7f2 755stream<NextLayer, deflateSupported>::
b32b8144 756do_accept(
11fdf7f2
TL
757 http::request<Body,
758 http::basic_fields<Allocator>> const& req,
b32b8144
FG
759 Decorator const& decorator,
760 error_code& ec)
761{
11fdf7f2
TL
762 error_code result;
763 auto const res = build_response(req, decorator, result);
b32b8144
FG
764 http::write(stream_, res, ec);
765 if(ec)
766 return;
11fdf7f2
TL
767 ec = result;
768 if(ec)
b32b8144 769 {
b32b8144
FG
770 // VFALCO TODO Respect keep alive setting, perform
771 // teardown if Connection: close.
772 return;
773 }
11fdf7f2 774 do_pmd_config(res, is_deflate_supported{});
b32b8144
FG
775 open(role_type::server);
776}
777
778} // websocket
779} // beast
780} // boost
781
782#endif