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