]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/include/beast/websocket/detail/decorator.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / include / beast / websocket / detail / decorator.hpp
1 //
2 // Copyright (c) 2013-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
8 #ifndef BEAST_WEBSOCKET_DETAIL_DECORATOR_HPP
9 #define BEAST_WEBSOCKET_DETAIL_DECORATOR_HPP
10
11 #include <beast/http/message.hpp>
12 #include <beast/http/string_body.hpp>
13 #include <beast/version.hpp>
14 #include <type_traits>
15 #include <utility>
16
17 namespace beast {
18 namespace websocket {
19 namespace detail {
20
21 using request_type = http::request_header;
22
23 using response_type = http::response_header;
24
25 struct abstract_decorator
26 {
27 virtual
28 ~abstract_decorator() = default;
29
30 virtual
31 void
32 operator()(request_type& req) const = 0;
33
34 virtual
35 void
36 operator()(response_type& res) const = 0;
37 };
38
39 template<class F>
40 class decorator : public abstract_decorator
41 {
42 F f_;
43
44 class call_req_possible
45 {
46 template<class U, class R = decltype(
47 std::declval<U const>().operator()(
48 std::declval<request_type&>()),
49 std::true_type{})>
50 static R check(int);
51 template<class>
52 static std::false_type check(...);
53 public:
54 using type = decltype(check<F>(0));
55 };
56
57 class call_res_possible
58 {
59 template<class U, class R = decltype(
60 std::declval<U const>().operator()(
61 std::declval<response_type&>()),
62 std::true_type{})>
63 static R check(int);
64 template<class>
65 static std::false_type check(...);
66 public:
67 using type = decltype(check<F>(0));
68 };
69
70 public:
71 decorator(F&& t)
72 : f_(std::move(t))
73 {
74 }
75
76 decorator(F const& t)
77 : f_(t)
78 {
79 }
80
81 void
82 operator()(request_type& req) const override
83 {
84 (*this)(req, typename call_req_possible::type{});
85 }
86
87 void
88 operator()(response_type& res) const override
89 {
90 (*this)(res, typename call_res_possible::type{});
91 }
92
93 private:
94 void
95 operator()(request_type& req, std::true_type) const
96 {
97 f_(req);
98 }
99
100 void
101 operator()(request_type& req, std::false_type) const
102 {
103 req.fields.replace("User-Agent",
104 std::string{"Beast/"} + BEAST_VERSION_STRING);
105 }
106
107 void
108 operator()(response_type& res, std::true_type) const
109 {
110 f_(res);
111 }
112
113 void
114 operator()(response_type& res, std::false_type) const
115 {
116 res.fields.replace("Server",
117 std::string{"Beast/"} + BEAST_VERSION_STRING);
118 }
119 };
120
121 class decorator_type
122 {
123 std::shared_ptr<abstract_decorator> p_;
124
125 public:
126 decorator_type() = delete;
127 decorator_type(decorator_type&&) = default;
128 decorator_type(decorator_type const&) = default;
129 decorator_type& operator=(decorator_type&&) = default;
130 decorator_type& operator=(decorator_type const&) = default;
131
132 template<class F, class =
133 typename std::enable_if<! std::is_same<
134 typename std::decay<F>::type,
135 decorator_type>::value>>
136 decorator_type(F&& f)
137 : p_(std::make_shared<decorator<F>>(
138 std::forward<F>(f)))
139 {
140 BOOST_ASSERT(p_);
141 }
142
143 void
144 operator()(request_type& req)
145 {
146 (*p_)(req);
147 BOOST_ASSERT(p_);
148 }
149
150 void
151 operator()(response_type& res)
152 {
153 (*p_)(res);
154 BOOST_ASSERT(p_);
155 }
156 };
157
158 struct default_decorator
159 {
160 };
161
162 } // detail
163 } // websocket
164 } // beast
165
166 #endif