]>
git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/test/http/read.cpp
2 // Copyright (c) 2013-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)
8 // Test that header file is self-contained.
9 #include <beast/http/read.hpp>
11 #include "test_parser.hpp"
13 #include <beast/http/fields.hpp>
14 #include <beast/http/header_parser.hpp>
15 #include <beast/http/streambuf_body.hpp>
16 #include <beast/http/string_body.hpp>
17 #include <beast/test/fail_stream.hpp>
18 #include <beast/test/string_istream.hpp>
19 #include <beast/test/yield_to.hpp>
20 #include <beast/unit_test/suite.hpp>
21 #include <boost/asio/spawn.hpp>
28 : public beast::unit_test::suite
29 , public test::enable_yield_to
32 template<bool isRequest
>
34 failMatrix(char const* s
, yield_context do_yield
)
36 using boost::asio::buffer
;
37 using boost::asio::buffer_copy
;
38 static std::size_t constexpr limit
= 100;
40 auto const len
= strlen(s
);
41 for(n
= 0; n
< limit
; ++n
)
44 sb
.commit(buffer_copy(
45 sb
.prepare(len
), buffer(s
, len
)));
46 test::fail_counter
fc(n
);
48 test::string_istream
> fs
{fc
, ios_
, ""};
49 test_parser
<isRequest
> p(fc
);
55 BEAST_EXPECT(n
< limit
);
56 for(n
= 0; n
< limit
; ++n
)
58 static std::size_t constexpr pre
= 10;
60 sb
.commit(buffer_copy(
61 sb
.prepare(pre
), buffer(s
, pre
)));
62 test::fail_counter
fc(n
);
63 test::fail_stream
<test::string_istream
> fs
{
64 fc
, ios_
, std::string
{s
+ pre
, len
- pre
}};
65 test_parser
<isRequest
> p(fc
);
71 BEAST_EXPECT(n
< limit
);
72 for(n
= 0; n
< limit
; ++n
)
75 sb
.commit(buffer_copy(
76 sb
.prepare(len
), buffer(s
, len
)));
77 test::fail_counter
fc(n
);
79 test::string_istream
> fs
{fc
, ios_
, ""};
80 test_parser
<isRequest
> p(fc
);
82 async_read(fs
, sb
, p
, do_yield
[ec
]);
86 BEAST_EXPECT(n
< limit
);
87 for(n
= 0; n
< limit
; ++n
)
89 static std::size_t constexpr pre
= 10;
91 sb
.commit(buffer_copy(
92 sb
.prepare(pre
), buffer(s
, pre
)));
93 test::fail_counter
fc(n
);
94 test::fail_stream
<test::string_istream
> fs
{
95 fc
, ios_
, std::string
{s
+ pre
, len
- pre
}};
96 test_parser
<isRequest
> p(fc
);
98 async_read(fs
, sb
, p
, do_yield
[ec
]);
102 BEAST_EXPECT(n
< limit
);
110 test::string_istream
ss(ios_
, "GET / X");
111 message_parser
<true, streambuf_body
, fields
> p
;
115 catch(std::exception
const&)
121 void testFailures(yield_context do_yield
)
123 char const* req
[] = {
125 "Host: localhost\r\n"
126 "User-Agent: test\r\n"
131 "Host: localhost\r\n"
132 "User-Agent: test\r\n"
133 "Content-Length: 2\r\n"
138 "Host: localhost\r\n"
139 "User-Agent: test\r\n"
140 "Transfer-Encoding: chunked\r\n"
143 "****************\r\n"
149 char const* res
[] = {
150 "HTTP/1.0 200 OK\r\n"
154 "HTTP/1.0 200 OK\r\n"
159 "HTTP/1.1 200 OK\r\n"
161 "Content-Length: 3\r\n"
165 "HTTP/1.1 200 OK\r\n"
167 "Transfer-Encoding: chunked\r\n"
170 "****************\r\n"
176 for(std::size_t i
= 0; req
[i
]; ++i
)
177 failMatrix
<true>(req
[i
], do_yield
);
179 for(std::size_t i
= 0; res
[i
]; ++i
)
180 failMatrix
<false>(res
[i
], do_yield
);
183 void testRead(yield_context do_yield
)
185 static std::size_t constexpr limit
= 100;
188 for(n
= 0; n
< limit
; ++n
)
190 test::fail_stream
<test::string_istream
> fs(n
, ios_
,
192 "Host: localhost\r\n"
193 "User-Agent: test\r\n"
194 "Content-Length: 0\r\n"
197 request
<streambuf_body
> m
;
204 catch(std::exception
const&)
208 BEAST_EXPECT(n
< limit
);
210 for(n
= 0; n
< limit
; ++n
)
212 test::fail_stream
<test::string_istream
> fs(n
, ios_
,
214 "Host: localhost\r\n"
215 "User-Agent: test\r\n"
216 "Content-Length: 0\r\n"
219 request
<streambuf_body
> m
;
226 BEAST_EXPECT(n
< limit
);
228 for(n
= 0; n
< limit
; ++n
)
230 test::fail_stream
<test::string_istream
> fs(n
, ios_
,
232 "Host: localhost\r\n"
233 "User-Agent: test\r\n"
234 "Content-Length: 0\r\n"
237 request
<streambuf_body
> m
;
240 async_read(fs
, sb
, m
, do_yield
[ec
]);
244 BEAST_EXPECT(n
< limit
);
248 testEof(yield_context do_yield
)
252 test::string_istream
ss(ios_
, "");
253 message_parser
<true, streambuf_body
, fields
> p
;
256 BEAST_EXPECT(ec
== boost::asio::error::eof
);
260 test::string_istream
ss(ios_
, "");
261 message_parser
<true, streambuf_body
, fields
> p
;
263 async_read(ss
, sb
, p
, do_yield
[ec
]);
264 BEAST_EXPECT(ec
== boost::asio::error::eof
);
268 // Ensure completion handlers are not leaked
271 static std::atomic
<std::size_t>&
272 count() { static std::atomic
<std::size_t> n
; return n
; }
273 handler() { ++count(); }
274 ~handler() { --count(); }
275 handler(handler
const&) { ++count(); }
276 void operator()(error_code
const&) const {}
283 // Make sure handlers are not destroyed
284 // after calling io_service::stop
285 boost::asio::io_service ios
;
286 test::string_istream is
{ios
,
287 "GET / HTTP/1.1\r\n\r\n"};
288 BEAST_EXPECT(handler::count() == 0);
290 message
<true, streambuf_body
, fields
> m
;
291 async_read(is
, sb
, m
, handler
{});
292 BEAST_EXPECT(handler::count() > 0);
294 BEAST_EXPECT(handler::count() > 0);
296 BEAST_EXPECT(handler::count() > 0);
298 BEAST_EXPECT(handler::count() == 0);
301 // Make sure uninvoked handlers are
302 // destroyed when calling ~io_service
304 boost::asio::io_service ios
;
305 test::string_istream is
{ios
,
306 "GET / HTTP/1.1\r\n\r\n"};
307 BEAST_EXPECT(handler::count() == 0);
309 message
<true, streambuf_body
, fields
> m
;
310 async_read(is
, sb
, m
, handler
{});
311 BEAST_EXPECT(handler::count() > 0);
313 BEAST_EXPECT(handler::count() == 0);
322 yield_to(&read_test::testFailures
, this);
323 yield_to(&read_test::testRead
, this);
324 yield_to(&read_test::testEof
, this);
330 BEAST_DEFINE_TESTSUITE(read
,http
,beast
);