]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/beast/http/fields.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / beast / test / beast / http / fields.cpp
1 //
2 // Copyright (c) 2016-2019 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/fields.hpp>
12
13 #include <boost/beast/http/empty_body.hpp>
14 #include <boost/beast/http/message.hpp>
15 #include <boost/beast/http/type_traits.hpp>
16 #include <boost/beast/test/test_allocator.hpp>
17 #include <boost/beast/_experimental/unit_test/suite.hpp>
18 #include <string>
19
20 namespace boost {
21 namespace beast {
22 namespace http {
23
24 class fields_test : public beast::unit_test::suite
25 {
26 public:
27 static constexpr std::size_t max_static_buffer =
28 sizeof(beast::detail::temporary_buffer);
29
30 template<class T>
31 class test_allocator
32 {
33 public:
34 using value_type = T;
35
36 test_allocator() noexcept(false) {}
37
38 template<class U, class = typename
39 std::enable_if<!std::is_same<test_allocator, U>::value>::type>
40 test_allocator(test_allocator<U> const&) noexcept {}
41
42 value_type*
43 allocate(std::size_t n)
44 {
45 return static_cast<value_type*>(::operator new (n*sizeof(value_type)));
46 }
47
48 void
49 deallocate(value_type* p, std::size_t) noexcept
50 {
51 ::operator delete(p);
52 }
53
54 template<class U>
55 friend
56 bool
57 operator==(test_allocator<T> const&, test_allocator<U> const&) noexcept
58 {
59 return true;
60 }
61
62 template<class U>
63 friend
64 bool
65 operator!=(test_allocator<T> const& x, test_allocator<U> const& y) noexcept
66 {
67 return !(x == y);
68 }
69 };
70
71 using test_fields = basic_fields<test_allocator<char>>;
72
73 BOOST_STATIC_ASSERT(is_fields<fields>::value);
74 BOOST_STATIC_ASSERT(is_fields<test_fields>::value);
75
76 // std::allocator is noexcept movable, fields should satisfy
77 // these constraints as well.
78 BOOST_STATIC_ASSERT(std::is_nothrow_move_constructible<fields>::value);
79 BOOST_STATIC_ASSERT(std::is_nothrow_move_assignable<fields>::value);
80
81 // Check if basic_fields respects throw-constructibility and
82 // propagate_on_container_move_assignment of the allocator.
83 BOOST_STATIC_ASSERT(std::is_nothrow_move_constructible<test_fields>::value);
84 BOOST_STATIC_ASSERT(!std::is_nothrow_move_assignable<test_fields>::value);
85
86 template<class Allocator>
87 using fa_t = basic_fields<Allocator>;
88
89 using f_t = fa_t<std::allocator<char>>;
90
91 template<class Allocator>
92 static
93 void
94 fill(std::size_t n, basic_fields<Allocator>& f)
95 {
96 for(std::size_t i = 1; i<= n; ++i)
97 f.insert(std::to_string(i), i);
98 }
99
100 template<class U, class V>
101 static
102 void
103 self_assign(U& u, V&& v)
104 {
105 u = std::forward<V>(v);
106 }
107
108 template<class Alloc>
109 static
110 bool
111 empty(basic_fields<Alloc> const& f)
112 {
113 return f.begin() == f.end();
114 }
115
116 template<class Alloc>
117 static
118 std::size_t
119 size(basic_fields<Alloc> const& f)
120 {
121 return std::distance(f.begin(), f.end());
122 }
123
124 void
125 testMembers()
126 {
127 using namespace test;
128
129 // compare equal
130 using equal_t = test::test_allocator<char,
131 true, true, true, true, true>;
132
133 // compare not equal
134 using unequal_t = test::test_allocator<char,
135 false, true, true, true, true>;
136
137 // construction
138 {
139 {
140 fields f;
141 BEAST_EXPECT(f.begin() == f.end());
142 }
143 {
144 unequal_t a1;
145 basic_fields<unequal_t> f{a1};
146 BEAST_EXPECT(f.get_allocator() == a1);
147 BEAST_EXPECT(f.get_allocator() != unequal_t{});
148 }
149 }
150
151 // move construction
152 {
153 {
154 basic_fields<equal_t> f1;
155 BEAST_EXPECT(f1.get_allocator()->nmove == 0);
156 f1.insert("1", "1");
157 BEAST_EXPECT(f1["1"] == "1");
158 basic_fields<equal_t> f2{std::move(f1)};
159 BEAST_EXPECT(f2.get_allocator()->nmove == 1);
160 BEAST_EXPECT(f2["1"] == "1");
161 BEAST_EXPECT(f1["1"] == "");
162 }
163 // allocators equal
164 {
165 basic_fields<equal_t> f1;
166 f1.insert("1", "1");
167 equal_t a;
168 basic_fields<equal_t> f2{std::move(f1), a};
169 BEAST_EXPECT(f2["1"] == "1");
170 BEAST_EXPECT(f1["1"] == "");
171 }
172 {
173 // allocators unequal
174 basic_fields<unequal_t> f1;
175 f1.insert("1", "1");
176 unequal_t a;
177 basic_fields<unequal_t> f2{std::move(f1), a};
178 BEAST_EXPECT(f2["1"] == "1");
179 }
180 }
181
182 // copy construction
183 {
184 {
185 basic_fields<equal_t> f1;
186 f1.insert("1", "1");
187 basic_fields<equal_t> f2{f1};
188 BEAST_EXPECT(f1.get_allocator() == f2.get_allocator());
189 BEAST_EXPECT(f1["1"] == "1");
190 BEAST_EXPECT(f2["1"] == "1");
191 }
192 {
193 basic_fields<unequal_t> f1;
194 f1.insert("1", "1");
195 unequal_t a;
196 basic_fields<unequal_t> f2(f1, a);
197 BEAST_EXPECT(f1.get_allocator() != f2.get_allocator());
198 BEAST_EXPECT(f1["1"] == "1");
199 BEAST_EXPECT(f2["1"] == "1");
200 }
201 {
202 basic_fields<equal_t> f1;
203 f1.insert("1", "1");
204 basic_fields<unequal_t> f2(f1);
205 BEAST_EXPECT(f1["1"] == "1");
206 BEAST_EXPECT(f2["1"] == "1");
207 }
208 {
209 basic_fields<unequal_t> f1;
210 f1.insert("1", "1");
211 equal_t a;
212 basic_fields<equal_t> f2(f1, a);
213 BEAST_EXPECT(f2.get_allocator() == a);
214 BEAST_EXPECT(f1["1"] == "1");
215 BEAST_EXPECT(f2["1"] == "1");
216 }
217 }
218
219 // move assignment
220 {
221 {
222 fields f1;
223 f1.insert("1", "1");
224 fields f2;
225 f2 = std::move(f1);
226 BEAST_EXPECT(f1.begin() == f1.end());
227 BEAST_EXPECT(f2["1"] == "1");
228 }
229 {
230 // propagate_on_container_move_assignment : true
231 using pocma_t = test::test_allocator<char,
232 true, true, true, true, true>;
233 basic_fields<pocma_t> f1;
234 f1.insert("1", "1");
235 basic_fields<pocma_t> f2;
236 f2 = std::move(f1);
237 BEAST_EXPECT(f1.begin() == f1.end());
238 BEAST_EXPECT(f2["1"] == "1");
239 }
240 {
241 // propagate_on_container_move_assignment : false
242 using pocma_t = test::test_allocator<char,
243 true, true, false, true, true>;
244 basic_fields<pocma_t> f1;
245 f1.insert("1", "1");
246 basic_fields<pocma_t> f2;
247 f2 = std::move(f1);
248 BEAST_EXPECT(f1.begin() == f1.end());
249 BEAST_EXPECT(f2["1"] == "1");
250 }
251 }
252
253 // copy assignment
254 {
255 {
256 fields f1;
257 f1.insert("1", "1");
258 fields f2;
259 f2 = f1;
260 BEAST_EXPECT(f1["1"] == "1");
261 BEAST_EXPECT(f2["1"] == "1");
262 basic_fields<equal_t> f3;
263 f3 = f2;
264 BEAST_EXPECT(f3["1"] == "1");
265 }
266 {
267 // propagate_on_container_copy_assignment : true
268 using pocca_t = test::test_allocator<char,
269 true, true, true, true, true>;
270 basic_fields<pocca_t> f1;
271 f1.insert("1", "1");
272 basic_fields<pocca_t> f2;
273 f2 = f1;
274 BEAST_EXPECT(f2["1"] == "1");
275 }
276 {
277 // propagate_on_container_copy_assignment : false
278 using pocca_t = test::test_allocator<char,
279 true, false, true, true, true>;
280 basic_fields<pocca_t> f1;
281 f1.insert("1", "1");
282 basic_fields<pocca_t> f2;
283 f2 = f1;
284 BEAST_EXPECT(f2["1"] == "1");
285 }
286 }
287
288 // swap
289 {
290 {
291 // propagate_on_container_swap : true
292 using pocs_t = test::test_allocator<char,
293 false, true, true, true, true>;
294 pocs_t a1, a2;
295 BEAST_EXPECT(a1 != a2);
296 basic_fields<pocs_t> f1{a1};
297 f1.insert("1", "1");
298 basic_fields<pocs_t> f2{a2};
299 BEAST_EXPECT(f1.get_allocator() == a1);
300 BEAST_EXPECT(f2.get_allocator() == a2);
301 swap(f1, f2);
302 BEAST_EXPECT(f1.get_allocator() == a2);
303 BEAST_EXPECT(f2.get_allocator() == a1);
304 BEAST_EXPECT(f1.begin() == f1.end());
305 BEAST_EXPECT(f2["1"] == "1");
306 swap(f1, f2);
307 BEAST_EXPECT(f1.get_allocator() == a1);
308 BEAST_EXPECT(f2.get_allocator() == a2);
309 BEAST_EXPECT(f1["1"] == "1");
310 BEAST_EXPECT(f2.begin() == f2.end());
311 }
312 {
313 // propagate_on_container_swap : false
314 using pocs_t = test::test_allocator<char,
315 true, true, true, false, true>;
316 pocs_t a1, a2;
317 BEAST_EXPECT(a1 == a2);
318 BEAST_EXPECT(a1.id() != a2.id());
319 basic_fields<pocs_t> f1{a1};
320 f1.insert("1", "1");
321 basic_fields<pocs_t> f2{a2};
322 BEAST_EXPECT(f1.get_allocator() == a1);
323 BEAST_EXPECT(f2.get_allocator() == a2);
324 swap(f1, f2);
325 BEAST_EXPECT(f1.get_allocator().id() == a1.id());
326 BEAST_EXPECT(f2.get_allocator().id() == a2.id());
327 BEAST_EXPECT(f1.begin() == f1.end());
328 BEAST_EXPECT(f2["1"] == "1");
329 swap(f1, f2);
330 BEAST_EXPECT(f1.get_allocator().id() == a1.id());
331 BEAST_EXPECT(f2.get_allocator().id() == a2.id());
332 BEAST_EXPECT(f1["1"] == "1");
333 BEAST_EXPECT(f2.begin() == f2.end());
334 }
335 }
336
337 // operations
338 {
339 fields f;
340 f.insert(field::user_agent, "x");
341 BEAST_EXPECT(f.count(field::user_agent));
342 BEAST_EXPECT(f.count(to_string(field::user_agent)));
343 BEAST_EXPECT(f.count(field::user_agent) == 1);
344 BEAST_EXPECT(f.count(to_string(field::user_agent)) == 1);
345 f.insert(field::user_agent, "y");
346 BEAST_EXPECT(f.count(field::user_agent) == 2);
347 }
348 }
349
350 void testHeaders()
351 {
352 f_t f1;
353 BEAST_EXPECT(empty(f1));
354 fill(1, f1);
355 BEAST_EXPECT(size(f1) == 1);
356 f_t f2;
357 f2 = f1;
358 BEAST_EXPECT(size(f2) == 1);
359 f2.insert("2", "2");
360 BEAST_EXPECT(std::distance(f2.begin(), f2.end()) == 2);
361 f1 = std::move(f2);
362 BEAST_EXPECT(size(f1) == 2);
363 BEAST_EXPECT(size(f2) == 0);
364 f_t f3(std::move(f1));
365 BEAST_EXPECT(size(f3) == 2);
366 BEAST_EXPECT(size(f1) == 0);
367 self_assign(f3, std::move(f3));
368 BEAST_EXPECT(size(f3) == 2);
369 BEAST_EXPECT(f2.erase("Not-Present") == 0);
370 }
371
372 void testRFC2616()
373 {
374 f_t f;
375 f.insert("a", "w");
376 f.insert("a", "x");
377 f.insert("aa", "y");
378 f.insert("f", "z");
379 BEAST_EXPECT(f.count("a") == 2);
380 }
381
382 void testErase()
383 {
384 f_t f;
385 f.insert("a", "w");
386 f.insert("a", "x");
387 f.insert("aa", "y");
388 f.insert("f", "z");
389 BEAST_EXPECT(size(f) == 4);
390 f.erase("a");
391 BEAST_EXPECT(size(f) == 2);
392 }
393
394 void testIteratorErase()
395 {
396 f_t f;
397 f.insert("a", "x");
398 f.insert("b", "y");
399 f.insert("c", "z");
400 BEAST_EXPECT(size(f) == 3);
401 f_t::const_iterator i = std::next(f.begin());
402 f.erase(i);
403 BEAST_EXPECT(size(f) == 2);
404 BEAST_EXPECT(std::next(f.begin(), 0)->name_string() == "a");
405 BEAST_EXPECT(std::next(f.begin(), 1)->name_string() == "c");
406 }
407
408 void
409 testContainer()
410 {
411 {
412 // group fields
413 fields f;
414 f.insert(field::age, 1);
415 f.insert(field::body, 2);
416 f.insert(field::close, 3);
417 f.insert(field::body, 4);
418 BEAST_EXPECT(std::next(f.begin(), 0)->name() == field::age);
419 BEAST_EXPECT(std::next(f.begin(), 1)->name() == field::body);
420 BEAST_EXPECT(std::next(f.begin(), 2)->name() == field::body);
421 BEAST_EXPECT(std::next(f.begin(), 3)->name() == field::close);
422 BEAST_EXPECT(std::next(f.begin(), 0)->name_string() == "Age");
423 BEAST_EXPECT(std::next(f.begin(), 1)->name_string() == "Body");
424 BEAST_EXPECT(std::next(f.begin(), 2)->name_string() == "Body");
425 BEAST_EXPECT(std::next(f.begin(), 3)->name_string() == "Close");
426 BEAST_EXPECT(std::next(f.begin(), 0)->value() == "1");
427 BEAST_EXPECT(std::next(f.begin(), 1)->value() == "2");
428 BEAST_EXPECT(std::next(f.begin(), 2)->value() == "4");
429 BEAST_EXPECT(std::next(f.begin(), 3)->value() == "3");
430 BEAST_EXPECT(f.erase(field::body) == 2);
431 BEAST_EXPECT(std::next(f.begin(), 0)->name_string() == "Age");
432 BEAST_EXPECT(std::next(f.begin(), 1)->name_string() == "Close");
433 }
434 {
435 // group fields, case insensitive
436 fields f;
437 f.insert("a", 1);
438 f.insert("ab", 2);
439 f.insert("b", 3);
440 f.insert("AB", 4);
441 BEAST_EXPECT(std::next(f.begin(), 0)->name() == field::unknown);
442 BEAST_EXPECT(std::next(f.begin(), 1)->name() == field::unknown);
443 BEAST_EXPECT(std::next(f.begin(), 2)->name() == field::unknown);
444 BEAST_EXPECT(std::next(f.begin(), 3)->name() == field::unknown);
445 BEAST_EXPECT(std::next(f.begin(), 0)->name_string() == "a");
446 BEAST_EXPECT(std::next(f.begin(), 1)->name_string() == "ab");
447 BEAST_EXPECT(std::next(f.begin(), 2)->name_string() == "AB");
448 BEAST_EXPECT(std::next(f.begin(), 3)->name_string() == "b");
449 BEAST_EXPECT(std::next(f.begin(), 0)->value() == "1");
450 BEAST_EXPECT(std::next(f.begin(), 1)->value() == "2");
451 BEAST_EXPECT(std::next(f.begin(), 2)->value() == "4");
452 BEAST_EXPECT(std::next(f.begin(), 3)->value() == "3");
453 BEAST_EXPECT(f.erase("Ab") == 2);
454 BEAST_EXPECT(std::next(f.begin(), 0)->name_string() == "a");
455 BEAST_EXPECT(std::next(f.begin(), 1)->name_string() == "b");
456 }
457 {
458 // verify insertion orde
459 fields f;
460 f.insert( "a", 1);
461 f.insert("dd", 2);
462 f.insert("b", 3);
463 f.insert("dD", 4);
464 f.insert("c", 5);
465 f.insert("Dd", 6);
466 f.insert("DD", 7);
467 f.insert( "e", 8);
468 BEAST_EXPECT(f.count("dd") == 4);
469 BEAST_EXPECT(std::next(f.begin(), 1)->name_string() == "dd");
470 BEAST_EXPECT(std::next(f.begin(), 2)->name_string() == "dD");
471 BEAST_EXPECT(std::next(f.begin(), 3)->name_string() == "Dd");
472 BEAST_EXPECT(std::next(f.begin(), 4)->name_string() == "DD");
473 f.set("dd", "-");
474 BEAST_EXPECT(f.count("dd") == 1);
475 BEAST_EXPECT(f["dd"] == "-");
476 }
477
478 // equal_range
479 {
480 fields f;
481 f.insert("E", 1);
482 f.insert("B", 2);
483 f.insert("D", 3);
484 f.insert("B", 4);
485 f.insert("C", 5);
486 f.insert("B", 6);
487 f.insert("A", 7);
488 auto const rng = f.equal_range("B");
489 BEAST_EXPECT(std::distance(rng.first, rng.second) == 3);
490 BEAST_EXPECT(std::next(rng.first, 0)->value() == "2");
491 BEAST_EXPECT(std::next(rng.first, 1)->value() == "4");
492 BEAST_EXPECT(std::next(rng.first, 2)->value() == "6");
493 }
494 }
495
496 struct sized_body
497 {
498 using value_type = std::uint64_t;
499
500 static
501 std::uint64_t
502 size(value_type const& v)
503 {
504 return v;
505 }
506 };
507
508 struct unsized_body
509 {
510 struct value_type {};
511 };
512
513 void
514 testPreparePayload()
515 {
516 // GET, empty
517 {
518 request<empty_body> req;
519 req.version(11);
520 req.method(verb::get);
521
522 req.prepare_payload();
523 BEAST_EXPECT(req.count(field::content_length) == 0);
524 BEAST_EXPECT(req.count(field::transfer_encoding) == 0);
525
526 req.set(field::content_length, "0");
527 req.set(field::transfer_encoding, "chunked");
528 req.prepare_payload();
529
530 BEAST_EXPECT(req.count(field::content_length) == 0);
531 BEAST_EXPECT(req.count(field::transfer_encoding) == 0);
532
533 req.set(field::transfer_encoding, "deflate");
534 req.prepare_payload();
535 BEAST_EXPECT(req.count(field::content_length) == 0);
536 BEAST_EXPECT(req[field::transfer_encoding] == "deflate");
537
538 req.set(field::transfer_encoding, "deflate, chunked");
539 req.prepare_payload();
540 BEAST_EXPECT(req.count(field::content_length) == 0);
541 BEAST_EXPECT(req[field::transfer_encoding] == "deflate");
542 }
543
544 // GET, sized
545 {
546 request<sized_body> req;
547 req.version(11);
548 req.method(verb::get);
549 req.body() = 50;
550
551 req.prepare_payload();
552 BEAST_EXPECT(req[field::content_length] == "50");
553 BEAST_EXPECT(req[field::transfer_encoding] == "");
554
555 req.set(field::content_length, "0");
556 req.set(field::transfer_encoding, "chunked");
557 req.prepare_payload();
558 BEAST_EXPECT(req[field::content_length] == "50");
559 BEAST_EXPECT(req.count(field::transfer_encoding) == 0);
560
561 req.set(field::transfer_encoding, "deflate, chunked");
562 req.prepare_payload();
563 BEAST_EXPECT(req[field::content_length] == "50");
564 BEAST_EXPECT(req[field::transfer_encoding] == "deflate");
565 }
566
567 // PUT, empty
568 {
569 request<empty_body> req;
570 req.version(11);
571 req.method(verb::put);
572
573 req.prepare_payload();
574 BEAST_EXPECT(req[field::content_length] == "0");
575 BEAST_EXPECT(req.count(field::transfer_encoding) == 0);
576
577 req.set(field::content_length, "50");
578 req.set(field::transfer_encoding, "deflate, chunked");
579 req.prepare_payload();
580 BEAST_EXPECT(req[field::content_length] == "0");
581 BEAST_EXPECT(req[field::transfer_encoding] == "deflate");
582 }
583
584 // PUT, sized
585 {
586 request<sized_body> req;
587 req.version(11);
588 req.method(verb::put);
589 req.body() = 50;
590
591 req.prepare_payload();
592 BEAST_EXPECT(req[field::content_length] == "50");
593 BEAST_EXPECT(req.count(field::transfer_encoding) == 0);
594
595 req.set(field::content_length, "25");
596 req.set(field::transfer_encoding, "deflate, chunked");
597 req.prepare_payload();
598 BEAST_EXPECT(req[field::content_length] == "50");
599 BEAST_EXPECT(req[field::transfer_encoding] == "deflate");
600 }
601
602 // POST, unsized
603 {
604 request<unsized_body> req;
605 req.version(11);
606 req.method(verb::post);
607
608 req.prepare_payload();
609 BEAST_EXPECT(req.count(field::content_length) == 0);
610 BEAST_EXPECT(req[field::transfer_encoding] == "chunked");
611
612 req.set(field::transfer_encoding, "deflate");
613 req.prepare_payload();
614 BEAST_EXPECT(req.count(field::content_length) == 0);
615 BEAST_EXPECT(req[field::transfer_encoding] == "deflate, chunked");
616 }
617
618 // POST, unsized HTTP/1.0
619 {
620 request<unsized_body> req;
621 req.version(10);
622 req.method(verb::post);
623
624 req.prepare_payload();
625 BEAST_EXPECT(req.count(field::content_length) == 0);
626 BEAST_EXPECT(req.count(field::transfer_encoding) == 0);
627
628 req.set(field::transfer_encoding, "deflate");
629 req.prepare_payload();
630 BEAST_EXPECT(req.count(field::content_length) == 0);
631 BEAST_EXPECT(req[field::transfer_encoding] == "deflate");
632 }
633
634 // OK, empty
635 {
636 response<empty_body> res;
637 res.version(11);
638
639 res.prepare_payload();
640 BEAST_EXPECT(res[field::content_length] == "0");
641 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
642
643 res.erase(field::content_length);
644 res.set(field::transfer_encoding, "chunked");
645 res.prepare_payload();
646 BEAST_EXPECT(res[field::content_length] == "0");
647 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
648 }
649
650 // OK, sized
651 {
652 response<sized_body> res;
653 res.version(11);
654 res.body() = 50;
655
656 res.prepare_payload();
657 BEAST_EXPECT(res[field::content_length] == "50");
658 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
659
660 res.erase(field::content_length);
661 res.set(field::transfer_encoding, "chunked");
662 res.prepare_payload();
663 BEAST_EXPECT(res[field::content_length] == "50");
664 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
665 }
666
667 // OK, unsized
668 {
669 response<unsized_body> res;
670 res.version(11);
671
672 res.prepare_payload();
673 BEAST_EXPECT(res.count(field::content_length) == 0);
674 BEAST_EXPECT(res[field::transfer_encoding] == "chunked");
675 }
676 }
677
678 void
679 testKeepAlive()
680 {
681 response<empty_body> res;
682 auto const keep_alive =
683 [&](bool v)
684 {
685 res.keep_alive(v);
686 BEAST_EXPECT(
687 (res.keep_alive() && v) ||
688 (! res.keep_alive() && ! v));
689 };
690
691 std::string const big(max_static_buffer + 1, 'a');
692
693 // HTTP/1.0
694 res.version(10);
695 res.erase(field::connection);
696
697 keep_alive(false);
698 BEAST_EXPECT(res.count(field::connection) == 0);
699
700 res.set(field::connection, "close");
701 keep_alive(false);
702 BEAST_EXPECT(res.count(field::connection) == 0);
703
704 res.set(field::connection, "keep-alive");
705 keep_alive(false);
706 BEAST_EXPECT(res.count(field::connection) == 0);
707
708 res.set(field::connection, "keep-alive, close");
709 keep_alive(false);
710 BEAST_EXPECT(res.count(field::connection) == 0);
711
712 res.erase(field::connection);
713 keep_alive(true);
714 BEAST_EXPECT(res[field::connection] == "keep-alive");
715
716 res.set(field::connection, "close");
717 keep_alive(true);
718 BEAST_EXPECT(res[field::connection] == "keep-alive");
719
720 res.set(field::connection, "keep-alive");
721 keep_alive(true);
722 BEAST_EXPECT(res[field::connection] == "keep-alive");
723
724 res.set(field::connection, "keep-alive, close");
725 keep_alive(true);
726 BEAST_EXPECT(res[field::connection] == "keep-alive");
727
728 auto const test10 =
729 [&](std::string s)
730 {
731 res.set(field::connection, s);
732 keep_alive(false);
733 BEAST_EXPECT(res[field::connection] == s);
734
735 res.set(field::connection, s + ", close");
736 keep_alive(false);
737 BEAST_EXPECT(res[field::connection] == s);
738
739 res.set(field::connection, "keep-alive, " + s);
740 keep_alive(false);
741 BEAST_EXPECT(res[field::connection] == s);
742
743 res.set(field::connection, "keep-alive, " + s + ", close");
744 keep_alive(false);
745 BEAST_EXPECT(res[field::connection] == s);
746
747 res.set(field::connection, s);
748 keep_alive(true);
749 BEAST_EXPECT(res[field::connection] == s + ", keep-alive");
750
751 res.set(field::connection, s + ", close");
752 keep_alive(true);
753 BEAST_EXPECT(res[field::connection] == s + ", keep-alive");
754
755 res.set(field::connection, "keep-alive, " + s);
756 keep_alive(true);
757 BEAST_EXPECT(res[field::connection] == "keep-alive, " + s);
758
759 res.set(field::connection, "keep-alive, " + s+ ", close");
760 keep_alive(true);
761 BEAST_EXPECT(res[field::connection] == "keep-alive, " + s);
762 };
763
764 test10("foo");
765 test10(big);
766
767 // HTTP/1.1
768 res.version(11);
769
770 res.erase(field::connection);
771 keep_alive(true);
772 BEAST_EXPECT(res.count(field::connection) == 0);
773
774 res.set(field::connection, "close");
775 keep_alive(true);
776 BEAST_EXPECT(res.count(field::connection) == 0);
777
778 res.set(field::connection, "keep-alive");
779 keep_alive(true);
780 BEAST_EXPECT(res.count(field::connection) == 0);
781
782 res.set(field::connection, "keep-alive, close");
783 keep_alive(true);
784 BEAST_EXPECT(res.count(field::connection) == 0);
785
786 res.erase(field::connection);
787 keep_alive(false);
788 BEAST_EXPECT(res[field::connection] == "close");
789
790 res.set(field::connection, "close");
791 keep_alive(false);
792 BEAST_EXPECT(res[field::connection] == "close");
793
794 res.set(field::connection, "keep-alive");
795 keep_alive(false);
796 BEAST_EXPECT(res[field::connection] == "close");
797
798 res.set(field::connection, "keep-alive, close");
799 keep_alive(false);
800 BEAST_EXPECT(res[field::connection] == "close");
801
802 auto const test11 =
803 [&](std::string s)
804 {
805 res.set(field::connection, s);
806 keep_alive(true);
807 BEAST_EXPECT(res[field::connection] == s);
808
809 res.set(field::connection, s + ", close");
810 keep_alive(true);
811 BEAST_EXPECT(res[field::connection] == s);
812
813 res.set(field::connection, "keep-alive, " + s);
814 keep_alive(true);
815 BEAST_EXPECT(res[field::connection] == s);
816
817 res.set(field::connection, "keep-alive, " + s + ", close");
818 keep_alive(true);
819 BEAST_EXPECT(res[field::connection] == s);
820
821 res.set(field::connection, s);
822 keep_alive(false);
823 BEAST_EXPECT(res[field::connection] == s + ", close");
824
825 res.set(field::connection, "close, " + s);
826 keep_alive(false);
827 BEAST_EXPECT(res[field::connection] == "close, " + s);
828
829 res.set(field::connection, "keep-alive, " + s);
830 keep_alive(false);
831 BEAST_EXPECT(res[field::connection] == s + ", close");
832
833 res.set(field::connection, "close, " + s + ", keep-alive");
834 keep_alive(false);
835 BEAST_EXPECT(res[field::connection] == "close, " + s);
836 };
837
838 test11("foo");
839 test11(big);
840 }
841
842 void
843 testContentLength()
844 {
845 response<empty_body> res{status::ok, 11};
846 BEAST_EXPECT(res.count(field::content_length) == 0);
847 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
848
849 res.content_length(0);
850 BEAST_EXPECT(res[field::content_length] == "0");
851
852 res.content_length(100);
853 BEAST_EXPECT(res[field::content_length] == "100");
854
855 res.content_length(boost::none);
856 BEAST_EXPECT(res.count(field::content_length) == 0);
857
858 res.set(field::transfer_encoding, "chunked");
859 res.content_length(0);
860 BEAST_EXPECT(res[field::content_length] == "0");
861 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
862
863 res.set(field::transfer_encoding, "chunked");
864 res.content_length(100);
865 BEAST_EXPECT(res[field::content_length] == "100");
866 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
867
868 res.set(field::transfer_encoding, "chunked");
869 res.content_length(boost::none);
870 BEAST_EXPECT(res.count(field::content_length) == 0);
871 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
872
873 auto const check = [&](std::string s)
874 {
875 res.set(field::transfer_encoding, s);
876 res.content_length(0);
877 BEAST_EXPECT(res[field::content_length] == "0");
878 BEAST_EXPECT(res[field::transfer_encoding] == s);
879
880 res.set(field::transfer_encoding, s);
881 res.content_length(100);
882 BEAST_EXPECT(res[field::content_length] == "100");
883 BEAST_EXPECT(res[field::transfer_encoding] == s);
884
885 res.set(field::transfer_encoding, s);
886 res.content_length(boost::none);
887 BEAST_EXPECT(res.count(field::content_length) == 0);
888 BEAST_EXPECT(res[field::transfer_encoding] == s);
889
890 res.set(field::transfer_encoding, s + ", chunked");
891 res.content_length(0);
892 BEAST_EXPECT(res[field::content_length] == "0");
893 BEAST_EXPECT(res[field::transfer_encoding] == s);
894
895 res.set(field::transfer_encoding, s + ", chunked");
896 res.content_length(100);
897 BEAST_EXPECT(res[field::content_length] == "100");
898 BEAST_EXPECT(res[field::transfer_encoding] == s);
899
900 res.set(field::transfer_encoding, s + ", chunked");
901 res.content_length(boost::none);
902 BEAST_EXPECT(res.count(field::content_length) == 0);
903 BEAST_EXPECT(res[field::transfer_encoding] == s);
904
905 res.set(field::transfer_encoding, "chunked, " + s);
906 res.content_length(0);
907 BEAST_EXPECT(res[field::content_length] == "0");
908 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, " + s);
909
910 res.set(field::transfer_encoding, "chunked, " + s);
911 res.content_length(100);
912 BEAST_EXPECT(res[field::content_length] == "100");
913 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, " + s);
914
915 res.set(field::transfer_encoding, "chunked, " + s);
916 res.content_length(boost::none);
917 BEAST_EXPECT(res.count(field::content_length) == 0);
918 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, " + s);
919 };
920
921 check("foo");
922
923 std::string const big(max_static_buffer + 1, 'a');
924
925 check(big);
926 }
927
928 void
929 testChunked()
930 {
931 response<empty_body> res{status::ok, 11};
932 BEAST_EXPECT(res.count(field::content_length) == 0);
933 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
934
935 auto const chunked =
936 [&](bool v)
937 {
938 res.chunked(v);
939 BEAST_EXPECT(
940 (res.chunked() && v) ||
941 (! res.chunked() && ! v));
942 BEAST_EXPECT(res.count(
943 field::content_length) == 0);
944 };
945
946 res.erase(field::transfer_encoding);
947 res.set(field::content_length, 32);
948 chunked(true);
949 BEAST_EXPECT(res[field::transfer_encoding] == "chunked");
950
951 res.set(field::transfer_encoding, "chunked");
952 chunked(true);
953 BEAST_EXPECT(res[field::transfer_encoding] == "chunked");
954
955 res.erase(field::transfer_encoding);
956 res.set(field::content_length, 32);
957 chunked(false);
958 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
959
960 res.set(field::transfer_encoding, "chunked");
961 chunked(false);
962 BEAST_EXPECT(res.count(field::transfer_encoding) == 0);
963
964
965
966 res.set(field::transfer_encoding, "foo");
967 chunked(true);
968 BEAST_EXPECT(res[field::transfer_encoding] == "foo, chunked");
969
970 res.set(field::transfer_encoding, "chunked, foo");
971 chunked(true);
972 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, foo, chunked");
973
974 res.set(field::transfer_encoding, "chunked, foo, chunked");
975 chunked(true);
976 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, foo, chunked");
977
978 res.set(field::transfer_encoding, "foo, chunked");
979 chunked(false);
980 BEAST_EXPECT(res[field::transfer_encoding] == "foo");
981
982 res.set(field::transfer_encoding, "chunked, foo");
983 chunked(false);
984 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, foo");
985
986 res.set(field::transfer_encoding, "chunked, foo, chunked");
987 chunked(false);
988 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, foo");
989 }
990
991 void
992 run() override
993 {
994 testMembers();
995 testHeaders();
996 testRFC2616();
997 testErase();
998 testIteratorErase();
999 testContainer();
1000 testPreparePayload();
1001
1002 testKeepAlive();
1003 testContentLength();
1004 testChunked();
1005 }
1006 };
1007
1008 BEAST_DEFINE_TESTSUITE(beast,http,fields);
1009
1010 } // http
1011 } // beast
1012 } // boost