]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/beast/http/chunk_encode.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / beast / test / beast / http / chunk_encode.cpp
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 // Test that header file is self-contained.
11 #include <boost/beast/http/chunk_encode.hpp>
12
13 #include "message_fuzz.hpp"
14
15 #include <boost/beast/core/static_string.hpp>
16 #include <boost/beast/http/fields.hpp>
17 #include <boost/beast/test/fuzz.hpp>
18 #include <boost/beast/unit_test/suite.hpp>
19 #include <boost/optional.hpp>
20 #include <random>
21
22 namespace boost {
23 namespace beast {
24 namespace http {
25
26 class chunk_encode_test
27 : public beast::unit_test::suite
28 {
29 public:
30 struct not_chunk_extensions {};
31
32 BOOST_STATIC_ASSERT(
33 detail::is_chunk_extensions<chunk_extensions>::value);
34
35 BOOST_STATIC_ASSERT(
36 ! detail::is_chunk_extensions<not_chunk_extensions>::value);
37
38 template<class ConstBufferSequence>
39 static
40 std::string
41 to_string(ConstBufferSequence const& buffers)
42 {
43 std::string s;
44 s.reserve(boost::asio::buffer_size(buffers));
45 for(boost::asio::const_buffer b : beast::detail::buffers_range(buffers))
46 s.append(
47 reinterpret_cast<char const*>(b.data()),
48 b.size());
49 return s;
50 }
51
52 template<class T, class... Args>
53 void
54 check(string_view match, Args&&... args)
55 {
56 T t(std::forward<Args>(args)...);
57 BEAST_EXPECT(to_string(t) == match);
58 T t2(t);
59 BEAST_EXPECT(to_string(t2) == match);
60 T t3(std::move(t2));
61 BEAST_EXPECT(to_string(t3) == match);
62 }
63
64 template<class T, class... Args>
65 void
66 check_fwd(string_view match, Args&&... args)
67 {
68 T t(std::forward<Args>(args)...);
69 BEAST_EXPECT(to_string(t) == match);
70 T t2(t);
71 BEAST_EXPECT(to_string(t2) == match);
72 T t3(std::move(t2));
73 BEAST_EXPECT(to_string(t3) == match);
74 }
75
76 using cb_t = boost::asio::const_buffer;
77
78 static
79 cb_t
80 cb(string_view s)
81 {
82 return {s.data(), s.size()};
83 }
84
85 void
86 testChunkCRLF()
87 {
88 #if ! defined(BOOST_GCC) || BOOST_GCC >= 50000
89 check<chunk_crlf>("\r\n");
90 #endif
91 }
92
93 void
94 testChunkHeader()
95 {
96 check<chunk_header>("10\r\n", 16u);
97
98 check<chunk_header>("20;x\r\n", 32u, ";x");
99
100 chunk_extensions exts;
101 exts.insert("y");
102 exts.insert("z");
103
104 check<chunk_header>("30;y;z\r\n", 48u, exts);
105
106 {
107 auto exts2 = exts;
108
109 check_fwd<chunk_header>(
110 "30;y;z\r\n", 48u, std::move(exts2));
111 }
112
113 check<chunk_header>("30;y;z\r\n", 48u, exts,
114 std::allocator<double>{});
115
116 {
117 auto exts2 = exts;
118
119 check<chunk_header>(
120 "30;y;z\r\n", 48u, std::move(exts2),
121 std::allocator<double>{});
122 }
123 }
124
125 void
126 testChunkBody()
127 {
128 check<chunk_body<cb_t>>(
129 "3\r\n***\r\n", cb("***"));
130
131 check<chunk_body<cb_t>>(
132 "3;x\r\n***\r\n", cb("***"), ";x");
133
134 chunk_extensions exts;
135 exts.insert("y");
136 exts.insert("z");
137
138 check<chunk_body<cb_t>>(
139 "3;y;z\r\n***\r\n",
140 cb("***"), exts);
141
142 {
143 auto exts2 = exts;
144
145 check_fwd<chunk_body<cb_t>>(
146 "3;y;z\r\n***\r\n",
147 cb("***"), std::move(exts2));
148 }
149
150 check<chunk_body<cb_t>>(
151 "3;y;z\r\n***\r\n",
152 cb("***"), exts, std::allocator<double>{});
153
154 {
155 auto exts2 = exts;
156
157 check_fwd<chunk_body<cb_t>>(
158 "3;y;z\r\n***\r\n",
159 cb("***"), std::move(exts2),
160 std::allocator<double>{});
161 }
162 }
163
164 void
165 testChunkFinal()
166 {
167 check<chunk_last<>>(
168 "0\r\n\r\n");
169
170 check<chunk_last<cb_t>>(
171 "0\r\nMD5:ou812\r\n\r\n",
172 cb("MD5:ou812\r\n\r\n"));
173
174 fields trailers;
175 trailers.set(field::content_md5, "ou812");
176
177 check<chunk_last<fields>>(
178 "0\r\nContent-MD5: ou812\r\n\r\n",
179 trailers);
180
181 {
182 auto trailers2 = trailers;
183
184 check_fwd<chunk_last<fields>>(
185 "0\r\nContent-MD5: ou812\r\n\r\n",
186 std::move(trailers2));
187 }
188
189 check<chunk_last<fields>>(
190 "0\r\nContent-MD5: ou812\r\n\r\n",
191 trailers, std::allocator<double>{});
192
193 {
194 auto trailers2 = trailers;
195
196 check<chunk_last<fields>>(
197 "0\r\nContent-MD5: ou812\r\n\r\n",
198 std::move(trailers2), std::allocator<double>{});
199 }
200 }
201
202 void
203 testChunkExtensions()
204 {
205 auto const str =
206 [](chunk_extensions const& ce)
207 {
208 std::string s;
209 for(auto const& v : ce)
210 {
211 s.append(v.first.to_string());
212 s.push_back(',');
213 if(! v.second.empty())
214 {
215 s.append(v.second.to_string());
216 s.push_back(',');
217 }
218 }
219 return s;
220 };
221 chunk_extensions ce;
222 ce.insert("x");
223 BEAST_EXPECT(ce.str() == ";x");
224 BEAST_EXPECT(str(ce) == "x,");
225 ce.insert("y", "z");
226 BEAST_EXPECT(ce.str() == ";x;y=z");
227 BEAST_EXPECT(str(ce) == "x,y,z,");
228 ce.insert("z", R"(")");
229 BEAST_EXPECT(ce.str() == R"(;x;y=z;z="\"")");
230 BEAST_EXPECT(str(ce) == R"(x,y,z,z,",)");
231 ce.insert("p", R"(\)");
232 BEAST_EXPECT(ce.str() == R"(;x;y=z;z="\"";p="\\")");
233 BEAST_EXPECT(str(ce) == R"(x,y,z,z,",p,\,)");
234 ce.insert("q", R"(1"2\)");
235 BEAST_EXPECT(ce.str() == R"(;x;y=z;z="\"";p="\\";q="1\"2\\")");
236 BEAST_EXPECT(str(ce) == R"(x,y,z,z,",p,\,q,1"2\,)");
237 }
238
239 void
240 testParseChunkExtensions()
241 {
242 auto const grind =
243 [&](string_view s)
244 {
245 error_code ec;
246 static_string<200> ss{s};
247 test::fuzz_rand r;
248 for(auto i = 3; i--;)
249 {
250 test::fuzz(ss, 5, 5, r,
251 [&](string_view s)
252 {
253 chunk_extensions c1;
254 c1.parse(s, ec);
255 if(ec)
256 {
257 pass();
258 return;
259 }
260 chunk_extensions c2;
261 c2.parse(c1.str(), ec);
262 if(! BEAST_EXPECTS(! ec, ec.message()))
263 return;
264 chunk_extensions c3;
265 for(auto const& v : c2)
266 if(v.second.empty())
267 c3.insert(v.first);
268 else
269 c3.insert(v.first, v.second);
270 BEAST_EXPECTS(c2.str() == c3.str(), c3.str());
271 });
272 }
273 };
274 auto const good =
275 [&](string_view s)
276 {
277 error_code ec;
278 chunk_extensions ce;
279 ce.parse(s, ec);
280 BEAST_EXPECTS(! ec, ec.message());
281 grind(s);
282 };
283 auto const bad =
284 [&](string_view s)
285 {
286 error_code ec;
287 chunk_extensions ce;
288 ce.parse(s, ec);
289 BEAST_EXPECT(ec);
290 grind(s);
291 };
292 chunkExtensionsTest(good, bad);
293 }
294
295 void
296 run() override
297 {
298 testChunkCRLF();
299 testChunkHeader();
300 testChunkBody();
301 testChunkFinal();
302 testChunkExtensions();
303 testParseChunkExtensions();
304 }
305 };
306
307 BEAST_DEFINE_TESTSUITE(beast,http,chunk_encode);
308
309 } // http
310 } // beast
311 } // boost