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

source code of boost/libs/beast/test/beast/http/fields.cpp