// // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Test that header file is self-contained. #include #include #include #include namespace beast { namespace http { class chunk_encode_test : public beast::unit_test::suite { public: struct not_chunk_extensions {}; BOOST_STATIC_ASSERT( detail::is_chunk_extensions::value); BOOST_STATIC_ASSERT( ! detail::is_chunk_extensions::value); template static std::string to_string(ConstBufferSequence const& buffers) { std::string s; s.reserve(boost::asio::buffer_size(buffers)); for(boost::asio::const_buffer buffer : buffers) s.append( boost::asio::buffer_cast(buffer), boost::asio::buffer_size(buffer)); return s; } template void check(string_view match, Args&&... args) { T t{std::forward(args)...}; BEAST_EXPECT(to_string(t) == match); T t2{t}; BEAST_EXPECT(to_string(t2) == match); T t3{std::move(t2)}; BEAST_EXPECT(to_string(t3) == match); } template void check_fwd(string_view match, Args&&... args) { T t{std::forward(args)...}; BEAST_EXPECT(to_string(t) == match); T t2{t}; BEAST_EXPECT(to_string(t2) == match); T t3{std::move(t2)}; BEAST_EXPECT(to_string(t3) == match); } using cb_t = boost::asio::const_buffers_1; static cb_t cb(string_view s) { return {s.data(), s.size()}; } void testChunkCRLF() { #if ! defined(BOOST_GCC) || BOOST_GCC >= 50000 check("\r\n"); #endif } void testChunkHeader() { check("10\r\n", 16u); check("20;x\r\n", 32u, ";x"); chunk_extensions exts; exts.insert("y"); exts.insert("z"); check("30;y;z\r\n", 48u, exts); { auto exts2 = exts; check_fwd( "30;y;z\r\n", 48u, std::move(exts2)); } check("30;y;z\r\n", 48u, exts, std::allocator{}); { auto exts2 = exts; check( "30;y;z\r\n", 48u, std::move(exts2), std::allocator{}); } } void testChunkBody() { check>( "3\r\n***\r\n", cb("***")); check>( "3;x\r\n***\r\n", cb("***"), ";x"); chunk_extensions exts; exts.insert("y"); exts.insert("z"); check>( "3;y;z\r\n***\r\n", cb("***"), exts); { auto exts2 = exts; check_fwd>( "3;y;z\r\n***\r\n", cb("***"), std::move(exts2)); } check>( "3;y;z\r\n***\r\n", cb("***"), exts, std::allocator{}); { auto exts2 = exts; check_fwd>( "3;y;z\r\n***\r\n", cb("***"), std::move(exts2), std::allocator{}); } } void testChunkFinal() { check>( "0\r\n\r\n"); check>( "0\r\nMD5:ou812\r\n\r\n", cb("MD5:ou812\r\n\r\n")); fields trailers; trailers.set(field::content_md5, "ou812"); check>( "0\r\nContent-MD5: ou812\r\n\r\n", trailers); { auto trailers2 = trailers; check_fwd>( "0\r\nContent-MD5: ou812\r\n\r\n", std::move(trailers2)); } check>( "0\r\nContent-MD5: ou812\r\n\r\n", trailers, std::allocator{}); { auto trailers2 = trailers; check>( "0\r\nContent-MD5: ou812\r\n\r\n", std::move(trailers2), std::allocator{}); } } void testChunkExtensions() { chunk_extensions ce; ce.insert("x"); BEAST_EXPECT(ce.str() == ";x"); ce.insert("y", "z"); BEAST_EXPECT(ce.str() == ";x;y=z"); ce.insert("z", R"(")"); BEAST_EXPECT(ce.str() == R"(;x;y=z;z="\"")"); ce.insert("p", R"(\)"); BEAST_EXPECT(ce.str() == R"(;x;y=z;z="\"";p="\\")"); ce.insert("q", R"(1"2\)"); BEAST_EXPECT(ce.str() == R"(;x;y=z;z="\"";p="\\";q="1\"2\\")"); } void run() override { testChunkCRLF(); testChunkHeader(); testChunkBody(); testChunkFinal(); testChunkExtensions(); } }; BEAST_DEFINE_TESTSUITE(chunk_encode,http,beast); } // http } // beast