]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/test/http/message.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / Beast / test / http / message.cpp
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 // Test that header file is self-contained.
9 #include <beast/http/message.hpp>
10
11 #include <beast/http/string_body.hpp>
12 #include <beast/http/fields.hpp>
13 #include <beast/http/string_body.hpp>
14 #include <beast/unit_test/suite.hpp>
15 #include <type_traits>
16
17 namespace beast {
18 namespace http {
19
20 class message_test : public beast::unit_test::suite
21 {
22 public:
23 struct Arg1
24 {
25 bool moved = false;
26
27 Arg1() = default;
28
29 Arg1(Arg1&& other)
30 {
31 other.moved = true;
32 }
33 };
34
35 struct Arg2 { };
36 struct Arg3 { };
37
38 // default constructible Body
39 struct default_body
40 {
41 using value_type = std::string;
42 };
43
44 // 1-arg constructible Body
45 struct one_arg_body
46 {
47 struct value_type
48 {
49 explicit
50 value_type(Arg1 const&)
51 {
52 }
53
54 explicit
55 value_type(Arg1&& arg)
56 {
57 Arg1 arg_(std::move(arg));
58 }
59 };
60 };
61
62 // 2-arg constructible Body
63 struct two_arg_body
64 {
65 struct value_type
66 {
67 value_type(Arg1 const&, Arg2 const&)
68 {
69 }
70 };
71 };
72
73 void testMessage()
74 {
75 static_assert(std::is_constructible<
76 message<true, default_body, fields>>::value, "");
77
78 static_assert(std::is_constructible<
79 message<true, one_arg_body, fields>, Arg1>::value, "");
80
81 static_assert(std::is_constructible<
82 message<true, one_arg_body, fields>, Arg1 const>::value, "");
83
84 static_assert(std::is_constructible<
85 message<true, one_arg_body, fields>, Arg1 const&>::value, "");
86
87 static_assert(std::is_constructible<
88 message<true, one_arg_body, fields>, Arg1&&>::value, "");
89
90 static_assert(! std::is_constructible<
91 message<true, one_arg_body, fields>>::value, "");
92
93 static_assert(std::is_constructible<
94 message<true, one_arg_body, fields>,
95 Arg1, fields::allocator_type>::value, "");
96
97 static_assert(std::is_constructible<
98 message<true, one_arg_body, fields>, std::piecewise_construct_t,
99 std::tuple<Arg1>>::value, "");
100
101 static_assert(std::is_constructible<
102 message<true, two_arg_body, fields>, std::piecewise_construct_t,
103 std::tuple<Arg1, Arg2>>::value, "");
104
105 static_assert(std::is_constructible<
106 message<true, two_arg_body, fields>, std::piecewise_construct_t,
107 std::tuple<Arg1, Arg2>, std::tuple<fields::allocator_type>>::value, "");
108
109 {
110 Arg1 arg1;
111 message<true, one_arg_body, fields>{std::move(arg1)};
112 BEAST_EXPECT(arg1.moved);
113 }
114
115 {
116 fields h;
117 h.insert("User-Agent", "test");
118 message<true, one_arg_body, fields> m{Arg1{}, h};
119 BEAST_EXPECT(h["User-Agent"] == "test");
120 BEAST_EXPECT(m.fields["User-Agent"] == "test");
121 }
122 {
123 fields h;
124 h.insert("User-Agent", "test");
125 message<true, one_arg_body, fields> m{Arg1{}, std::move(h)};
126 BEAST_EXPECT(! h.exists("User-Agent"));
127 BEAST_EXPECT(m.fields["User-Agent"] == "test");
128 }
129
130 // swap
131 message<true, string_body, fields> m1;
132 message<true, string_body, fields> m2;
133 m1.url = "u";
134 m1.body = "1";
135 m1.fields.insert("h", "v");
136 m2.method = "G";
137 m2.body = "2";
138 swap(m1, m2);
139 BEAST_EXPECT(m1.method == "G");
140 BEAST_EXPECT(m2.method.empty());
141 BEAST_EXPECT(m1.url.empty());
142 BEAST_EXPECT(m2.url == "u");
143 BEAST_EXPECT(m1.body == "2");
144 BEAST_EXPECT(m2.body == "1");
145 BEAST_EXPECT(! m1.fields.exists("h"));
146 BEAST_EXPECT(m2.fields.exists("h"));
147 }
148
149 struct MoveHeaders
150 {
151 bool moved_to = false;
152 bool moved_from = false;
153
154 MoveHeaders() = default;
155
156 MoveHeaders(MoveHeaders&& other)
157 : moved_to(true)
158 {
159 other.moved_from = true;
160 }
161
162 MoveHeaders& operator=(MoveHeaders&& other)
163 {
164 return *this;
165 }
166 };
167
168 void testHeaders()
169 {
170 {
171 using req_type = request_header;
172 static_assert(std::is_copy_constructible<req_type>::value, "");
173 static_assert(std::is_move_constructible<req_type>::value, "");
174 static_assert(std::is_copy_assignable<req_type>::value, "");
175 static_assert(std::is_move_assignable<req_type>::value, "");
176
177 using res_type = response_header;
178 static_assert(std::is_copy_constructible<res_type>::value, "");
179 static_assert(std::is_move_constructible<res_type>::value, "");
180 static_assert(std::is_copy_assignable<res_type>::value, "");
181 static_assert(std::is_move_assignable<res_type>::value, "");
182 }
183
184 {
185 MoveHeaders h;
186 header<true, MoveHeaders> r{std::move(h)};
187 BEAST_EXPECT(h.moved_from);
188 BEAST_EXPECT(r.fields.moved_to);
189 request<string_body, MoveHeaders> m{std::move(r)};
190 BEAST_EXPECT(r.fields.moved_from);
191 BEAST_EXPECT(m.fields.moved_to);
192 }
193 }
194
195 void testFreeFunctions()
196 {
197 {
198 request<string_body> m;
199 m.method = "GET";
200 m.url = "/";
201 m.version = 11;
202 m.fields.insert("Upgrade", "test");
203 BEAST_EXPECT(! is_upgrade(m));
204
205 prepare(m, connection::upgrade);
206 BEAST_EXPECT(is_upgrade(m));
207 BEAST_EXPECT(m.fields["Connection"] == "upgrade");
208
209 m.version = 10;
210 BEAST_EXPECT(! is_upgrade(m));
211 }
212 }
213
214 void testPrepare()
215 {
216 request<string_body> m;
217 m.version = 10;
218 BEAST_EXPECT(! is_upgrade(m));
219 m.fields.insert("Transfer-Encoding", "chunked");
220 try
221 {
222 prepare(m);
223 fail();
224 }
225 catch(std::exception const&)
226 {
227 }
228 m.fields.erase("Transfer-Encoding");
229 m.fields.insert("Content-Length", "0");
230 try
231 {
232 prepare(m);
233 fail();
234 }
235 catch(std::exception const&)
236 {
237 pass();
238 }
239 m.fields.erase("Content-Length");
240 m.fields.insert("Connection", "keep-alive");
241 try
242 {
243 prepare(m);
244 fail();
245 }
246 catch(std::exception const&)
247 {
248 pass();
249 }
250 m.version = 11;
251 m.fields.erase("Connection");
252 m.fields.insert("Connection", "close");
253 BEAST_EXPECT(! is_keep_alive(m));
254 }
255
256 void testSwap()
257 {
258 message<false, string_body, fields> m1;
259 message<false, string_body, fields> m2;
260 m1.status = 200;
261 m1.version = 10;
262 m1.body = "1";
263 m1.fields.insert("h", "v");
264 m2.status = 404;
265 m2.reason = "OK";
266 m2.body = "2";
267 m2.version = 11;
268 swap(m1, m2);
269 BEAST_EXPECT(m1.status == 404);
270 BEAST_EXPECT(m2.status == 200);
271 BEAST_EXPECT(m1.reason == "OK");
272 BEAST_EXPECT(m2.reason.empty());
273 BEAST_EXPECT(m1.version == 11);
274 BEAST_EXPECT(m2.version == 10);
275 BEAST_EXPECT(m1.body == "2");
276 BEAST_EXPECT(m2.body == "1");
277 BEAST_EXPECT(! m1.fields.exists("h"));
278 BEAST_EXPECT(m2.fields.exists("h"));
279 }
280
281 void
282 testSpecialMembers()
283 {
284 response<string_body> r1;
285 response<string_body> r2{r1};
286 response<string_body> r3{std::move(r2)};
287 r2 = r3;
288 r1 = std::move(r2);
289 [r1]()
290 {
291 }();
292 }
293
294 void run() override
295 {
296 testMessage();
297 testHeaders();
298 testFreeFunctions();
299 testPrepare();
300 testSwap();
301 testSpecialMembers();
302 }
303 };
304
305 BEAST_DEFINE_TESTSUITE(message,http,beast);
306
307 } // http
308 } // beast