]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/beast/http/read.cpp
2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
7 // Official repository: https://github.com/boostorg/beast
10 // Test that header file is self-contained.
11 #include <boost/beast/http/read.hpp>
13 #include "test_parser.hpp"
15 #include <boost/beast/core/ostream.hpp>
16 #include <boost/beast/core/flat_static_buffer.hpp>
17 #include <boost/beast/http/fields.hpp>
18 #include <boost/beast/http/dynamic_body.hpp>
19 #include <boost/beast/http/parser.hpp>
20 #include <boost/beast/http/string_body.hpp>
21 #include <boost/beast/test/stream.hpp>
22 #include <boost/beast/test/yield_to.hpp>
23 #include <boost/beast/unit_test/suite.hpp>
24 #include <boost/asio/spawn.hpp>
32 : public beast::unit_test::suite
33 , public test::enable_yield_to
36 template<bool isRequest
>
38 failMatrix(char const* s
, yield_context do_yield
)
40 using boost::asio::buffer
;
41 using boost::asio::buffer_copy
;
42 static std::size_t constexpr limit
= 100;
44 auto const len
= strlen(s
);
45 for(n
= 0; n
< limit
; ++n
)
49 b
.prepare(len
), buffer(s
, len
)));
50 test::fail_counter
fc(n
);
51 test::stream ts
{ioc_
, fc
};
52 test_parser
<isRequest
> p(fc
);
53 error_code ec
= test::error::fail_error
;
59 BEAST_EXPECT(n
< limit
);
60 for(n
= 0; n
< limit
; ++n
)
62 static std::size_t constexpr pre
= 10;
65 b
.prepare(pre
), buffer(s
, pre
)));
66 test::fail_counter
fc(n
);
67 test::stream ts
{ioc_
, fc
,
68 std::string(s
+ pre
, len
- pre
)};
69 test_parser
<isRequest
> p(fc
);
70 error_code ec
= test::error::fail_error
;
76 BEAST_EXPECT(n
< limit
);
77 for(n
= 0; n
< limit
; ++n
)
81 b
.prepare(len
), buffer(s
, len
)));
82 test::fail_counter
fc(n
);
83 test::stream ts
{ioc_
, fc
};
84 test_parser
<isRequest
> p(fc
);
85 error_code ec
= test::error::fail_error
;
87 async_read(ts
, b
, p
, do_yield
[ec
]);
91 BEAST_EXPECT(n
< limit
);
92 for(n
= 0; n
< limit
; ++n
)
96 b
.prepare(len
), buffer(s
, len
)));
97 test::fail_counter
fc(n
);
98 test::stream ts
{ioc_
, fc
};
99 test_parser
<isRequest
> p(fc
);
100 error_code ec
= test::error::fail_error
;
102 async_read_header(ts
, b
, p
, do_yield
[ec
]);
106 BEAST_EXPECT(n
< limit
);
107 for(n
= 0; n
< limit
; ++n
)
109 static std::size_t constexpr pre
= 10;
111 b
.commit(buffer_copy(
112 b
.prepare(pre
), buffer(s
, pre
)));
113 test::fail_counter
fc(n
);
114 test::stream
ts(ioc_
, fc
,
115 std::string
{s
+ pre
, len
- pre
});
116 test_parser
<isRequest
> p(fc
);
117 error_code ec
= test::error::fail_error
;
119 async_read(ts
, b
, p
, do_yield
[ec
]);
123 BEAST_EXPECT(n
< limit
);
131 test::stream c
{ioc_
, "GET / X"};
133 request_parser
<dynamic_body
> p
;
137 catch(std::exception
const&)
147 test::stream c
{ioc_
};
148 ostream(c
.buffer()) <<
150 "Host: localhost\r\n"
151 "User-Agent: test\r\n"
152 "Transfer-Encoding: chunked\r\n"
155 "****************\r\n"
157 flat_static_buffer
<1024> b
;
158 request
<string_body
> req
;
164 catch(std::exception
const& e
)
166 fail(e
.what(), __FILE__
, __LINE__
);
170 test::stream c
{ioc_
};
171 ostream(c
.buffer()) <<
173 "Host: localhost\r\n"
174 "User-Agent: test\r\n"
175 "Transfer-Encoding: chunked\r\n"
178 "****************\r\n"
180 error_code ec
= test::error::fail_error
;
181 flat_static_buffer
<10> b
;
182 request
<string_body
> req
;
184 BEAST_EXPECTS(ec
== error::buffer_overflow
,
189 void testFailures(yield_context do_yield
)
191 char const* req
[] = {
193 "Host: localhost\r\n"
194 "User-Agent: test\r\n"
199 "Host: localhost\r\n"
200 "User-Agent: test\r\n"
201 "Content-Length: 2\r\n"
206 "Host: localhost\r\n"
207 "User-Agent: test\r\n"
208 "Transfer-Encoding: chunked\r\n"
211 "****************\r\n"
217 char const* res
[] = {
218 "HTTP/1.0 200 OK\r\n"
222 "HTTP/1.0 200 OK\r\n"
227 "HTTP/1.1 200 OK\r\n"
229 "Content-Length: 3\r\n"
233 "HTTP/1.1 200 OK\r\n"
235 "Transfer-Encoding: chunked\r\n"
238 "****************\r\n"
243 for(std::size_t i
= 0; req
[i
]; ++i
)
244 failMatrix
<true>(req
[i
], do_yield
);
245 for(std::size_t i
= 0; res
[i
]; ++i
)
246 failMatrix
<false>(res
[i
], do_yield
);
249 void testRead(yield_context do_yield
)
251 static std::size_t constexpr limit
= 100;
254 for(n
= 0; n
< limit
; ++n
)
256 test::fail_counter fc
{n
};
257 test::stream c
{ioc_
, fc
,
259 "Host: localhost\r\n"
260 "User-Agent: test\r\n"
261 "Content-Length: 0\r\n"
264 request
<dynamic_body
> m
;
271 catch(std::exception
const&)
275 BEAST_EXPECT(n
< limit
);
277 for(n
= 0; n
< limit
; ++n
)
279 test::fail_counter fc
{n
};
280 test::stream ts
{ioc_
, fc
,
282 "Host: localhost\r\n"
283 "User-Agent: test\r\n"
284 "Content-Length: 0\r\n"
287 request
<dynamic_body
> m
;
288 error_code ec
= test::error::fail_error
;
294 BEAST_EXPECT(n
< limit
);
296 for(n
= 0; n
< limit
; ++n
)
298 test::fail_counter fc
{n
};
299 test::stream c
{ioc_
, fc
,
301 "Host: localhost\r\n"
302 "User-Agent: test\r\n"
303 "Content-Length: 0\r\n"
306 request
<dynamic_body
> m
;
307 error_code ec
= test::error::fail_error
;
309 async_read(c
, b
, m
, do_yield
[ec
]);
313 BEAST_EXPECT(n
< limit
);
315 for(n
= 0; n
< limit
; ++n
)
317 test::fail_counter fc
{n
};
318 test::stream c
{ioc_
, fc
,
320 "Host: localhost\r\n"
321 "User-Agent: test\r\n"
322 "Content-Length: 0\r\n"
325 request_parser
<dynamic_body
> m
;
326 error_code ec
= test::error::fail_error
;
328 async_read_some(c
, b
, m
, do_yield
[ec
]);
332 BEAST_EXPECT(n
< limit
);
336 testEof(yield_context do_yield
)
340 test::stream ts
{ioc_
};
341 request_parser
<dynamic_body
> p
;
345 BEAST_EXPECT(ec
== http::error::end_of_stream
);
349 test::stream ts
{ioc_
};
350 request_parser
<dynamic_body
> p
;
353 async_read(ts
, b
, p
, do_yield
[ec
]);
354 BEAST_EXPECT(ec
== http::error::end_of_stream
);
358 // Ensure completion handlers are not leaked
361 static std::atomic
<std::size_t>&
362 count() { static std::atomic
<std::size_t> n
; return n
; }
363 handler() { ++count(); }
364 ~handler() { --count(); }
365 handler(handler
const&) { ++count(); }
366 void operator()(error_code
const&, std::size_t) const {}
373 // Make sure handlers are not destroyed
374 // after calling io_context::stop
375 boost::asio::io_context ioc
;
377 "GET / HTTP/1.1\r\n\r\n"};
378 BEAST_EXPECT(handler::count() == 0);
380 request
<dynamic_body
> m
;
381 async_read(ts
, b
, m
, handler
{});
382 BEAST_EXPECT(handler::count() > 0);
384 BEAST_EXPECT(handler::count() > 0);
386 BEAST_EXPECT(handler::count() > 0);
388 BEAST_EXPECT(handler::count() == 0);
391 // Make sure uninvoked handlers are
392 // destroyed when calling ~io_context
394 boost::asio::io_context ioc
;
396 "GET / HTTP/1.1\r\n\r\n"};
397 BEAST_EXPECT(handler::count() == 0);
399 request
<dynamic_body
> m
;
400 async_read(ts
, b
, m
, handler
{});
401 BEAST_EXPECT(handler::count() > 0);
403 BEAST_EXPECT(handler::count() == 0);
407 // https://github.com/boostorg/beast/issues/430
411 test::stream ts
{ioc_
};
413 ostream(ts
.buffer()) <<
414 "HTTP/1.1 200 OK\r\n"
415 "Transfer-Encoding: chunked\r\n"
416 "Content-Type: application/octet-stream\r\n"
422 response_parser
<dynamic_body
> p
;
424 BEAST_EXPECTS(! ec
, ec
.message());
427 //--------------------------------------------------------------------------
429 template<class Parser
, class Pred
>
431 readgrind(string_view s
, Pred
&& pred
)
433 using boost::asio::buffer
;
434 for(std::size_t n
= 1; n
< s
.size() - 1; ++n
)
437 error_code ec
= test::error::fail_error
;
439 test::stream ts
{ioc_
};
440 ostream(ts
.buffer()) << s
;
443 if(! BEAST_EXPECTS(! ec
, ec
.message()))
452 readgrind
<test_parser
<false>>(
453 "HTTP/1.1 200 OK\r\n"
454 "Transfer-Encoding: chunked\r\n"
455 "Content-Type: application/octet-stream\r\n"
459 ,[&](test_parser
<false> const& p
)
461 BEAST_EXPECT(p
.body
== "abcd");
463 readgrind
<test_parser
<false>>(
464 "HTTP/1.1 200 OK\r\n"
466 "Expect: Expires, MD5-Fingerprint\r\n"
467 "Transfer-Encoding: chunked\r\n"
471 "2;a;b=1;c=\"2\"\r\n"
473 "0;d;e=3;f=\"4\"\r\n"
475 "MD5-Fingerprint: -\r\n"
477 ,[&](test_parser
<false> const& p
)
479 BEAST_EXPECT(p
.body
== "*****--");
487 testBufferOverflow();
489 yield_to([&](yield_context yield
)
493 yield_to([&](yield_context yield
)
497 yield_to([&](yield_context yield
)
508 BEAST_DEFINE_TESTSUITE(beast
,http
,read
);