2 // Copyright (c) 2016-2019 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/fields.hpp>
13 #include <boost/beast/core/static_string.hpp>
14 #include <boost/beast/http/empty_body.hpp>
15 #include <boost/beast/http/message.hpp>
16 #include <boost/beast/http/type_traits.hpp>
17 #include <boost/beast/test/test_allocator.hpp>
18 #include <boost/beast/_experimental/unit_test/suite.hpp>
25 class fields_test
: public beast::unit_test::suite
28 static constexpr std::size_t max_static_buffer
=
29 sizeof(beast::detail::temporary_buffer
);
37 test_allocator() noexcept(false) {}
39 template<class U
, class = typename
40 std::enable_if
<!std::is_same
<test_allocator
, U
>::value
>::type
>
41 test_allocator(test_allocator
<U
> const&) noexcept
{}
44 allocate(std::size_t n
)
46 return static_cast<value_type
*>(::operator new (n
*sizeof(value_type
)));
50 deallocate(value_type
* p
, std::size_t) noexcept
58 operator==(test_allocator
<T
> const&, test_allocator
<U
> const&) noexcept
66 operator!=(test_allocator
<T
> const& x
, test_allocator
<U
> const& y
) noexcept
72 using test_fields
= basic_fields
<test_allocator
<char>>;
74 BOOST_STATIC_ASSERT(is_fields
<fields
>::value
);
75 BOOST_STATIC_ASSERT(is_fields
<test_fields
>::value
);
77 // std::allocator is noexcept movable, fields should satisfy
78 // these constraints as well.
79 BOOST_STATIC_ASSERT(std::is_nothrow_move_constructible
<fields
>::value
);
80 BOOST_STATIC_ASSERT(std::is_nothrow_move_assignable
<fields
>::value
);
82 // Check if basic_fields respects throw-constructibility and
83 // propagate_on_container_move_assignment of the allocator.
84 BOOST_STATIC_ASSERT(std::is_nothrow_move_constructible
<test_fields
>::value
);
85 BOOST_STATIC_ASSERT(!std::is_nothrow_move_assignable
<test_fields
>::value
);
87 template<class Allocator
>
88 using fa_t
= basic_fields
<Allocator
>;
90 using f_t
= fa_t
<std::allocator
<char>>;
92 template<class Allocator
>
95 fill(std::size_t n
, basic_fields
<Allocator
>& f
)
97 for(std::size_t i
= 1; i
<= n
; ++i
)
98 f
.insert(std::to_string(i
), to_static_string(i
));
101 template<class U
, class V
>
104 self_assign(U
& u
, V
&& v
)
106 u
= std::forward
<V
>(v
);
109 template<class Alloc
>
112 empty(basic_fields
<Alloc
> const& f
)
114 return f
.begin() == f
.end();
117 template<class Alloc
>
120 size(basic_fields
<Alloc
> const& f
)
122 return std::distance(f
.begin(), f
.end());
128 using namespace test
;
131 using equal_t
= test::test_allocator
<char,
132 true, true, true, true, true>;
135 using unequal_t
= test::test_allocator
<char,
136 false, true, true, true, true>;
142 BEAST_EXPECT(f
.begin() == f
.end());
146 basic_fields
<unequal_t
> f
{a1
};
147 BEAST_EXPECT(f
.get_allocator() == a1
);
148 BEAST_EXPECT(f
.get_allocator() != unequal_t
{});
155 basic_fields
<equal_t
> f1
;
156 BEAST_EXPECT(f1
.get_allocator()->nmove
== 0);
158 BEAST_EXPECT(f1
["1"] == "1");
159 basic_fields
<equal_t
> f2
{std::move(f1
)};
160 BEAST_EXPECT(f2
.get_allocator()->nmove
== 1);
161 BEAST_EXPECT(f2
["1"] == "1");
162 BEAST_EXPECT(f1
["1"] == "");
166 basic_fields
<equal_t
> f1
;
169 basic_fields
<equal_t
> f2
{std::move(f1
), a
};
170 BEAST_EXPECT(f2
["1"] == "1");
171 BEAST_EXPECT(f1
["1"] == "");
174 // allocators unequal
175 basic_fields
<unequal_t
> f1
;
178 basic_fields
<unequal_t
> f2
{std::move(f1
), a
};
179 BEAST_EXPECT(f2
["1"] == "1");
186 basic_fields
<equal_t
> f1
;
188 basic_fields
<equal_t
> f2
{f1
};
189 BEAST_EXPECT(f1
.get_allocator() == f2
.get_allocator());
190 BEAST_EXPECT(f1
["1"] == "1");
191 BEAST_EXPECT(f2
["1"] == "1");
194 basic_fields
<unequal_t
> f1
;
197 basic_fields
<unequal_t
> f2(f1
, a
);
198 BEAST_EXPECT(f1
.get_allocator() != f2
.get_allocator());
199 BEAST_EXPECT(f1
["1"] == "1");
200 BEAST_EXPECT(f2
["1"] == "1");
203 basic_fields
<equal_t
> f1
;
205 basic_fields
<unequal_t
> f2(f1
);
206 BEAST_EXPECT(f1
["1"] == "1");
207 BEAST_EXPECT(f2
["1"] == "1");
210 basic_fields
<unequal_t
> f1
;
213 basic_fields
<equal_t
> f2(f1
, a
);
214 BEAST_EXPECT(f2
.get_allocator() == a
);
215 BEAST_EXPECT(f1
["1"] == "1");
216 BEAST_EXPECT(f2
["1"] == "1");
227 BEAST_EXPECT(f1
.begin() == f1
.end());
228 BEAST_EXPECT(f2
["1"] == "1");
231 // propagate_on_container_move_assignment : true
232 using pocma_t
= test::test_allocator
<char,
233 true, true, true, true, true>;
234 basic_fields
<pocma_t
> f1
;
236 basic_fields
<pocma_t
> f2
;
238 BEAST_EXPECT(f1
.begin() == f1
.end());
239 BEAST_EXPECT(f2
["1"] == "1");
242 // propagate_on_container_move_assignment : false
243 using pocma_t
= test::test_allocator
<char,
244 true, true, false, true, true>;
245 basic_fields
<pocma_t
> f1
;
247 basic_fields
<pocma_t
> f2
;
249 BEAST_EXPECT(f1
.begin() == f1
.end());
250 BEAST_EXPECT(f2
["1"] == "1");
261 BEAST_EXPECT(f1
["1"] == "1");
262 BEAST_EXPECT(f2
["1"] == "1");
263 basic_fields
<equal_t
> f3
;
265 BEAST_EXPECT(f3
["1"] == "1");
268 // propagate_on_container_copy_assignment : true
269 using pocca_t
= test::test_allocator
<char,
270 true, true, true, true, true>;
271 basic_fields
<pocca_t
> f1
;
273 basic_fields
<pocca_t
> f2
;
275 BEAST_EXPECT(f2
["1"] == "1");
278 // propagate_on_container_copy_assignment : false
279 using pocca_t
= test::test_allocator
<char,
280 true, false, true, true, true>;
281 basic_fields
<pocca_t
> f1
;
283 basic_fields
<pocca_t
> f2
;
285 BEAST_EXPECT(f2
["1"] == "1");
292 // propagate_on_container_swap : true
293 using pocs_t
= test::test_allocator
<char,
294 false, true, true, true, true>;
296 BEAST_EXPECT(a1
!= a2
);
297 basic_fields
<pocs_t
> f1
{a1
};
299 basic_fields
<pocs_t
> f2
{a2
};
300 BEAST_EXPECT(f1
.get_allocator() == a1
);
301 BEAST_EXPECT(f2
.get_allocator() == a2
);
303 BEAST_EXPECT(f1
.get_allocator() == a2
);
304 BEAST_EXPECT(f2
.get_allocator() == a1
);
305 BEAST_EXPECT(f1
.begin() == f1
.end());
306 BEAST_EXPECT(f2
["1"] == "1");
308 BEAST_EXPECT(f1
.get_allocator() == a1
);
309 BEAST_EXPECT(f2
.get_allocator() == a2
);
310 BEAST_EXPECT(f1
["1"] == "1");
311 BEAST_EXPECT(f2
.begin() == f2
.end());
314 // propagate_on_container_swap : false
315 using pocs_t
= test::test_allocator
<char,
316 true, true, true, false, true>;
318 BEAST_EXPECT(a1
== a2
);
319 BEAST_EXPECT(a1
.id() != a2
.id());
320 basic_fields
<pocs_t
> f1
{a1
};
322 basic_fields
<pocs_t
> f2
{a2
};
323 BEAST_EXPECT(f1
.get_allocator() == a1
);
324 BEAST_EXPECT(f2
.get_allocator() == a2
);
326 BEAST_EXPECT(f1
.get_allocator().id() == a1
.id());
327 BEAST_EXPECT(f2
.get_allocator().id() == a2
.id());
328 BEAST_EXPECT(f1
.begin() == f1
.end());
329 BEAST_EXPECT(f2
["1"] == "1");
331 BEAST_EXPECT(f1
.get_allocator().id() == a1
.id());
332 BEAST_EXPECT(f2
.get_allocator().id() == a2
.id());
333 BEAST_EXPECT(f1
["1"] == "1");
334 BEAST_EXPECT(f2
.begin() == f2
.end());
341 f
.insert(field::user_agent
, "x");
342 BEAST_EXPECT(f
.count(field::user_agent
));
343 BEAST_EXPECT(f
.count(to_string(field::user_agent
)));
344 BEAST_EXPECT(f
.count(field::user_agent
) == 1);
345 BEAST_EXPECT(f
.count(to_string(field::user_agent
)) == 1);
346 f
.insert(field::user_agent
, "y");
347 BEAST_EXPECT(f
.count(field::user_agent
) == 2);
354 BEAST_EXPECT(empty(f1
));
356 BEAST_EXPECT(size(f1
) == 1);
359 BEAST_EXPECT(size(f2
) == 1);
361 BEAST_EXPECT(std::distance(f2
.begin(), f2
.end()) == 2);
363 BEAST_EXPECT(size(f1
) == 2);
364 BEAST_EXPECT(size(f2
) == 0);
365 f_t
f3(std::move(f1
));
366 BEAST_EXPECT(size(f3
) == 2);
367 BEAST_EXPECT(size(f1
) == 0);
368 self_assign(f3
, std::move(f3
));
369 BEAST_EXPECT(size(f3
) == 2);
370 BEAST_EXPECT(f2
.erase("Not-Present") == 0);
380 BEAST_EXPECT(f
.count("a") == 2);
390 BEAST_EXPECT(size(f
) == 4);
392 BEAST_EXPECT(size(f
) == 2);
395 void testIteratorErase()
401 BEAST_EXPECT(size(f
) == 3);
402 f_t::const_iterator i
= std::next(f
.begin());
404 BEAST_EXPECT(size(f
) == 2);
405 BEAST_EXPECT(std::next(f
.begin(), 0)->name_string() == "a");
406 BEAST_EXPECT(std::next(f
.begin(), 1)->name_string() == "c");
415 f
.insert(field::age
, to_static_string(1));
416 f
.insert(field::body
, to_static_string(2));
417 f
.insert(field::close
, to_static_string(3));
418 f
.insert(field::body
, to_static_string(4));
419 BEAST_EXPECT(std::next(f
.begin(), 0)->name() == field::age
);
420 BEAST_EXPECT(std::next(f
.begin(), 1)->name() == field::body
);
421 BEAST_EXPECT(std::next(f
.begin(), 2)->name() == field::body
);
422 BEAST_EXPECT(std::next(f
.begin(), 3)->name() == field::close
);
423 BEAST_EXPECT(std::next(f
.begin(), 0)->name_string() == "Age");
424 BEAST_EXPECT(std::next(f
.begin(), 1)->name_string() == "Body");
425 BEAST_EXPECT(std::next(f
.begin(), 2)->name_string() == "Body");
426 BEAST_EXPECT(std::next(f
.begin(), 3)->name_string() == "Close");
427 BEAST_EXPECT(std::next(f
.begin(), 0)->value() == "1");
428 BEAST_EXPECT(std::next(f
.begin(), 1)->value() == "2");
429 BEAST_EXPECT(std::next(f
.begin(), 2)->value() == "4");
430 BEAST_EXPECT(std::next(f
.begin(), 3)->value() == "3");
431 BEAST_EXPECT(f
.erase(field::body
) == 2);
432 BEAST_EXPECT(std::next(f
.begin(), 0)->name_string() == "Age");
433 BEAST_EXPECT(std::next(f
.begin(), 1)->name_string() == "Close");
436 // group fields, case insensitive
438 f
.insert("a", to_static_string(1));
439 f
.insert("ab", to_static_string(2));
440 f
.insert("b", to_static_string(3));
441 f
.insert("AB", to_static_string(4));
442 BEAST_EXPECT(std::next(f
.begin(), 0)->name() == field::unknown
);
443 BEAST_EXPECT(std::next(f
.begin(), 1)->name() == field::unknown
);
444 BEAST_EXPECT(std::next(f
.begin(), 2)->name() == field::unknown
);
445 BEAST_EXPECT(std::next(f
.begin(), 3)->name() == field::unknown
);
446 BEAST_EXPECT(std::next(f
.begin(), 0)->name_string() == "a");
447 BEAST_EXPECT(std::next(f
.begin(), 1)->name_string() == "ab");
448 BEAST_EXPECT(std::next(f
.begin(), 2)->name_string() == "AB");
449 BEAST_EXPECT(std::next(f
.begin(), 3)->name_string() == "b");
450 BEAST_EXPECT(std::next(f
.begin(), 0)->value() == "1");
451 BEAST_EXPECT(std::next(f
.begin(), 1)->value() == "2");
452 BEAST_EXPECT(std::next(f
.begin(), 2)->value() == "4");
453 BEAST_EXPECT(std::next(f
.begin(), 3)->value() == "3");
454 BEAST_EXPECT(f
.erase("Ab") == 2);
455 BEAST_EXPECT(std::next(f
.begin(), 0)->name_string() == "a");
456 BEAST_EXPECT(std::next(f
.begin(), 1)->name_string() == "b");
459 // verify insertion orde
461 f
.insert( "a", to_static_string(1));
462 f
.insert("dd", to_static_string(2));
463 f
.insert("b", to_static_string(3));
464 f
.insert("dD", to_static_string(4));
465 f
.insert("c", to_static_string(5));
466 f
.insert("Dd", to_static_string(6));
467 f
.insert("DD", to_static_string(7));
468 f
.insert( "e", to_static_string(8));
469 BEAST_EXPECT(f
.count("dd") == 4);
470 BEAST_EXPECT(std::next(f
.begin(), 1)->name_string() == "dd");
471 BEAST_EXPECT(std::next(f
.begin(), 2)->name_string() == "dD");
472 BEAST_EXPECT(std::next(f
.begin(), 3)->name_string() == "Dd");
473 BEAST_EXPECT(std::next(f
.begin(), 4)->name_string() == "DD");
475 BEAST_EXPECT(f
.count("dd") == 1);
476 BEAST_EXPECT(f
["dd"] == "-");
482 f
.insert("E", to_static_string(1));
483 f
.insert("B", to_static_string(2));
484 f
.insert("D", to_static_string(3));
485 f
.insert("B", to_static_string(4));
486 f
.insert("C", to_static_string(5));
487 f
.insert("B", to_static_string(6));
488 f
.insert("A", to_static_string(7));
489 auto const rng
= f
.equal_range("B");
490 BEAST_EXPECT(std::distance(rng
.first
, rng
.second
) == 3);
491 BEAST_EXPECT(std::next(rng
.first
, 0)->value() == "2");
492 BEAST_EXPECT(std::next(rng
.first
, 1)->value() == "4");
493 BEAST_EXPECT(std::next(rng
.first
, 2)->value() == "6");
499 using value_type
= std::uint64_t;
503 size(value_type
const& v
)
511 struct value_type
{};
519 request
<empty_body
> req
;
521 req
.method(verb::get
);
523 req
.prepare_payload();
524 BEAST_EXPECT(req
.count(field::content_length
) == 0);
525 BEAST_EXPECT(req
.count(field::transfer_encoding
) == 0);
527 req
.set(field::content_length
, "0");
528 req
.set(field::transfer_encoding
, "chunked");
529 req
.prepare_payload();
531 BEAST_EXPECT(req
.count(field::content_length
) == 0);
532 BEAST_EXPECT(req
.count(field::transfer_encoding
) == 0);
534 req
.set(field::transfer_encoding
, "deflate");
535 req
.prepare_payload();
536 BEAST_EXPECT(req
.count(field::content_length
) == 0);
537 BEAST_EXPECT(req
[field::transfer_encoding
] == "deflate");
539 req
.set(field::transfer_encoding
, "deflate, chunked");
540 req
.prepare_payload();
541 BEAST_EXPECT(req
.count(field::content_length
) == 0);
542 BEAST_EXPECT(req
[field::transfer_encoding
] == "deflate");
547 request
<sized_body
> req
;
549 req
.method(verb::get
);
552 req
.prepare_payload();
553 BEAST_EXPECT(req
[field::content_length
] == "50");
554 BEAST_EXPECT(req
[field::transfer_encoding
] == "");
556 req
.set(field::content_length
, "0");
557 req
.set(field::transfer_encoding
, "chunked");
558 req
.prepare_payload();
559 BEAST_EXPECT(req
[field::content_length
] == "50");
560 BEAST_EXPECT(req
.count(field::transfer_encoding
) == 0);
562 req
.set(field::transfer_encoding
, "deflate, chunked");
563 req
.prepare_payload();
564 BEAST_EXPECT(req
[field::content_length
] == "50");
565 BEAST_EXPECT(req
[field::transfer_encoding
] == "deflate");
570 request
<empty_body
> req
;
572 req
.method(verb::put
);
574 req
.prepare_payload();
575 BEAST_EXPECT(req
[field::content_length
] == "0");
576 BEAST_EXPECT(req
.count(field::transfer_encoding
) == 0);
578 req
.set(field::content_length
, "50");
579 req
.set(field::transfer_encoding
, "deflate, chunked");
580 req
.prepare_payload();
581 BEAST_EXPECT(req
[field::content_length
] == "0");
582 BEAST_EXPECT(req
[field::transfer_encoding
] == "deflate");
587 request
<sized_body
> req
;
589 req
.method(verb::put
);
592 req
.prepare_payload();
593 BEAST_EXPECT(req
[field::content_length
] == "50");
594 BEAST_EXPECT(req
.count(field::transfer_encoding
) == 0);
596 req
.set(field::content_length
, "25");
597 req
.set(field::transfer_encoding
, "deflate, chunked");
598 req
.prepare_payload();
599 BEAST_EXPECT(req
[field::content_length
] == "50");
600 BEAST_EXPECT(req
[field::transfer_encoding
] == "deflate");
605 request
<unsized_body
> req
;
607 req
.method(verb::post
);
609 req
.prepare_payload();
610 BEAST_EXPECT(req
.count(field::content_length
) == 0);
611 BEAST_EXPECT(req
[field::transfer_encoding
] == "chunked");
613 req
.set(field::transfer_encoding
, "deflate");
614 req
.prepare_payload();
615 BEAST_EXPECT(req
.count(field::content_length
) == 0);
616 BEAST_EXPECT(req
[field::transfer_encoding
] == "deflate, chunked");
619 // POST, unsized HTTP/1.0
621 request
<unsized_body
> req
;
623 req
.method(verb::post
);
625 req
.prepare_payload();
626 BEAST_EXPECT(req
.count(field::content_length
) == 0);
627 BEAST_EXPECT(req
.count(field::transfer_encoding
) == 0);
629 req
.set(field::transfer_encoding
, "deflate");
630 req
.prepare_payload();
631 BEAST_EXPECT(req
.count(field::content_length
) == 0);
632 BEAST_EXPECT(req
[field::transfer_encoding
] == "deflate");
637 response
<empty_body
> res
;
640 res
.prepare_payload();
641 BEAST_EXPECT(res
[field::content_length
] == "0");
642 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
644 res
.erase(field::content_length
);
645 res
.set(field::transfer_encoding
, "chunked");
646 res
.prepare_payload();
647 BEAST_EXPECT(res
[field::content_length
] == "0");
648 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
653 response
<sized_body
> res
;
657 res
.prepare_payload();
658 BEAST_EXPECT(res
[field::content_length
] == "50");
659 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
661 res
.erase(field::content_length
);
662 res
.set(field::transfer_encoding
, "chunked");
663 res
.prepare_payload();
664 BEAST_EXPECT(res
[field::content_length
] == "50");
665 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
670 response
<unsized_body
> res
;
673 res
.prepare_payload();
674 BEAST_EXPECT(res
.count(field::content_length
) == 0);
675 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked");
682 response
<empty_body
> res
;
683 auto const keep_alive
=
688 (res
.keep_alive() && v
) ||
689 (! res
.keep_alive() && ! v
));
692 std::string
const big(max_static_buffer
+ 1, 'a');
696 res
.erase(field::connection
);
699 BEAST_EXPECT(res
.count(field::connection
) == 0);
701 res
.set(field::connection
, "close");
703 BEAST_EXPECT(res
.count(field::connection
) == 0);
705 res
.set(field::connection
, "keep-alive");
707 BEAST_EXPECT(res
.count(field::connection
) == 0);
709 res
.set(field::connection
, "keep-alive, close");
711 BEAST_EXPECT(res
.count(field::connection
) == 0);
713 res
.erase(field::connection
);
715 BEAST_EXPECT(res
[field::connection
] == "keep-alive");
717 res
.set(field::connection
, "close");
719 BEAST_EXPECT(res
[field::connection
] == "keep-alive");
721 res
.set(field::connection
, "keep-alive");
723 BEAST_EXPECT(res
[field::connection
] == "keep-alive");
725 res
.set(field::connection
, "keep-alive, close");
727 BEAST_EXPECT(res
[field::connection
] == "keep-alive");
732 res
.set(field::connection
, s
);
734 BEAST_EXPECT(res
[field::connection
] == s
);
736 res
.set(field::connection
, s
+ ", close");
738 BEAST_EXPECT(res
[field::connection
] == s
);
740 res
.set(field::connection
, "keep-alive, " + s
);
742 BEAST_EXPECT(res
[field::connection
] == s
);
744 res
.set(field::connection
, "keep-alive, " + s
+ ", close");
746 BEAST_EXPECT(res
[field::connection
] == s
);
748 res
.set(field::connection
, s
);
750 BEAST_EXPECT(res
[field::connection
] == s
+ ", keep-alive");
752 res
.set(field::connection
, s
+ ", close");
754 BEAST_EXPECT(res
[field::connection
] == s
+ ", keep-alive");
756 res
.set(field::connection
, "keep-alive, " + s
);
758 BEAST_EXPECT(res
[field::connection
] == "keep-alive, " + s
);
760 res
.set(field::connection
, "keep-alive, " + s
+ ", close");
762 BEAST_EXPECT(res
[field::connection
] == "keep-alive, " + s
);
771 res
.erase(field::connection
);
773 BEAST_EXPECT(res
.count(field::connection
) == 0);
775 res
.set(field::connection
, "close");
777 BEAST_EXPECT(res
.count(field::connection
) == 0);
779 res
.set(field::connection
, "keep-alive");
781 BEAST_EXPECT(res
.count(field::connection
) == 0);
783 res
.set(field::connection
, "keep-alive, close");
785 BEAST_EXPECT(res
.count(field::connection
) == 0);
787 res
.erase(field::connection
);
789 BEAST_EXPECT(res
[field::connection
] == "close");
791 res
.set(field::connection
, "close");
793 BEAST_EXPECT(res
[field::connection
] == "close");
795 res
.set(field::connection
, "keep-alive");
797 BEAST_EXPECT(res
[field::connection
] == "close");
799 res
.set(field::connection
, "keep-alive, close");
801 BEAST_EXPECT(res
[field::connection
] == "close");
806 res
.set(field::connection
, s
);
808 BEAST_EXPECT(res
[field::connection
] == s
);
810 res
.set(field::connection
, s
+ ", close");
812 BEAST_EXPECT(res
[field::connection
] == s
);
814 res
.set(field::connection
, "keep-alive, " + s
);
816 BEAST_EXPECT(res
[field::connection
] == s
);
818 res
.set(field::connection
, "keep-alive, " + s
+ ", close");
820 BEAST_EXPECT(res
[field::connection
] == s
);
822 res
.set(field::connection
, s
);
824 BEAST_EXPECT(res
[field::connection
] == s
+ ", close");
826 res
.set(field::connection
, "close, " + s
);
828 BEAST_EXPECT(res
[field::connection
] == "close, " + s
);
830 res
.set(field::connection
, "keep-alive, " + s
);
832 BEAST_EXPECT(res
[field::connection
] == s
+ ", close");
834 res
.set(field::connection
, "close, " + s
+ ", keep-alive");
836 BEAST_EXPECT(res
[field::connection
] == "close, " + s
);
846 response
<empty_body
> res
{status::ok
, 11};
847 BEAST_EXPECT(res
.count(field::content_length
) == 0);
848 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
850 res
.content_length(0);
851 BEAST_EXPECT(res
[field::content_length
] == "0");
853 res
.content_length(100);
854 BEAST_EXPECT(res
[field::content_length
] == "100");
856 res
.content_length(boost::none
);
857 BEAST_EXPECT(res
.count(field::content_length
) == 0);
859 res
.set(field::transfer_encoding
, "chunked");
860 res
.content_length(0);
861 BEAST_EXPECT(res
[field::content_length
] == "0");
862 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
864 res
.set(field::transfer_encoding
, "chunked");
865 res
.content_length(100);
866 BEAST_EXPECT(res
[field::content_length
] == "100");
867 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
869 res
.set(field::transfer_encoding
, "chunked");
870 res
.content_length(boost::none
);
871 BEAST_EXPECT(res
.count(field::content_length
) == 0);
872 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
874 auto const check
= [&](std::string s
)
876 res
.set(field::transfer_encoding
, s
);
877 res
.content_length(0);
878 BEAST_EXPECT(res
[field::content_length
] == "0");
879 BEAST_EXPECT(res
[field::transfer_encoding
] == s
);
881 res
.set(field::transfer_encoding
, s
);
882 res
.content_length(100);
883 BEAST_EXPECT(res
[field::content_length
] == "100");
884 BEAST_EXPECT(res
[field::transfer_encoding
] == s
);
886 res
.set(field::transfer_encoding
, s
);
887 res
.content_length(boost::none
);
888 BEAST_EXPECT(res
.count(field::content_length
) == 0);
889 BEAST_EXPECT(res
[field::transfer_encoding
] == s
);
891 res
.set(field::transfer_encoding
, s
+ ", chunked");
892 res
.content_length(0);
893 BEAST_EXPECT(res
[field::content_length
] == "0");
894 BEAST_EXPECT(res
[field::transfer_encoding
] == s
);
896 res
.set(field::transfer_encoding
, s
+ ", chunked");
897 res
.content_length(100);
898 BEAST_EXPECT(res
[field::content_length
] == "100");
899 BEAST_EXPECT(res
[field::transfer_encoding
] == s
);
901 res
.set(field::transfer_encoding
, s
+ ", chunked");
902 res
.content_length(boost::none
);
903 BEAST_EXPECT(res
.count(field::content_length
) == 0);
904 BEAST_EXPECT(res
[field::transfer_encoding
] == s
);
906 res
.set(field::transfer_encoding
, "chunked, " + s
);
907 res
.content_length(0);
908 BEAST_EXPECT(res
[field::content_length
] == "0");
909 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked, " + s
);
911 res
.set(field::transfer_encoding
, "chunked, " + s
);
912 res
.content_length(100);
913 BEAST_EXPECT(res
[field::content_length
] == "100");
914 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked, " + s
);
916 res
.set(field::transfer_encoding
, "chunked, " + s
);
917 res
.content_length(boost::none
);
918 BEAST_EXPECT(res
.count(field::content_length
) == 0);
919 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked, " + s
);
924 std::string
const big(max_static_buffer
+ 1, 'a');
932 response
<empty_body
> res
{status::ok
, 11};
933 BEAST_EXPECT(res
.count(field::content_length
) == 0);
934 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
941 (res
.chunked() && v
) ||
942 (! res
.chunked() && ! v
));
943 BEAST_EXPECT(res
.count(
944 field::content_length
) == 0);
947 res
.erase(field::transfer_encoding
);
948 res
.set(field::content_length
, to_static_string(32));
950 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked");
952 res
.set(field::transfer_encoding
, "chunked");
954 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked");
956 res
.erase(field::transfer_encoding
);
957 res
.set(field::content_length
, to_static_string(32));
959 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
961 res
.set(field::transfer_encoding
, "chunked");
963 BEAST_EXPECT(res
.count(field::transfer_encoding
) == 0);
967 res
.set(field::transfer_encoding
, "foo");
969 BEAST_EXPECT(res
[field::transfer_encoding
] == "foo, chunked");
971 res
.set(field::transfer_encoding
, "chunked, foo");
973 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked, foo, chunked");
975 res
.set(field::transfer_encoding
, "chunked, foo, chunked");
977 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked, foo, chunked");
979 res
.set(field::transfer_encoding
, "foo, chunked");
981 BEAST_EXPECT(res
[field::transfer_encoding
] == "foo");
983 res
.set(field::transfer_encoding
, "chunked, foo");
985 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked, foo");
987 res
.set(field::transfer_encoding
, "chunked, foo, chunked");
989 BEAST_EXPECT(res
[field::transfer_encoding
] == "chunked, foo");
995 beast::http::fields req
;
996 req
.insert("abc", "1");
997 req
.insert("abc", "2");
998 req
.insert("abc", "3");
999 BEAST_EXPECT(req
.count("abc") == 3);
1000 auto iter
= req
.find("abc");
1001 BEAST_EXPECT(iter
->value() == "1");
1002 req
.insert("abc", "4");
1004 BEAST_EXPECT(req
.count("abc") == 3);
1007 template<class Arg1
, class InArg
>
1010 static auto test(...) ->
1013 template<class U
= InArg
>
1014 static auto test(U arg
) ->
1015 decltype(std::declval
<fields
>().
1016 set(std::declval
<Arg1
>(),
1020 static constexpr bool value
=
1021 decltype(test(std::declval
<InArg
>()))::value
;
1024 template<class Arg1
, class InArg
>
1027 static auto test(...) ->
1030 template<class U
= InArg
>
1031 static auto test(U arg
) ->
1032 decltype(std::declval
<fields
>().
1033 insert(std::declval
<Arg1
>(),
1037 static constexpr bool value
=
1038 decltype(test(std::declval
<InArg
>()))::value
;
1044 BOOST_STATIC_ASSERT((! set_test
<field
, int>::value
));
1045 BOOST_STATIC_ASSERT((! set_test
<field
, std::nullptr_t
>::value
));
1046 BOOST_STATIC_ASSERT((! set_test
<field
, double>::value
));
1047 BOOST_STATIC_ASSERT((! set_test
<string_view
, int>::value
));
1048 BOOST_STATIC_ASSERT((! set_test
<string_view
, std::nullptr_t
>::value
));
1049 BOOST_STATIC_ASSERT((! set_test
<string_view
, double>::value
));
1051 BOOST_STATIC_ASSERT(( set_test
<field
, const char*>::value
));
1052 BOOST_STATIC_ASSERT(( set_test
<field
, string_view
>::value
));
1053 BOOST_STATIC_ASSERT(( set_test
<field
, const char(&)[10]>::value
));
1054 BOOST_STATIC_ASSERT(( set_test
<string_view
, const char*>::value
));
1055 BOOST_STATIC_ASSERT(( set_test
<string_view
, string_view
>::value
));
1056 BOOST_STATIC_ASSERT(( set_test
<string_view
, const char(&)[10]>::value
));
1058 BOOST_STATIC_ASSERT((! insert_test
<field
, int>::value
));
1059 BOOST_STATIC_ASSERT((! insert_test
<field
, std::nullptr_t
>::value
));
1060 BOOST_STATIC_ASSERT((! insert_test
<field
, double>::value
));
1061 BOOST_STATIC_ASSERT((! insert_test
<string_view
, int>::value
));
1062 BOOST_STATIC_ASSERT((! insert_test
<string_view
, std::nullptr_t
>::value
));
1063 BOOST_STATIC_ASSERT((! insert_test
<string_view
, double>::value
));
1065 BOOST_STATIC_ASSERT(( insert_test
<field
, const char*>::value
));
1066 BOOST_STATIC_ASSERT(( insert_test
<field
, string_view
>::value
));
1067 BOOST_STATIC_ASSERT(( insert_test
<field
, const char(&)[10]>::value
));
1068 BOOST_STATIC_ASSERT(( insert_test
<string_view
, const char*>::value
));
1069 BOOST_STATIC_ASSERT(( insert_test
<string_view
, string_view
>::value
));
1070 BOOST_STATIC_ASSERT(( insert_test
<string_view
, const char(&)[10]>::value
));
1080 testIteratorErase();
1082 testPreparePayload();
1085 testContentLength();
1089 boost::ignore_unused(&fields_test::testIssue2085
);
1093 BEAST_DEFINE_TESTSUITE(beast
,http
,fields
);