diff options
| -rw-r--r-- | icespider/core/ihttpRequest.cpp | 19 | ||||
| -rw-r--r-- | icespider/unittests/testAccept.cpp | 30 | 
2 files changed, 39 insertions, 10 deletions
diff --git a/icespider/core/ihttpRequest.cpp b/icespider/core/ihttpRequest.cpp index 873c96b..97cdcd7 100644 --- a/icespider/core/ihttpRequest.cpp +++ b/icespider/core/ihttpRequest.cpp @@ -76,7 +76,7 @@ namespace IceSpider {  		while (!acceptHdr.empty()) {  			const auto group = upto(acceptHdr, "/", true).first; -			const auto [type, tc] = upto(acceptHdr, ";,", false); +			auto [type, tc] = upto(acceptHdr, ";,", false);  			Accept a;  			if (type != "*") {  				a.type.emplace(type); @@ -87,15 +87,16 @@ namespace IceSpider {  			else if (a.type) {  				throw Http400_BadRequest();  			} -			if (tc == ';') { -				if (upto(acceptHdr, "=", true).first != "q") { -					throw Http400_BadRequest(); -				} -				const auto qs = upto(acceptHdr, ",", false).first; -				a.q = std::strtof(std::string(qs).c_str(), nullptr); -				if (a.q <= 0.0F || a.q > 1.0F) { -					throw Http400_BadRequest(); +			while (tc == ';') { +				const auto paramName = upto(acceptHdr, "=", true); +				const auto paramValue = upto(acceptHdr, ",;", false); +				if (paramName.first == "q") { +					a.q = std::strtof(std::string(paramValue.first).c_str(), nullptr); +					if (a.q <= 0.0F || a.q > 1.0F) { +						throw Http400_BadRequest(); +					}  				} +				tc = paramValue.second;  			}  			accepts.push_back(a);  		} diff --git a/icespider/unittests/testAccept.cpp b/icespider/unittests/testAccept.cpp index cacb01e..67b1411 100644 --- a/icespider/unittests/testAccept.cpp +++ b/icespider/unittests/testAccept.cpp @@ -37,7 +37,6 @@ BOOST_DATA_TEST_CASE(bad_requests,  				" text / plain ; q = ",  				" text / plain ; q = 0.0 ",  				" text / plain ; q = 1.1 ", -				" text / plain ; f = 0.1 ",  		}),  		a)  { @@ -120,3 +119,32 @@ BOOST_DATA_TEST_CASE(q1,  		}  	}  } + +BOOST_DATA_TEST_CASE(extra_params_q_half, +		make({ +				"a/a;q=0.5", +				"a/a;v=1;q=0.5", +				"a/a;q=0.5;v=1", +				"a/a;p=1;q=0.5;v=1", +				"a/a;v=string;q=0.5", +		}), +		a) +{ +	auto all = parse(a); +	for (const auto & accept : all) { +		BOOST_TEST_CONTEXT(accept) { +			BOOST_CHECK_CLOSE(accept.q, 0.5, 0.1); +		} +	} +} + +BOOST_DATA_TEST_CASE(samples, +		make({ +				// From Chromium, causes HTTP 400 in v0.7, unexpected param `v` +				"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/" +				"*;q=0.8,application/signed-exchange;v=b3;q=0.9", +		}), +		a) +{ +	BOOST_CHECK_NO_THROW(parse(a)); +}  | 
