text: /*
  	restinio
  */
  
  /*!
  	Tests for header objects.
  */
  
  #include <catch2/catch.hpp>
  
  #include <iterator>
  #include <set>
  
  #include <restinio/all.hpp>
  
  using namespace restinio;
  
  TEST_CASE( "Working with fields (by name)" , "[header][fields][by_name]" )
  {
  	http_header_fields_t fields;
  
  	REQUIRE( 0 == fields.fields_count() ); // No fields yet.
  
  	REQUIRE(
  		fields.get_field_or( "Content-Type", "default-value" )
  			== "default-value" );
  
  	REQUIRE(
  		fields.get_field_or( "CONTENT-Type", "default-value-2" )
  			== "default-value-2" );
  
  	REQUIRE(
  		fields.get_field_or( "CONTENT-TYPE", "default-value-3" )
  			== "default-value-3" );
  
  	fields.set_field( "Content-Type", "text/plain" );
  	REQUIRE( 1 == fields.fields_count() );
  
  	REQUIRE( fields.get_field( "Content-Type" ) == "text/plain" );
  	REQUIRE( fields.value_of( "Content-Type" ) == "text/plain" );
  	REQUIRE( fields.get_field( "CONTENT-TYPE" ) == "text/plain" );
  	REQUIRE( fields.value_of( "CONTENT-TYPE" ) == "text/plain" );
  	REQUIRE( fields.get_field_or( "content-type", "WRONG1" ) == "text/plain" );
  	// By id must also be available:
  	REQUIRE( fields.get_field( http_field::content_type ) == "text/plain" );
  	REQUIRE( fields.value_of( http_field::content_type ) == "text/plain" );
  	REQUIRE( fields.get_field_or( http_field::content_type, "WRONG2" ) == "text/plain" );
  
  	REQUIRE(
  		fields.get_field_or( "Content-Type", "Default-Value" ) == "text/plain" );
  	REQUIRE(
  		fields.get_field_or( "CONTENT-TYPE", "DEFAULT-VALUE" ) == "text/plain" );
  	REQUIRE(
  		fields.get_field_or( "content-type", "default-value" ) == "text/plain" );
  
  	REQUIRE(
  		fields.get_field_or( "Content-Type-XXX", "default-value" )
  			== "default-value" );
  
  	impl::append_last_field_accessor( fields, "; charset=utf-8" );
  
  	REQUIRE(
  		fields.get_field( "Content-Type" ) == "text/plain; charset=utf-8" );
  	REQUIRE(
  		fields.value_of( "Content-Type" ) == "text/plain; charset=utf-8" );
  	REQUIRE(
  		fields.get_field_or( "Content-Type", "Default-Value" )
  			== "text/plain; charset=utf-8" );
  
  	fields.append_field( "Server", "Unit Test" );
  	REQUIRE( 2 == fields.fields_count() );
  
  	REQUIRE( fields.get_field( "server" ) == "Unit Test" );
  	REQUIRE( fields.value_of( "server" ) == "Unit Test" );
  	REQUIRE( fields.get_field_or( "SERVER", "EMPTY" ) == "Unit Test" );
  
  	fields.append_field( "sERVER", "; Fields Test" );
  	REQUIRE( fields.get_field( "sERVEr" ) == "Unit Test; Fields Test" );
  	REQUIRE( fields.value_of( "sERVEr" ) == "Unit Test; Fields Test" );
  	REQUIRE( fields.get_field_or( "SeRveR", "EMPTY" ) == "Unit Test; Fields Test" );
  
  	{
  		int counter = 0;
  		fields.for_each_field( [&counter](const auto & f) {
  			if( 0 == counter ) {
  				REQUIRE( f.name() == "Content-Type" );
  				REQUIRE( f.value() == "text/plain; charset=utf-8" );
  			}
  			else if( 1 == counter ) {
  				REQUIRE( f.name() == "Server" );
  				REQUIRE( f.value() == "Unit Test; Fields Test" );
  			}
  			// Just ignore all other values.
  
  			++counter;
  		} );
  	}
  
  	// Fields that don't exist
  	REQUIRE_FALSE( fields.has_field( "Kontent-typo" ) );
  	REQUIRE_FALSE( fields.has_field( "Zerver" ) );
  
  	REQUIRE_THROWS( fields.get_field( "Kontent-typo" ) );
  	REQUIRE_THROWS( fields.get_field( "Zerver" ) );
  
  	REQUIRE( !fields.remove_field( "Kontent-typo" ) );
  	REQUIRE( !fields.remove_field( "Zerver" ) );
  	REQUIRE( 2 == fields.fields_count() );
  
  	REQUIRE( fields.remove_field( "Content-TYPE" ) );
  	REQUIRE( 1 == fields.fields_count() );
  	REQUIRE( fields.remove_field( "ServeR" ) );
  	REQUIRE( 0 == fields.fields_count() );
  }
  
  TEST_CASE( "get_field_or(name, value) overloads" ,
  		"[header][get_field_or][by_name][overloads]" )
  {
  	http_header_fields_t fields;
  
  	REQUIRE(
  		fields.get_field_or( "Content-Type", "default-value" )
  			== "default-value" );
  
  	REQUIRE(
  		fields.get_field_or( "Content-Type",
  			restinio::string_view_t{ "default-value" } ) == "default-value" );
  
  	std::string dv1{ "default-value" };
  	const std::string dv2{ "default-value" };
  
  	REQUIRE(
  		fields.get_field_or( "Content-Type", dv1 ) == "default-value" );
  	REQUIRE(
  		fields.get_field_or( "Content-Type", dv2 ) == "default-value" );
  
  	REQUIRE(
  		fields.get_field_or( "Content-Type",
  			std::string{ "default-value" } ) == "default-value" );
  
  	{
  		std::string long_value{
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  		};
  		const std::string long_value2{ long_value };
  
  		REQUIRE( long_value == long_value2 );
  		REQUIRE( long_value.data() != long_value2.data() );
  
  		const char * long_value_ptr{ long_value.data() };
  
  		auto v = fields.get_field_or( "Content-Type", std::move(long_value) );
  		REQUIRE( v == long_value2 );
  		REQUIRE( v.data() == long_value_ptr );
  	}
  }
  
  TEST_CASE( "Working with optional fields (by name)",
  		"[header][opt_fields][by_name]" )
  {
  	http_header_fields_t fields;
  
  	REQUIRE( 0 == fields.fields_count() ); // No fields yet.
  
  	{
  		const auto f = fields.try_get_field( "Content-Type" );
  		REQUIRE( !f );
  	}
  	{
  		const auto f = fields.opt_value_of( "Content-Type" );
  		REQUIRE( !f );
  	}
  
  	fields.set_field( "Content-Type", "text/plain" );
  	REQUIRE( 1 == fields.fields_count() );
  
  	{
  		const auto f = fields.try_get_field( "Content-Type" );
  		REQUIRE( f );
  		REQUIRE( *f == "text/plain" );
  	}
  	{
  		const auto f = fields.opt_value_of( "Content-Type" );
  		REQUIRE( f );
  		REQUIRE( *f == "text/plain" );
  	}
  	{
  		const auto f = fields.try_get_field( "CONTENT-Type" );
  		REQUIRE( f );
  		REQUIRE( *f == "text/plain" );
  	}
  	{
  		const auto f = fields.opt_value_of( "CONTENT-Type" );
  		REQUIRE( f );
  		REQUIRE( *f == "text/plain" );
  	}
  }
  
  TEST_CASE( "Working with fields (by id)" , "[header][fields][by_id]" )
  {
  	http_header_fields_t fields;
  
  	REQUIRE( 0 == fields.fields_count() ); // No fields yet.
  
  	REQUIRE(
  		fields.get_field_or( http_field::content_type, "default-value" )
  			== "default-value" );
  
  	REQUIRE(
  		fields.get_field_or( http_field::content_type, "default-value-2" )
  			== "default-value-2" );
  
  	fields.set_field( http_field::content_type, "text/plain" );
  	REQUIRE( 1 == fields.fields_count() );
  
  	REQUIRE( fields.get_field( http_field::content_type ) == "text/plain" );
  	REQUIRE( fields.value_of( http_field::content_type ) == "text/plain" );
  	REQUIRE( fields.get_field_or( http_field::content_type, "WRONG1" ) == "text/plain" );
  	// By name must be also availabl.
  	REQUIRE( fields.get_field( "Content-Type" ) == "text/plain" );
  	REQUIRE( fields.get_field_or( "CONTENT-TYPE", "WRONG2" ) == "text/plain" );
  	REQUIRE( fields.get_field( "content-type" ) == "text/plain" );
  
  	impl::append_last_field_accessor( fields, "; charset=utf-8" );
  
  	REQUIRE(
  		fields.get_field( http_field::content_type ) == "text/plain; charset=utf-8" );
  	REQUIRE(
  		fields.value_of( http_field::content_type ) == "text/plain; charset=utf-8" );
  	REQUIRE(
  		fields.get_field_or( http_field::content_type, "Default-Value" )
  			== "text/plain; charset=utf-8" );
  
  	fields.append_field( http_field::server, "Unit Test" );
  	REQUIRE( 2 == fields.fields_count() );
  
  	REQUIRE( fields.get_field( http_field::server ) == "Unit Test" );
  	REQUIRE( fields.value_of( http_field::server ) == "Unit Test" );
  	REQUIRE( fields.get_field_or( http_field::server, "EMPTY" ) == "Unit Test" );
  
  	fields.append_field( http_field::server, "; Fields Test" );
  	REQUIRE( fields.get_field( http_field::server ) == "Unit Test; Fields Test" );
  	REQUIRE( fields.value_of( http_field::server ) == "Unit Test; Fields Test" );
  	REQUIRE( fields.get_field_or( http_field::server, "EMPTY" ) == "Unit Test; Fields Test" );
  	REQUIRE( fields.get_field( "sERVEr" ) == "Unit Test; Fields Test" );
  	REQUIRE( fields.get_field_or( "SeRveR", "EMPTY" ) == "Unit Test; Fields Test" );
  
  	// Must add nothing.
  	fields.set_field( http_field::field_unspecified, "NOWAY" );
  	REQUIRE( 2 == fields.fields_count() );
  	fields.append_field( http_field::field_unspecified, "STILLNOWAY" );
  	REQUIRE( 2 == fields.fields_count() );
  
  	// Add unspecified field.
  	fields.append_field( "Non-Specified-Field-Unit-Test", "UNSPECIFIED" );
  	REQUIRE( 3 == fields.fields_count() );
  	REQUIRE( fields.get_field( "Non-Specified-Field-Unit-Test" ) == "UNSPECIFIED" );
  
  	fields.append_field( http_field::field_unspecified, "WRONG" );
  	REQUIRE( fields.get_field( "Non-Specified-Field-Unit-Test" ) == "UNSPECIFIED" );
  
  	REQUIRE_THROWS( fields.get_field( http_field::field_unspecified ) );
  
  	REQUIRE( fields.get_field_or( http_field::field_unspecified, "?" ) == "?" );
  
  	{
  		int counter = 0;
  		fields.for_each_field( [&counter](const auto & f) {
  			if( 0 == counter ) {
  				REQUIRE( f.field_id() == http_field::content_type );
  				REQUIRE( f.name() == field_to_string( http_field::content_type ) );
  				REQUIRE( f.value() == "text/plain; charset=utf-8" );
  			}
  			else if( 1 == counter ) {
  				REQUIRE( f.field_id() == http_field::server );
  				REQUIRE( f.name() == field_to_string( http_field::server ) );
  				REQUIRE( f.value() == "Unit Test; Fields Test" );
  			}
  			// Just ignore all other values.
  
  			++counter;
  		} );
  	}
  
  	// Fields that don't exist
  	REQUIRE_FALSE( fields.has_field( http_field::date ) );
  	REQUIRE_FALSE( fields.has_field( http_field::accept_encoding ) );
  	REQUIRE_FALSE( fields.has_field( http_field::authorization ) );
  
  	REQUIRE_THROWS( fields.get_field( http_field::date ) );
  	REQUIRE_THROWS( fields.get_field( http_field::accept_encoding ) );
  	REQUIRE_THROWS( fields.get_field( http_field::authorization ) );
  
  	fields.remove_field( http_field::date );
  	fields.remove_field( http_field::accept_encoding );
  	fields.remove_field( http_field::field_unspecified );
  
  	REQUIRE( 3 == fields.fields_count() );
  
  	fields.remove_field( http_field::content_type );
  	REQUIRE( 2 == fields.fields_count() );
  	fields.remove_field( http_field::server );
  	REQUIRE( 1 == fields.fields_count() );
  }
  
  TEST_CASE( "get_field_or(field_id, value) overloads" ,
  		"[header][get_field_or][by_id][overloads]" )
  {
  	http_header_fields_t fields;
  
  	REQUIRE(
  		fields.get_field_or( http_field::content_type, "default-value" )
  			== "default-value" );
  
  	REQUIRE(
  		fields.get_field_or( http_field::content_type,
  			restinio::string_view_t{ "default-value" } ) == "default-value" );
  
  	std::string dv1{ "default-value" };
  	const std::string dv2{ "default-value" };
  
  	REQUIRE(
  		fields.get_field_or( http_field::content_type, dv1 ) == "default-value" );
  	REQUIRE(
  		fields.get_field_or( http_field::content_type, dv2 ) == "default-value" );
  
  	REQUIRE(
  		fields.get_field_or( http_field::content_type,
  			std::string{ "default-value" } ) == "default-value" );
  
  	{
  		std::string long_value{
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  			"This is a long value to avoid SSO. "
  		};
  		const std::string long_value2{ long_value };
  
  		REQUIRE( long_value == long_value2 );
  		REQUIRE( long_value.data() != long_value2.data() );
  
  		const char * long_value_ptr{ long_value.data() };
  
  		auto v = fields.get_field_or(
  				http_field::content_type, std::move(long_value) );
  		REQUIRE( v == long_value2 );
  		REQUIRE( v.data() == long_value_ptr );
  	}
  }
  
  TEST_CASE( "Working with optional fields (by id)",
  		"[header][opt_fields][by_id]" )
  {
  	http_header_fields_t fields;
  
  	REQUIRE( 0 == fields.fields_count() ); // No fields yet.
  
  	{
  		const auto f = fields.try_get_field( http_field::content_type );
  		REQUIRE( !f );
  	}
  
  	{
  		const auto f = fields.opt_value_of( http_field::content_type );
  		REQUIRE( !f );
  	}
  
  	fields.set_field( "Content-Type", "text/plain" );
  	REQUIRE( 1 == fields.fields_count() );
  
  	{
  		const auto f = fields.try_get_field( http_field::content_type );
  		REQUIRE( f );
  		REQUIRE( *f == "text/plain" );
  	}
  
  	{
  		const auto f = fields.opt_value_of( http_field::content_type );
  		REQUIRE( f );
  		REQUIRE( *f == "text/plain" );
  	}
  }
  
  TEST_CASE( "Working with fields (by http_header_field_t)" , "[header][fields][by_http_header_field_t]" )
  {
  	http_header_fields_t fields;
  
  	fields.set_field( http_header_field_t{ std::string{"Content-Type"}, std::string{ "text/plain"} } );
  	fields.set_field( http_header_field_t{ http_field::server, std::string{"UNIT-TEST"} } );
  
  	REQUIRE( fields.get_field( http_field::content_type ) == "text/plain" );
  	REQUIRE( fields.get_field( "Server" ) == "UNIT-TEST" );
  }
  
  TEST_CASE( "Enumeration of fields" , "[header][fields][for_each]" )
  {
  	http_header_fields_t fields;
  
  	fields.set_field( "Content-Type", "text/plain" );
  	fields.set_field( "Accept-Encoding", "utf-8" );
  	fields.set_field( "Server", "Unknown" );
  
  	REQUIRE( 3 == fields.fields_count() );
  
  	std::set< std::string > names, values;
  
  	fields.for_each_field( [&](const auto & hf) {
  			names.insert( hf.name() );
  			values.insert( hf.value() );
  		} );
  
  	REQUIRE( names == std::set< std::string >{
  			"Content-Type", "Accept-Encoding", "Server"
  		} );
  	REQUIRE( values == std::set< std::string >{
  			"text/plain", "utf-8", "Unknown"
  		} );
  }
  
  TEST_CASE( "Removement of fields" , "[header][fields][remove_field][remove_all_of]" )
  {
  	SECTION( "Remove first (by name)" )
  	{
  		http_header_fields_t fields;
  
  		fields.add_field( "Content-Type", "text/plain" );
  		fields.add_field( "Accept-Encoding", "utf-8" );
  		fields.add_field( "Transfer-Encoding", "gzip" );
  		fields.add_field( "Server", "Unknown" );
  		fields.add_field( "Transfer-Encoding", "chunked" );
  
  		REQUIRE( 5 == fields.fields_count() );
  		
  		REQUIRE( fields.remove_field( "Transfer-Encoding" ) );
  
  		REQUIRE( 4 == fields.fields_count() );
  
  		REQUIRE( "chunked" == fields.get_field( "Transfer-Encoding" ) );
  	}
  
  	SECTION( "Remove first (by id)" )
  	{
  		http_header_fields_t fields;
  
  		fields.add_field( "Content-Type", "text/plain" );
  		fields.add_field( "Accept-Encoding", "utf-8" );
  		fields.add_field( "Transfer-Encoding", "gzip" );
  		fields.add_field( "Server", "Unknown" );
  		fields.add_field( "Transfer-Encoding", "chunked" );
  
  		REQUIRE( 5 == fields.fields_count() );
  		
  		REQUIRE( fields.remove_field( http_field_t::transfer_encoding ) );
  
  		REQUIRE( 4 == fields.fields_count() );
  
  		REQUIRE( "chunked" == fields.get_field( http_field_t::transfer_encoding ) );
  	}
  
  	SECTION( "Remove all of (by name)" )
  	{
  		http_header_fields_t fields;
  
  		fields.add_field( "Content-Type", "text/plain" );
  		fields.add_field( "Accept-Encoding", "utf-8" );
  		fields.add_field( "Transfer-Encoding", "gzip" );
  		fields.add_field( "Server", "Unknown" );
  		fields.add_field( "Transfer-Encoding", "chunked" );
  
  		REQUIRE( 5 == fields.fields_count() );
  		
  		REQUIRE( 2u == fields.remove_all_of( "Transfer-Encoding" ) );
  
  		REQUIRE( 3 == fields.fields_count() );
  
  		REQUIRE( !fields.has_field( "Transfer-Encoding" ) );
  	}
  
  	SECTION( "Remove first (by id)" )
  	{
  		http_header_fields_t fields;
  
  		fields.add_field( "Content-Type", "text/plain" );
  		fields.add_field( "Accept-Encoding", "utf-8" );
  		fields.add_field( "Transfer-Encoding", "gzip" );
  		fields.add_field( "Server", "Unknown" );
  		fields.add_field( "Transfer-Encoding", "chunked" );
  
  		REQUIRE( 5 == fields.fields_count() );
  		
  		REQUIRE( 2u == fields.remove_all_of( http_field_t::transfer_encoding ) );
  
  		REQUIRE( 3 == fields.fields_count() );
  
  		REQUIRE( !fields.has_field( http_field_t::transfer_encoding ) );
  	}
  }
  
  TEST_CASE( "Enumeration of field's values" , "[header][fields][for_each_value_of]" )
  {
  	SECTION( "By name (single value)" )
  	{
  		http_header_fields_t fields;
  
  		fields.set_field( "Content-Type", "text/plain" );
  		fields.set_field( "Accept-Encoding", "utf-8" );
  		fields.set_field( "Server", "Unknown" );
  
  		REQUIRE( 3 == fields.fields_count() );
  
  		std::string expected_content;
  
  		fields.for_each_value_of( "Content-Type",
  			[&](const auto & value) {
  				expected_content.append( value.data(), value.size() );
  				return http_header_fields_t::continue_enumeration();
  			} );
  
  		REQUIRE( "text/plain" == expected_content );
  	}
  
  	SECTION( "By name (multiple values)" )
  	{
  		http_header_fields_t fields;
  
  		fields.add_field( "Content-Language", "en" );
  		fields.add_field( "Accept-Encoding", "utf-8" );
  		fields.add_field( "Server", "Unknown" );
  		fields.add_field( "Content-Language", "ru-RU" );
  
  		REQUIRE( 4 == fields.fields_count() );
  
  		std::string expected_content;
  
  		fields.for_each_value_of( "Content-Language",
  			[&](const auto & value) {
  				if( !expected_content.empty() )
  					expected_content += ", ";
  				expected_content.append( value.data(), value.size() );
  				return http_header_fields_t::continue_enumeration();
  			} );
  
  		REQUIRE( "en, ru-RU" == expected_content );
  	}
  
  	SECTION( "By Id (single value)" )
  	{
  		http_header_fields_t fields;
  
  		fields.set_field( http_field_t::content_type, "text/html" );
  		fields.set_field( http_field_t::accept_encoding, "utf-8" );
  		fields.set_field( http_field_t::server, "Unknown" );
  
  		REQUIRE( 3 == fields.fields_count() );
  
  		std::string expected_content;
  
  		fields.for_each_value_of( http_field_t::content_type,
  			[&](const auto & value) {
  				expected_content.append( value.data(), value.size() );
  				return http_header_fields_t::continue_enumeration();
  			} );
  
  		REQUIRE( "text/html" == expected_content );
  	}
  
  	SECTION( "By name (multiple values)" )
  	{
  		http_header_fields_t fields;
  
  		fields.add_field( http_field_t::content_language, "en" );
  		fields.add_field( http_field_t::accept_encoding, "utf-8" );
  		fields.add_field( http_field_t::server, "Unknown" );
  		fields.add_field( http_field_t::content_language, "ru-RU" );
  
  		REQUIRE( 4 == fields.fields_count() );
  
  		std::string expected_content;
  
  		fields.for_each_value_of( http_field_t::content_language,
  			[&](const auto & value) {
  				if( !expected_content.empty() )
  					expected_content += ", ";
  				expected_content.append( value.data(), value.size() );
  				return http_header_fields_t::continue_enumeration();
  			} );
  
  		REQUIRE( "en, ru-RU" == expected_content );
  	}
  	SECTION( "Mixed case (name/id)" )
  	{
  		http_header_fields_t fields;
  
  		fields.set_field( "Content-Type", "text/plain" );
  		fields.set_field( "Accept-Encoding", "utf-8" );
  		fields.set_field( "Server", "Unknown" );
  
  		REQUIRE( 3 == fields.fields_count() );
  
  		std::string expected_content;
  
  		fields.for_each_value_of( http_field_t::content_type,
  			[&](const auto & value) {
  				expected_content.append( value.data(), value.size() );
  				return http_header_fields_t::continue_enumeration();
  			} );
  
  		REQUIRE( "text/plain" == expected_content );
  	}
  
  	SECTION( "Mixed case (id/name)" )
  	{
  		http_header_fields_t fields;
  
  		fields.set_field( http_field_t::content_type, "text/html" );
  		fields.set_field( http_field_t::accept_encoding, "utf-8" );
  		fields.set_field( http_field_t::server, "Unknown" );
  
  		REQUIRE( 3 == fields.fields_count() );
  
  		std::string expected_content;
  
  		fields.for_each_value_of( "content-type",
  			[&](const auto & value) {
  				expected_content.append( value.data(), value.size() );
  				return http_header_fields_t::continue_enumeration();
  			} );
  
  		REQUIRE( "text/html" == expected_content );
  	}
  }
  
  TEST_CASE( "Working with common header" , "[header][common]" )
  {
  	SECTION( "http version" )
  	{
  		http_header_common_t h;
  		REQUIRE( 1 == h.http_major() );
  		REQUIRE( 1 == h.http_minor() );
  	}
  
  	SECTION( "content length" )
  	{
  		http_header_common_t h;
  		REQUIRE( 0 == h.content_length() );
  
  		h.content_length( 128 );
  		REQUIRE( 128 == h.content_length() );
  	}
  
  	SECTION( "keep alive" )
  	{
  		http_header_common_t h;
  		REQUIRE_FALSE( h.should_keep_alive() );
  
  		h.should_keep_alive( true );
  		REQUIRE( h.should_keep_alive() );
  	}
  }
  
  TEST_CASE( "working with request header" , "[header][request]" )
  {
  	SECTION( "method" )
  	{
  		http_request_header_t h;
  		REQUIRE( http_method_get() == h.method() );
  
  		h.method( http_method_post() );
  		REQUIRE( http_method_post() == h.method() );
  	}
  
  	SECTION( "request target" )
  	{
  		http_request_header_t h;
  		REQUIRE( h.request_target() == "" );
  
  		h.request_target( "/" );
  		REQUIRE( h.request_target() == "/" );
  
  		h.append_request_target( "197", 3 );
  		REQUIRE( h.request_target() == "/197" );
  	}
  }
  
  TEST_CASE( "working with response header" , "[header][response]" )
  {
  	SECTION( "status code" )
  	{
  		http_response_header_t h;
  		REQUIRE( restinio::status_code::ok == h.status_code() );
  
  		h.status_code( restinio::status_code::not_found );
  		REQUIRE( restinio::status_code::not_found == h.status_code() );
  	}
  
  	SECTION( "request target" )
  	{
  		http_response_header_t h;
  		REQUIRE( h.reason_phrase() == "" );
  
  		h.reason_phrase( "OK" );
  		REQUIRE( h.reason_phrase() == "OK" );
  
  		h.reason_phrase( "Not Found" );
  		REQUIRE( h.reason_phrase() == "Not Found" );
  	}
  }
  
  TEST_CASE( "working with string_to_field()" , "[header][string_to_field]" )
  {
  
  #define RESTINIO_FIELD_FROM_STRIN_TEST( field_id, field_name ) \
  	REQUIRE( http_field:: field_id == string_to_field( #field_name ) );
  
  	RESTINIO_FIELD_FROM_STRIN_TEST( a_im,                         A-IM )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept,                       Accept )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept_additions,             Accept-Additions )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept_charset,               Accept-Charset )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept_datetime,              Accept-Datetime )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept_encoding,              Accept-Encoding )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept_features,              Accept-Features )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept_language,              Accept-Language )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept_patch,                 Accept-Patch )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept_post,                  Accept-Post )
  	RESTINIO_FIELD_FROM_STRIN_TEST( accept_ranges,                Accept-Ranges )
  	RESTINIO_FIELD_FROM_STRIN_TEST( age,                          Age )
  	RESTINIO_FIELD_FROM_STRIN_TEST( allow,                        Allow )
  	RESTINIO_FIELD_FROM_STRIN_TEST( alpn,                         ALPN )
  	RESTINIO_FIELD_FROM_STRIN_TEST( alt_svc,                      Alt-Svc )
  	RESTINIO_FIELD_FROM_STRIN_TEST( alt_used,                     Alt-Used )
  	RESTINIO_FIELD_FROM_STRIN_TEST( alternates,                   Alternates )
  	RESTINIO_FIELD_FROM_STRIN_TEST( apply_to_redirect_ref,        Apply-To-Redirect-Ref )
  	RESTINIO_FIELD_FROM_STRIN_TEST( authentication_control,       Authentication-Control )
  	RESTINIO_FIELD_FROM_STRIN_TEST( authentication_info,          Authentication-Info )
  	RESTINIO_FIELD_FROM_STRIN_TEST( authorization,                Authorization )
  	RESTINIO_FIELD_FROM_STRIN_TEST( c_ext,                        C-Ext )
  	RESTINIO_FIELD_FROM_STRIN_TEST( c_man,                        C-Man )
  	RESTINIO_FIELD_FROM_STRIN_TEST( c_opt,                        C-Opt )
  	RESTINIO_FIELD_FROM_STRIN_TEST( c_pep,                        C-PEP )
  	RESTINIO_FIELD_FROM_STRIN_TEST( c_pep_info,                   C-PEP-Info )
  	RESTINIO_FIELD_FROM_STRIN_TEST( cache_control,                Cache-Control )
  	RESTINIO_FIELD_FROM_STRIN_TEST( caldav_timezones,             CalDAV-Timezones )
  	RESTINIO_FIELD_FROM_STRIN_TEST( close,                        Close )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_base,                 Content-Base )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_disposition,          Content-Disposition )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_encoding,             Content-Encoding )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_id,                   Content-ID )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_language,             Content-Language )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_location,             Content-Location )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_md5,                  Content-MD5 )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_range,                Content-Range )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_script_type,          Content-Script-Type )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_style_type,           Content-Style-Type )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_type,                 Content-Type )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_version,              Content-Version )
  	RESTINIO_FIELD_FROM_STRIN_TEST( cookie,                       Cookie )
  	RESTINIO_FIELD_FROM_STRIN_TEST( cookie2,                      Cookie2 )
  	RESTINIO_FIELD_FROM_STRIN_TEST( dasl,                         DASL )
  	RESTINIO_FIELD_FROM_STRIN_TEST( dav,                          DAV )
  	RESTINIO_FIELD_FROM_STRIN_TEST( date,                         Date )
  	RESTINIO_FIELD_FROM_STRIN_TEST( default_style,                Default-Style )
  	RESTINIO_FIELD_FROM_STRIN_TEST( delta_base,                   Delta-Base )
  	RESTINIO_FIELD_FROM_STRIN_TEST( depth,                        Depth )
  	RESTINIO_FIELD_FROM_STRIN_TEST( derived_from,                 Derived-From )
  	RESTINIO_FIELD_FROM_STRIN_TEST( destination,                  Destination )
  	RESTINIO_FIELD_FROM_STRIN_TEST( differential_id,              Differential-ID )
  	RESTINIO_FIELD_FROM_STRIN_TEST( digest,                       Digest )
  	RESTINIO_FIELD_FROM_STRIN_TEST( etag,                         ETag )
  	RESTINIO_FIELD_FROM_STRIN_TEST( expect,                       Expect )
  	RESTINIO_FIELD_FROM_STRIN_TEST( expires,                      Expires )
  	RESTINIO_FIELD_FROM_STRIN_TEST( ext,                          Ext )
  	RESTINIO_FIELD_FROM_STRIN_TEST( forwarded,                    Forwarded )
  	RESTINIO_FIELD_FROM_STRIN_TEST( from,                         From )
  	RESTINIO_FIELD_FROM_STRIN_TEST( getprofile,                   GetProfile )
  	RESTINIO_FIELD_FROM_STRIN_TEST( hobareg,                      Hobareg )
  	RESTINIO_FIELD_FROM_STRIN_TEST( host,                         Host )
  	RESTINIO_FIELD_FROM_STRIN_TEST( http2_settings,               HTTP2-Settings )
  	RESTINIO_FIELD_FROM_STRIN_TEST( im,                           IM )
  	RESTINIO_FIELD_FROM_STRIN_TEST( if_,                          If )
  	RESTINIO_FIELD_FROM_STRIN_TEST( if_match,                     If-Match )
  	RESTINIO_FIELD_FROM_STRIN_TEST( if_modified_since,            If-Modified-Since )
  	RESTINIO_FIELD_FROM_STRIN_TEST( if_none_match,                If-None-Match )
  	RESTINIO_FIELD_FROM_STRIN_TEST( if_range,                     If-Range )
  	RESTINIO_FIELD_FROM_STRIN_TEST( if_schedule_tag_match,        If-Schedule-Tag-Match )
  	RESTINIO_FIELD_FROM_STRIN_TEST( if_unmodified_since,          If-Unmodified-Since )
  	RESTINIO_FIELD_FROM_STRIN_TEST( keep_alive,                   Keep-Alive )
  	RESTINIO_FIELD_FROM_STRIN_TEST( label,                        Label )
  	RESTINIO_FIELD_FROM_STRIN_TEST( last_modified,                Last-Modified )
  	RESTINIO_FIELD_FROM_STRIN_TEST( link,                         Link )
  	RESTINIO_FIELD_FROM_STRIN_TEST( location,                     Location )
  	RESTINIO_FIELD_FROM_STRIN_TEST( lock_token,                   Lock-Token )
  	RESTINIO_FIELD_FROM_STRIN_TEST( man,                          Man )
  	RESTINIO_FIELD_FROM_STRIN_TEST( max_forwards,                 Max-Forwards )
  	RESTINIO_FIELD_FROM_STRIN_TEST( memento_datetime,             Memento-Datetime )
  	RESTINIO_FIELD_FROM_STRIN_TEST( meter,                        Meter )
  	RESTINIO_FIELD_FROM_STRIN_TEST( mime_version,                 MIME-Version )
  	RESTINIO_FIELD_FROM_STRIN_TEST( negotiate,                    Negotiate )
  	RESTINIO_FIELD_FROM_STRIN_TEST( opt,                          Opt )
  	RESTINIO_FIELD_FROM_STRIN_TEST( optional_www_authenticate,    Optional-WWW-Authenticate )
  	RESTINIO_FIELD_FROM_STRIN_TEST( ordering_type,                Ordering-Type )
  	RESTINIO_FIELD_FROM_STRIN_TEST( origin,                       Origin )
  	RESTINIO_FIELD_FROM_STRIN_TEST( overwrite,                    Overwrite )
  	RESTINIO_FIELD_FROM_STRIN_TEST( p3p,                          P3P )
  	RESTINIO_FIELD_FROM_STRIN_TEST( pep,                          PEP )
  	RESTINIO_FIELD_FROM_STRIN_TEST( pics_label,                   PICS-Label )
  	RESTINIO_FIELD_FROM_STRIN_TEST( pep_info,                     Pep-Info )
  	RESTINIO_FIELD_FROM_STRIN_TEST( position,                     Position )
  	RESTINIO_FIELD_FROM_STRIN_TEST( pragma,                       Pragma )
  	RESTINIO_FIELD_FROM_STRIN_TEST( prefer,                       Prefer )
  	RESTINIO_FIELD_FROM_STRIN_TEST( preference_applied,           Preference-Applied )
  	RESTINIO_FIELD_FROM_STRIN_TEST( profileobject,                ProfileObject )
  	RESTINIO_FIELD_FROM_STRIN_TEST( protocol,                     Protocol )
  	RESTINIO_FIELD_FROM_STRIN_TEST( protocol_info,                Protocol-Info )
  	RESTINIO_FIELD_FROM_STRIN_TEST( protocol_query,               Protocol-Query )
  	RESTINIO_FIELD_FROM_STRIN_TEST( protocol_request,             Protocol-Request )
  	RESTINIO_FIELD_FROM_STRIN_TEST( proxy_authenticate,           Proxy-Authenticate )
  	RESTINIO_FIELD_FROM_STRIN_TEST( proxy_authentication_info,    Proxy-Authentication-Info )
  	RESTINIO_FIELD_FROM_STRIN_TEST( proxy_authorization,          Proxy-Authorization )
  	RESTINIO_FIELD_FROM_STRIN_TEST( proxy_features,               Proxy-Features )
  	RESTINIO_FIELD_FROM_STRIN_TEST( proxy_instruction,            Proxy-Instruction )
  	RESTINIO_FIELD_FROM_STRIN_TEST( public_,                      Public )
  	RESTINIO_FIELD_FROM_STRIN_TEST( public_key_pins,              Public-Key-Pins )
  	RESTINIO_FIELD_FROM_STRIN_TEST( public_key_pins_report_only,  Public-Key-Pins-Report-Only )
  	RESTINIO_FIELD_FROM_STRIN_TEST( range,                        Range )
  	RESTINIO_FIELD_FROM_STRIN_TEST( redirect_ref,                 Redirect-Ref )
  	RESTINIO_FIELD_FROM_STRIN_TEST( referer,                      Referer )
  	RESTINIO_FIELD_FROM_STRIN_TEST( retry_after,                  Retry-After )
  	RESTINIO_FIELD_FROM_STRIN_TEST( safe,                         Safe )
  	RESTINIO_FIELD_FROM_STRIN_TEST( schedule_reply,               Schedule-Reply )
  	RESTINIO_FIELD_FROM_STRIN_TEST( schedule_tag,                 Schedule-Tag )
  	RESTINIO_FIELD_FROM_STRIN_TEST( sec_websocket_accept,         Sec-WebSocket-Accept )
  	RESTINIO_FIELD_FROM_STRIN_TEST( sec_websocket_extensions,     Sec-WebSocket-Extensions )
  	RESTINIO_FIELD_FROM_STRIN_TEST( sec_websocket_key,            Sec-WebSocket-Key )
  	RESTINIO_FIELD_FROM_STRIN_TEST( sec_websocket_protocol,       Sec-WebSocket-Protocol )
  	RESTINIO_FIELD_FROM_STRIN_TEST( sec_websocket_version,        Sec-WebSocket-Version )
  	RESTINIO_FIELD_FROM_STRIN_TEST( security_scheme,              Security-Scheme )
  	RESTINIO_FIELD_FROM_STRIN_TEST( server,                       Server )
  	RESTINIO_FIELD_FROM_STRIN_TEST( set_cookie,                   Set-Cookie )
  	RESTINIO_FIELD_FROM_STRIN_TEST( set_cookie2,                  Set-Cookie2 )
  	RESTINIO_FIELD_FROM_STRIN_TEST( setprofile,                   SetProfile )
  	RESTINIO_FIELD_FROM_STRIN_TEST( slug,                         SLUG )
  	RESTINIO_FIELD_FROM_STRIN_TEST( soapaction,                   SoapAction )
  	RESTINIO_FIELD_FROM_STRIN_TEST( status_uri,                   Status-URI )
  	RESTINIO_FIELD_FROM_STRIN_TEST( strict_transport_security,    Strict-Transport-Security )
  	RESTINIO_FIELD_FROM_STRIN_TEST( surrogate_capability,         Surrogate-Capability )
  	RESTINIO_FIELD_FROM_STRIN_TEST( surrogate_control,            Surrogate-Control )
  	RESTINIO_FIELD_FROM_STRIN_TEST( tcn,                          TCN )
  	RESTINIO_FIELD_FROM_STRIN_TEST( te,                           TE )
  	RESTINIO_FIELD_FROM_STRIN_TEST( timeout,                      Timeout )
  	RESTINIO_FIELD_FROM_STRIN_TEST( topic,                        Topic )
  	RESTINIO_FIELD_FROM_STRIN_TEST( trailer,                      Trailer )
  	RESTINIO_FIELD_FROM_STRIN_TEST( transfer_encoding,            Transfer-Encoding )
  	RESTINIO_FIELD_FROM_STRIN_TEST( ttl,                          TTL )
  	RESTINIO_FIELD_FROM_STRIN_TEST( urgency,                      Urgency )
  	RESTINIO_FIELD_FROM_STRIN_TEST( uri,                          URI )
  	RESTINIO_FIELD_FROM_STRIN_TEST( upgrade,                      Upgrade )
  	RESTINIO_FIELD_FROM_STRIN_TEST( user_agent,                   User-Agent )
  	RESTINIO_FIELD_FROM_STRIN_TEST( variant_vary,                 Variant-Vary )
  	RESTINIO_FIELD_FROM_STRIN_TEST( vary,                         Vary )
  	RESTINIO_FIELD_FROM_STRIN_TEST( via,                          Via )
  	RESTINIO_FIELD_FROM_STRIN_TEST( www_authenticate,             WWW-Authenticate )
  	RESTINIO_FIELD_FROM_STRIN_TEST( want_digest,                  Want-Digest )
  	RESTINIO_FIELD_FROM_STRIN_TEST( warning,                      Warning )
  	RESTINIO_FIELD_FROM_STRIN_TEST( x_frame_options,              X-Frame-Options )
  
  	// Since v0.4.7
  	RESTINIO_FIELD_FROM_STRIN_TEST( access_control,               Access-Control )
  	RESTINIO_FIELD_FROM_STRIN_TEST( access_control_allow_credentials, Access-Control-Allow-Credentials )
  	RESTINIO_FIELD_FROM_STRIN_TEST( access_control_allow_headers, Access-Control-Allow-Headers )
  	RESTINIO_FIELD_FROM_STRIN_TEST( access_control_allow_methods, Access-Control-Allow-Methods )
  	RESTINIO_FIELD_FROM_STRIN_TEST( access_control_allow_origin,  Access-Control-Allow-Origin )
  	RESTINIO_FIELD_FROM_STRIN_TEST( access_control_max_age,       Access-Control-Max-Age )
  	RESTINIO_FIELD_FROM_STRIN_TEST( access_control_request_method,    Access-Control-Request-Method )
  	RESTINIO_FIELD_FROM_STRIN_TEST( access_control_request_headers,   Access-Control-Request-Headers )
  	RESTINIO_FIELD_FROM_STRIN_TEST( compliance,                   Compliance )
  	RESTINIO_FIELD_FROM_STRIN_TEST( content_transfer_encoding,    Content-Transfer-Encoding )
  	RESTINIO_FIELD_FROM_STRIN_TEST( cost,                         Cost )
  	RESTINIO_FIELD_FROM_STRIN_TEST( ediint_features,              EDIINT-Features )
  	RESTINIO_FIELD_FROM_STRIN_TEST( message_id,                   Message-ID )
  	RESTINIO_FIELD_FROM_STRIN_TEST( method_check,                 Method-Check )
  	RESTINIO_FIELD_FROM_STRIN_TEST( method_check_expires,         Method-Check-Expires )
  	RESTINIO_FIELD_FROM_STRIN_TEST( non_compliance,               Non-Compliance )
  	RESTINIO_FIELD_FROM_STRIN_TEST( optional,                     Optional )
  	RESTINIO_FIELD_FROM_STRIN_TEST( referer_root,                 Referer-Root )
  	RESTINIO_FIELD_FROM_STRIN_TEST( resolution_hint,              Resolution-Hint )
  	RESTINIO_FIELD_FROM_STRIN_TEST( resolver_location,            Resolver-Location )
  	RESTINIO_FIELD_FROM_STRIN_TEST( subok,                        SubOK )
  	RESTINIO_FIELD_FROM_STRIN_TEST( subst,                        Subst )
  	RESTINIO_FIELD_FROM_STRIN_TEST( title,                        Title )
  	RESTINIO_FIELD_FROM_STRIN_TEST( ua_color,                     UA-Color )
  	RESTINIO_FIELD_FROM_STRIN_TEST( ua_media,                     UA-Media )
  	RESTINIO_FIELD_FROM_STRIN_TEST( ua_pixels,                    UA-Pixels )
  	RESTINIO_FIELD_FROM_STRIN_TEST( ua_resolution,                UA-Resolution )
  	RESTINIO_FIELD_FROM_STRIN_TEST( ua_windowpixels,              UA-Windowpixels )
  	RESTINIO_FIELD_FROM_STRIN_TEST( version,                      Version )
  	RESTINIO_FIELD_FROM_STRIN_TEST( x_device_accept,              X-Device-Accept )
  	RESTINIO_FIELD_FROM_STRIN_TEST( x_device_accept_charset,      X-Device-Accept-Charset )
  	RESTINIO_FIELD_FROM_STRIN_TEST( x_device_accept_encoding,     X-Device-Accept-Encoding )
  	RESTINIO_FIELD_FROM_STRIN_TEST( x_device_accept_language,     X-Device-Accept-Language )
  	RESTINIO_FIELD_FROM_STRIN_TEST( x_device_user_agent,          X-Device-User-Agent )
  #undef RESTINIO_FIELD_FROM_STRIN_TEST
  }
  
  TEST_CASE( "Connection" , "[header][connection]" )
  {
  	using namespace Catch;
  
  	{
  		// Default.
  		http_response_header_t h;
  		const auto serialized =
  			impl::create_header_string( h,
  				impl::content_length_field_presence_t::skip_content_length );
  
  		REQUIRE_THAT(
  			serialized,
  			Contains( "Connection: close" ) ||
  			!Contains( "Content-Length" ) );
  	}
  	{
  		// Default.
  		http_response_header_t h;
  		const auto serialized =
  			impl::create_header_string( h );
  
  		REQUIRE_THAT(
  			serialized,
  			Contains( "Connection: close" ) ||
  			Contains( "Content-Length: 0" ) );
  	}
  
  	{
  		http_response_header_t h;
  		h.should_keep_alive( false );
  		const auto serialized =
  			impl::create_header_string( h );
  
  		REQUIRE_THAT(
  			serialized,
  			Contains( "Connection: close" ) );
  	}
  
  	{
  		http_response_header_t h;
  		h.should_keep_alive( true );
  		const auto serialized =
  			impl::create_header_string( h );
  
  		REQUIRE_THAT(
  			serialized,
  			Contains( "Connection: keep-alive" ) );
  	}
  
  	{
  		http_response_header_t h;
  		h.connection( http_connection_header_t::upgrade );
  		const auto serialized =
  			impl::create_header_string( h );
  
  		REQUIRE_THAT(
  			serialized,
  			Contains( "Connection: Upgrade" ) );
  	}
  }
  
  
  TEST_CASE( "Query" , "[header][query string][query path]" )
  {
  	auto append = []( http_request_header_t & h, const std::string & part ){
  		h.append_request_target( part.data(), part.size() );
  	};
  	// Default.
  	http_request_header_t h;
  
  	h.request_target( "/sobjectizerteam" );
  
  	REQUIRE( h.request_target() == "/sobjectizerteam" );
  	REQUIRE( h.path() == "/sobjectizerteam" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "" );
  
  	append( h, "/json_dto-0.2" );
  
  	REQUIRE( h.request_target() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.path() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "" );
  
  
  
  	append( h, "#markdown-header" );
  
  	REQUIRE( h.request_target() == "/sobjectizerteam/json_dto-0.2#markdown-header" );
  	REQUIRE( h.path() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "markdown-header" );
  
  	append( h, "-what-is-json_dto" );
  
  	REQUIRE( h.request_target() == "/sobjectizerteam/json_dto-0.2#markdown-header-what-is-json_dto" );
  	REQUIRE( h.path() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "markdown-header-what-is-json_dto" );
  
  
  	h.request_target( "/sobjectizerteam/json_dto-0.2#markdown-header-what-is-json_dto" );
  	REQUIRE( h.request_target() == "/sobjectizerteam/json_dto-0.2#markdown-header-what-is-json_dto" );
  
  	REQUIRE( h.path() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "markdown-header-what-is-json_dto" );
  
  
  	h.request_target( "/sobjectizerteam/json_dto-0.2?#" );
  	REQUIRE( h.request_target() == "/sobjectizerteam/json_dto-0.2?#" );
  
  	REQUIRE( h.path() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "" );
  
  	h.request_target( "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.request_target() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.path() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "" );
  
  	append( h, "?" );
  	REQUIRE( h.request_target() == "/sobjectizerteam/json_dto-0.2?" );
  	REQUIRE( h.path() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "" );
  
  	append( h, "#" );
  	REQUIRE( h.request_target() == "/sobjectizerteam/json_dto-0.2?#" );
  	REQUIRE( h.path() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "" );
  
  	append( h, "123" );
  	REQUIRE( h.request_target() == "/sobjectizerteam/json_dto-0.2?#123" );
  	REQUIRE( h.path() == "/sobjectizerteam/json_dto-0.2" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "123" );
  
  
  	h.request_target( "/weather/temperature?from=2012-01-01&to=2012-01-10" );
  	REQUIRE( h.request_target() == "/weather/temperature?from=2012-01-01&to=2012-01-10" );
  	REQUIRE( h.path() == "/weather/temperature" );
  	REQUIRE( h.query() == "from=2012-01-01&to=2012-01-10" );
  	REQUIRE( h.fragment() == "" );
  
  	h.request_target( "/weather/temperature" );
  	append( h, "?" );
  	append( h, "from=2012-01-01" );
  	append( h, "&" );
  	append( h, "to=2012-01-10" );
  	REQUIRE( h.request_target() == "/weather/temperature?from=2012-01-01&to=2012-01-10" );
  	REQUIRE( h.path() == "/weather/temperature" );
  	REQUIRE( h.query() == "from=2012-01-01&to=2012-01-10" );
  	REQUIRE( h.fragment() == "" );
  
  	h.request_target( "/weather/temperature" );
  	append( h, "?" );
  	append( h, "from=2012-01-01" );
  	append( h, "&" );
  	append( h, "to=2012-01-10" );
  	append( h, "#" );
  	append( h, "Celsius" );
  	REQUIRE( h.request_target() == "/weather/temperature?from=2012-01-01&to=2012-01-10#Celsius" );
  	REQUIRE( h.path() == "/weather/temperature" );
  	REQUIRE( h.query() == "from=2012-01-01&to=2012-01-10" );
  	REQUIRE( h.fragment() == "Celsius" );
  
  
  	h.request_target( "/weather/temperature#Celsius?from=2012-01-01&to=2012-01-10" );
  	REQUIRE( h.request_target() == "/weather/temperature#Celsius?from=2012-01-01&to=2012-01-10" );
  	REQUIRE( h.path() == "/weather/temperature" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "Celsius?from=2012-01-01&to=2012-01-10" );
  
  	h.request_target( "/weather" );
  	append( h, "/temperature" );
  	append( h, "#" );
  	append( h, "Celsius" );
  	append( h, "?" );
  	append( h, "from=2012-01-01" );
  	append( h, "&" );
  	append( h, "to=2012-01-10" );
  	REQUIRE( h.request_target() == "/weather/temperature#Celsius?from=2012-01-01&to=2012-01-10" );
  	REQUIRE( h.path() == "/weather/temperature" );
  	REQUIRE( h.query() == "" );
  	REQUIRE( h.fragment() == "Celsius?from=2012-01-01&to=2012-01-10" );
  }
  
  