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 21 namespace boost { 22 namespace beast { 23 namespace http { 24 25 class fields_test : public beast::unit_test::suite 26 { 27 public: 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 test_allocator()37 test_allocator() noexcept(false) {} 38 39 template<class U, class = typename 40 std::enable_if<!std::is_same<test_allocator, U>::value>::type> test_allocator(test_allocator<U> const &)41 test_allocator(test_allocator<U> const&) noexcept {} 42 43 value_type* allocate(std::size_t n)44 allocate(std::size_t n) 45 { 46 return static_cast<value_type*>(::operator new (n*sizeof(value_type))); 47 } 48 49 void deallocate(value_type * p,std::size_t)50 deallocate(value_type* p, std::size_t) noexcept 51 { 52 ::operator delete(p); 53 } 54 55 template<class U> 56 friend 57 bool operator ==(test_allocator<T> const &,test_allocator<U> const &)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 operator !=(test_allocator<T> const & x,test_allocator<U> const & y)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 fill(std::size_t n,basic_fields<Allocator> & f)95 fill(std::size_t n, basic_fields<Allocator>& f) 96 { 97 for(std::size_t i = 1; i<= n; ++i) 98 f.insert(std::to_string(i), to_static_string(i)); 99 } 100 101 template<class U, class V> 102 static 103 void self_assign(U & u,V && v)104 self_assign(U& u, V&& v) 105 { 106 u = std::forward<V>(v); 107 } 108 109 template<class Alloc> 110 static 111 bool empty(basic_fields<Alloc> const & f)112 empty(basic_fields<Alloc> const& f) 113 { 114 return f.begin() == f.end(); 115 } 116 117 template<class Alloc> 118 static 119 std::size_t size(basic_fields<Alloc> const & f)120 size(basic_fields<Alloc> const& f) 121 { 122 return std::distance(f.begin(), f.end()); 123 } 124 125 void testMembers()126 testMembers() 127 { 128 using namespace test; 129 130 // compare equal 131 using equal_t = test::test_allocator<char, 132 true, true, true, true, true>; 133 134 // compare not equal 135 using unequal_t = test::test_allocator<char, 136 false, true, true, true, true>; 137 138 // construction 139 { 140 { 141 fields f; 142 BEAST_EXPECT(f.begin() == f.end()); 143 } 144 { 145 unequal_t a1; 146 basic_fields<unequal_t> f{a1}; 147 BEAST_EXPECT(f.get_allocator() == a1); 148 BEAST_EXPECT(f.get_allocator() != unequal_t{}); 149 } 150 } 151 152 // move construction 153 { 154 { 155 basic_fields<equal_t> f1; 156 BEAST_EXPECT(f1.get_allocator()->nmove == 0); 157 f1.insert("1", "1"); 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"] == ""); 163 } 164 // allocators equal 165 { 166 basic_fields<equal_t> f1; 167 f1.insert("1", "1"); 168 equal_t a; 169 basic_fields<equal_t> f2{std::move(f1), a}; 170 BEAST_EXPECT(f2["1"] == "1"); 171 BEAST_EXPECT(f1["1"] == ""); 172 } 173 { 174 // allocators unequal 175 basic_fields<unequal_t> f1; 176 f1.insert("1", "1"); 177 unequal_t a; 178 basic_fields<unequal_t> f2{std::move(f1), a}; 179 BEAST_EXPECT(f2["1"] == "1"); 180 } 181 } 182 183 // copy construction 184 { 185 { 186 basic_fields<equal_t> f1; 187 f1.insert("1", "1"); 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"); 192 } 193 { 194 basic_fields<unequal_t> f1; 195 f1.insert("1", "1"); 196 unequal_t a; 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"); 201 } 202 { 203 basic_fields<equal_t> f1; 204 f1.insert("1", "1"); 205 basic_fields<unequal_t> f2(f1); 206 BEAST_EXPECT(f1["1"] == "1"); 207 BEAST_EXPECT(f2["1"] == "1"); 208 } 209 { 210 basic_fields<unequal_t> f1; 211 f1.insert("1", "1"); 212 equal_t a; 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"); 217 } 218 } 219 220 // move assignment 221 { 222 { 223 fields f1; 224 f1.insert("1", "1"); 225 fields f2; 226 f2 = std::move(f1); 227 BEAST_EXPECT(f1.begin() == f1.end()); 228 BEAST_EXPECT(f2["1"] == "1"); 229 } 230 { 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; 235 f1.insert("1", "1"); 236 basic_fields<pocma_t> f2; 237 f2 = std::move(f1); 238 BEAST_EXPECT(f1.begin() == f1.end()); 239 BEAST_EXPECT(f2["1"] == "1"); 240 } 241 { 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; 246 f1.insert("1", "1"); 247 basic_fields<pocma_t> f2; 248 f2 = std::move(f1); 249 BEAST_EXPECT(f1.begin() == f1.end()); 250 BEAST_EXPECT(f2["1"] == "1"); 251 } 252 } 253 254 // copy assignment 255 { 256 { 257 fields f1; 258 f1.insert("1", "1"); 259 fields f2; 260 f2 = f1; 261 BEAST_EXPECT(f1["1"] == "1"); 262 BEAST_EXPECT(f2["1"] == "1"); 263 basic_fields<equal_t> f3; 264 f3 = f2; 265 BEAST_EXPECT(f3["1"] == "1"); 266 } 267 { 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; 272 f1.insert("1", "1"); 273 basic_fields<pocca_t> f2; 274 f2 = f1; 275 BEAST_EXPECT(f2["1"] == "1"); 276 } 277 { 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; 282 f1.insert("1", "1"); 283 basic_fields<pocca_t> f2; 284 f2 = f1; 285 BEAST_EXPECT(f2["1"] == "1"); 286 } 287 } 288 289 // swap 290 { 291 { 292 // propagate_on_container_swap : true 293 using pocs_t = test::test_allocator<char, 294 false, true, true, true, true>; 295 pocs_t a1, a2; 296 BEAST_EXPECT(a1 != a2); 297 basic_fields<pocs_t> f1{a1}; 298 f1.insert("1", "1"); 299 basic_fields<pocs_t> f2{a2}; 300 BEAST_EXPECT(f1.get_allocator() == a1); 301 BEAST_EXPECT(f2.get_allocator() == a2); 302 swap(f1, f2); 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"); 307 swap(f1, f2); 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()); 312 } 313 { 314 // propagate_on_container_swap : false 315 using pocs_t = test::test_allocator<char, 316 true, true, true, false, true>; 317 pocs_t a1, a2; 318 BEAST_EXPECT(a1 == a2); 319 BEAST_EXPECT(a1.id() != a2.id()); 320 basic_fields<pocs_t> f1{a1}; 321 f1.insert("1", "1"); 322 basic_fields<pocs_t> f2{a2}; 323 BEAST_EXPECT(f1.get_allocator() == a1); 324 BEAST_EXPECT(f2.get_allocator() == a2); 325 swap(f1, f2); 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"); 330 swap(f1, f2); 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()); 335 } 336 } 337 338 // operations 339 { 340 fields f; 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); 348 } 349 } 350 testHeaders()351 void testHeaders() 352 { 353 f_t f1; 354 BEAST_EXPECT(empty(f1)); 355 fill(1, f1); 356 BEAST_EXPECT(size(f1) == 1); 357 f_t f2; 358 f2 = f1; 359 BEAST_EXPECT(size(f2) == 1); 360 f2.insert("2", "2"); 361 BEAST_EXPECT(std::distance(f2.begin(), f2.end()) == 2); 362 f1 = std::move(f2); 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); 371 } 372 testRFC2616()373 void testRFC2616() 374 { 375 f_t f; 376 f.insert("a", "w"); 377 f.insert("a", "x"); 378 f.insert("aa", "y"); 379 f.insert("f", "z"); 380 BEAST_EXPECT(f.count("a") == 2); 381 } 382 testErase()383 void testErase() 384 { 385 f_t f; 386 f.insert("a", "w"); 387 f.insert("a", "x"); 388 f.insert("aa", "y"); 389 f.insert("f", "z"); 390 BEAST_EXPECT(size(f) == 4); 391 f.erase("a"); 392 BEAST_EXPECT(size(f) == 2); 393 } 394 testIteratorErase()395 void testIteratorErase() 396 { 397 f_t f; 398 f.insert("a", "x"); 399 f.insert("b", "y"); 400 f.insert("c", "z"); 401 BEAST_EXPECT(size(f) == 3); 402 f_t::const_iterator i = std::next(f.begin()); 403 f.erase(i); 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"); 407 } 408 409 void testContainer()410 testContainer() 411 { 412 { 413 // group fields 414 fields f; 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"); 434 } 435 { 436 // group fields, case insensitive 437 fields f; 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"); 457 } 458 { 459 // verify insertion orde 460 fields f; 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"); 474 f.set("dd", "-"); 475 BEAST_EXPECT(f.count("dd") == 1); 476 BEAST_EXPECT(f["dd"] == "-"); 477 } 478 479 // equal_range 480 { 481 fields f; 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"); 494 } 495 } 496 497 struct sized_body 498 { 499 using value_type = std::uint64_t; 500 501 static 502 std::uint64_t sizeboost::beast::http::fields_test::sized_body503 size(value_type const& v) 504 { 505 return v; 506 } 507 }; 508 509 struct unsized_body 510 { 511 struct value_type {}; 512 }; 513 514 void testPreparePayload()515 testPreparePayload() 516 { 517 // GET, empty 518 { 519 request<empty_body> req; 520 req.version(11); 521 req.method(verb::get); 522 523 req.prepare_payload(); 524 BEAST_EXPECT(req.count(field::content_length) == 0); 525 BEAST_EXPECT(req.count(field::transfer_encoding) == 0); 526 527 req.set(field::content_length, "0"); 528 req.set(field::transfer_encoding, "chunked"); 529 req.prepare_payload(); 530 531 BEAST_EXPECT(req.count(field::content_length) == 0); 532 BEAST_EXPECT(req.count(field::transfer_encoding) == 0); 533 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"); 538 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"); 543 } 544 545 // GET, sized 546 { 547 request<sized_body> req; 548 req.version(11); 549 req.method(verb::get); 550 req.body() = 50; 551 552 req.prepare_payload(); 553 BEAST_EXPECT(req[field::content_length] == "50"); 554 BEAST_EXPECT(req[field::transfer_encoding] == ""); 555 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); 561 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"); 566 } 567 568 // PUT, empty 569 { 570 request<empty_body> req; 571 req.version(11); 572 req.method(verb::put); 573 574 req.prepare_payload(); 575 BEAST_EXPECT(req[field::content_length] == "0"); 576 BEAST_EXPECT(req.count(field::transfer_encoding) == 0); 577 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"); 583 } 584 585 // PUT, sized 586 { 587 request<sized_body> req; 588 req.version(11); 589 req.method(verb::put); 590 req.body() = 50; 591 592 req.prepare_payload(); 593 BEAST_EXPECT(req[field::content_length] == "50"); 594 BEAST_EXPECT(req.count(field::transfer_encoding) == 0); 595 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"); 601 } 602 603 // POST, unsized 604 { 605 request<unsized_body> req; 606 req.version(11); 607 req.method(verb::post); 608 609 req.prepare_payload(); 610 BEAST_EXPECT(req.count(field::content_length) == 0); 611 BEAST_EXPECT(req[field::transfer_encoding] == "chunked"); 612 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"); 617 } 618 619 // POST, unsized HTTP/1.0 620 { 621 request<unsized_body> req; 622 req.version(10); 623 req.method(verb::post); 624 625 req.prepare_payload(); 626 BEAST_EXPECT(req.count(field::content_length) == 0); 627 BEAST_EXPECT(req.count(field::transfer_encoding) == 0); 628 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"); 633 } 634 635 // OK, empty 636 { 637 response<empty_body> res; 638 res.version(11); 639 640 res.prepare_payload(); 641 BEAST_EXPECT(res[field::content_length] == "0"); 642 BEAST_EXPECT(res.count(field::transfer_encoding) == 0); 643 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); 649 } 650 651 // OK, sized 652 { 653 response<sized_body> res; 654 res.version(11); 655 res.body() = 50; 656 657 res.prepare_payload(); 658 BEAST_EXPECT(res[field::content_length] == "50"); 659 BEAST_EXPECT(res.count(field::transfer_encoding) == 0); 660 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); 666 } 667 668 // OK, unsized 669 { 670 response<unsized_body> res; 671 res.version(11); 672 673 res.prepare_payload(); 674 BEAST_EXPECT(res.count(field::content_length) == 0); 675 BEAST_EXPECT(res[field::transfer_encoding] == "chunked"); 676 } 677 } 678 679 void testKeepAlive()680 testKeepAlive() 681 { 682 response<empty_body> res; 683 auto const keep_alive = 684 [&](bool v) 685 { 686 res.keep_alive(v); 687 BEAST_EXPECT( 688 (res.keep_alive() && v) || 689 (! res.keep_alive() && ! v)); 690 }; 691 692 std::string const big(max_static_buffer + 1, 'a'); 693 694 // HTTP/1.0 695 res.version(10); 696 res.erase(field::connection); 697 698 keep_alive(false); 699 BEAST_EXPECT(res.count(field::connection) == 0); 700 701 res.set(field::connection, "close"); 702 keep_alive(false); 703 BEAST_EXPECT(res.count(field::connection) == 0); 704 705 res.set(field::connection, "keep-alive"); 706 keep_alive(false); 707 BEAST_EXPECT(res.count(field::connection) == 0); 708 709 res.set(field::connection, "keep-alive, close"); 710 keep_alive(false); 711 BEAST_EXPECT(res.count(field::connection) == 0); 712 713 res.erase(field::connection); 714 keep_alive(true); 715 BEAST_EXPECT(res[field::connection] == "keep-alive"); 716 717 res.set(field::connection, "close"); 718 keep_alive(true); 719 BEAST_EXPECT(res[field::connection] == "keep-alive"); 720 721 res.set(field::connection, "keep-alive"); 722 keep_alive(true); 723 BEAST_EXPECT(res[field::connection] == "keep-alive"); 724 725 res.set(field::connection, "keep-alive, close"); 726 keep_alive(true); 727 BEAST_EXPECT(res[field::connection] == "keep-alive"); 728 729 auto const test10 = 730 [&](std::string s) 731 { 732 res.set(field::connection, s); 733 keep_alive(false); 734 BEAST_EXPECT(res[field::connection] == s); 735 736 res.set(field::connection, s + ", close"); 737 keep_alive(false); 738 BEAST_EXPECT(res[field::connection] == s); 739 740 res.set(field::connection, "keep-alive, " + s); 741 keep_alive(false); 742 BEAST_EXPECT(res[field::connection] == s); 743 744 res.set(field::connection, "keep-alive, " + s + ", close"); 745 keep_alive(false); 746 BEAST_EXPECT(res[field::connection] == s); 747 748 res.set(field::connection, s); 749 keep_alive(true); 750 BEAST_EXPECT(res[field::connection] == s + ", keep-alive"); 751 752 res.set(field::connection, s + ", close"); 753 keep_alive(true); 754 BEAST_EXPECT(res[field::connection] == s + ", keep-alive"); 755 756 res.set(field::connection, "keep-alive, " + s); 757 keep_alive(true); 758 BEAST_EXPECT(res[field::connection] == "keep-alive, " + s); 759 760 res.set(field::connection, "keep-alive, " + s+ ", close"); 761 keep_alive(true); 762 BEAST_EXPECT(res[field::connection] == "keep-alive, " + s); 763 }; 764 765 test10("foo"); 766 test10(big); 767 768 // HTTP/1.1 769 res.version(11); 770 771 res.erase(field::connection); 772 keep_alive(true); 773 BEAST_EXPECT(res.count(field::connection) == 0); 774 775 res.set(field::connection, "close"); 776 keep_alive(true); 777 BEAST_EXPECT(res.count(field::connection) == 0); 778 779 res.set(field::connection, "keep-alive"); 780 keep_alive(true); 781 BEAST_EXPECT(res.count(field::connection) == 0); 782 783 res.set(field::connection, "keep-alive, close"); 784 keep_alive(true); 785 BEAST_EXPECT(res.count(field::connection) == 0); 786 787 res.erase(field::connection); 788 keep_alive(false); 789 BEAST_EXPECT(res[field::connection] == "close"); 790 791 res.set(field::connection, "close"); 792 keep_alive(false); 793 BEAST_EXPECT(res[field::connection] == "close"); 794 795 res.set(field::connection, "keep-alive"); 796 keep_alive(false); 797 BEAST_EXPECT(res[field::connection] == "close"); 798 799 res.set(field::connection, "keep-alive, close"); 800 keep_alive(false); 801 BEAST_EXPECT(res[field::connection] == "close"); 802 803 auto const test11 = 804 [&](std::string s) 805 { 806 res.set(field::connection, s); 807 keep_alive(true); 808 BEAST_EXPECT(res[field::connection] == s); 809 810 res.set(field::connection, s + ", close"); 811 keep_alive(true); 812 BEAST_EXPECT(res[field::connection] == s); 813 814 res.set(field::connection, "keep-alive, " + s); 815 keep_alive(true); 816 BEAST_EXPECT(res[field::connection] == s); 817 818 res.set(field::connection, "keep-alive, " + s + ", close"); 819 keep_alive(true); 820 BEAST_EXPECT(res[field::connection] == s); 821 822 res.set(field::connection, s); 823 keep_alive(false); 824 BEAST_EXPECT(res[field::connection] == s + ", close"); 825 826 res.set(field::connection, "close, " + s); 827 keep_alive(false); 828 BEAST_EXPECT(res[field::connection] == "close, " + s); 829 830 res.set(field::connection, "keep-alive, " + s); 831 keep_alive(false); 832 BEAST_EXPECT(res[field::connection] == s + ", close"); 833 834 res.set(field::connection, "close, " + s + ", keep-alive"); 835 keep_alive(false); 836 BEAST_EXPECT(res[field::connection] == "close, " + s); 837 }; 838 839 test11("foo"); 840 test11(big); 841 } 842 843 void testContentLength()844 testContentLength() 845 { 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); 849 850 res.content_length(0); 851 BEAST_EXPECT(res[field::content_length] == "0"); 852 853 res.content_length(100); 854 BEAST_EXPECT(res[field::content_length] == "100"); 855 856 res.content_length(boost::none); 857 BEAST_EXPECT(res.count(field::content_length) == 0); 858 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); 863 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); 868 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); 873 874 auto const check = [&](std::string s) 875 { 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); 880 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); 885 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); 890 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); 895 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); 900 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); 905 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); 910 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); 915 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); 920 }; 921 922 check("foo"); 923 924 std::string const big(max_static_buffer + 1, 'a'); 925 926 check(big); 927 } 928 929 void testChunked()930 testChunked() 931 { 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); 935 936 auto const chunked = 937 [&](bool v) 938 { 939 res.chunked(v); 940 BEAST_EXPECT( 941 (res.chunked() && v) || 942 (! res.chunked() && ! v)); 943 BEAST_EXPECT(res.count( 944 field::content_length) == 0); 945 }; 946 947 res.erase(field::transfer_encoding); 948 res.set(field::content_length, to_static_string(32)); 949 chunked(true); 950 BEAST_EXPECT(res[field::transfer_encoding] == "chunked"); 951 952 res.set(field::transfer_encoding, "chunked"); 953 chunked(true); 954 BEAST_EXPECT(res[field::transfer_encoding] == "chunked"); 955 956 res.erase(field::transfer_encoding); 957 res.set(field::content_length, to_static_string(32)); 958 chunked(false); 959 BEAST_EXPECT(res.count(field::transfer_encoding) == 0); 960 961 res.set(field::transfer_encoding, "chunked"); 962 chunked(false); 963 BEAST_EXPECT(res.count(field::transfer_encoding) == 0); 964 965 966 967 res.set(field::transfer_encoding, "foo"); 968 chunked(true); 969 BEAST_EXPECT(res[field::transfer_encoding] == "foo, chunked"); 970 971 res.set(field::transfer_encoding, "chunked, foo"); 972 chunked(true); 973 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, foo, chunked"); 974 975 res.set(field::transfer_encoding, "chunked, foo, chunked"); 976 chunked(true); 977 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, foo, chunked"); 978 979 res.set(field::transfer_encoding, "foo, chunked"); 980 chunked(false); 981 BEAST_EXPECT(res[field::transfer_encoding] == "foo"); 982 983 res.set(field::transfer_encoding, "chunked, foo"); 984 chunked(false); 985 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, foo"); 986 987 res.set(field::transfer_encoding, "chunked, foo, chunked"); 988 chunked(false); 989 BEAST_EXPECT(res[field::transfer_encoding] == "chunked, foo"); 990 } 991 992 void testIssue1828()993 testIssue1828() 994 { 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"); 1003 req.erase(iter); 1004 BEAST_EXPECT(req.count("abc") == 3); 1005 } 1006 1007 template<class Arg1, class InArg> 1008 struct set_test 1009 { 1010 static auto test(...) -> 1011 std::false_type; 1012 1013 template<class U = InArg> 1014 static auto test(U arg) -> 1015 decltype(std::declval<fields>(). 1016 set(std::declval<Arg1>(), 1017 std::declval<U>()), 1018 std::true_type()); 1019 1020 static constexpr bool value = 1021 decltype(test(std::declval<InArg>()))::value; 1022 }; 1023 1024 template<class Arg1, class InArg> 1025 struct insert_test 1026 { 1027 static auto test(...) -> 1028 std::false_type; 1029 1030 template<class U = InArg> 1031 static auto test(U arg) -> 1032 decltype(std::declval<fields>(). 1033 insert(std::declval<Arg1>(), 1034 std::declval<U>()), 1035 std::true_type()); 1036 1037 static constexpr bool value = 1038 decltype(test(std::declval<InArg>()))::value; 1039 }; 1040 1041 void testIssue2085()1042 testIssue2085() 1043 { 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)); 1050 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)); 1057 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)); 1064 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)); 1071 } 1072 1073 void run()1074 run() override 1075 { 1076 testMembers(); 1077 testHeaders(); 1078 testRFC2616(); 1079 testErase(); 1080 testIteratorErase(); 1081 testContainer(); 1082 testPreparePayload(); 1083 1084 testKeepAlive(); 1085 testContentLength(); 1086 testChunked(); 1087 1088 testIssue1828(); 1089 boost::ignore_unused(&fields_test::testIssue2085); 1090 } 1091 }; 1092 1093 BEAST_DEFINE_TESTSUITE(beast,http,fields); 1094 1095 } // http 1096 } // beast 1097 } // boost 1098