diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2019-11-12 16:16:37 +0000 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2019-11-12 16:16:37 +0000 | 
| commit | 6bdc9fe7ff98f6d76fc9f959b8c39e993a064216 (patch) | |
| tree | d7d444fd5c0b3385ca18a85b65ffef7835c0e268 | |
| parent | Modernize build (diff) | |
| download | icespider-6bdc9fe7ff98f6d76fc9f959b8c39e993a064216.tar.bz2 icespider-6bdc9fe7ff98f6d76fc9f959b8c39e993a064216.tar.xz icespider-6bdc9fe7ff98f6d76fc9f959b8c39e993a064216.zip | |
Performance fixesicespider-0.6.2
| -rw-r--r-- | icespider/common/pathparts.cpp | 3 | ||||
| -rw-r--r-- | icespider/core/xwwwFormUrlEncoded.h | 2 | ||||
| -rw-r--r-- | icespider/fcgi/cgiRequestBase.cpp | 32 | ||||
| -rw-r--r-- | icespider/fcgi/cgiRequestBase.h | 5 | ||||
| -rw-r--r-- | icespider/testing/testRequest.cpp | 3 | ||||
| -rw-r--r-- | icespider/unittests/testFcgi.cpp | 48 | 
6 files changed, 65 insertions, 28 deletions
| diff --git a/icespider/common/pathparts.cpp b/icespider/common/pathparts.cpp index 16c8d63..aabdd13 100644 --- a/icespider/common/pathparts.cpp +++ b/icespider/common/pathparts.cpp @@ -5,6 +5,7 @@  namespace ba = boost::algorithm;  namespace IceSpider { +	const auto slash = ba::first_finder("/", ba::is_equal());  	Path::Path(const std::string_view & p) :  		path(p)  	{ @@ -12,7 +13,7 @@ namespace IceSpider {  		if (relp.empty()) {  			return;  		} -		for (auto pi = ba::make_split_iterator(relp, ba::first_finder("/", ba::is_equal())); pi != decltype(pi)(); ++pi) { +		for (auto pi = ba::make_split_iterator(relp, slash); pi != decltype(pi)(); ++pi) {  			std::string_view pp(pi->begin(), pi->end() - pi->begin());  			if (pp.front() == '{' && pp.back() == '}') {  				parts.push_back(std::make_unique<PathParameter>(pp)); diff --git a/icespider/core/xwwwFormUrlEncoded.h b/icespider/core/xwwwFormUrlEncoded.h index 20f4ce6..d09b0c4 100644 --- a/icespider/core/xwwwFormUrlEncoded.h +++ b/icespider/core/xwwwFormUrlEncoded.h @@ -8,7 +8,7 @@  namespace IceSpider {  	class XWwwFormUrlEncoded : public Slicer::Deserializer {  		public: -			typedef std::function<void(const std::string &&, const std::string &&)> KVh; +			typedef std::function<void(std::string &&, std::string &&)> KVh;  			XWwwFormUrlEncoded(std::istream & in); diff --git a/icespider/fcgi/cgiRequestBase.cpp b/icespider/fcgi/cgiRequestBase.cpp index ab4d5e8..b6d5a77 100644 --- a/icespider/fcgi/cgiRequestBase.cpp +++ b/icespider/fcgi/cgiRequestBase.cpp @@ -15,9 +15,10 @@ using namespace std::literals;  #define CGI_CONST(NAME) static const std::string_view NAME(#NAME)  namespace IceSpider { -	static const std::string_view amp("&"); -	static const std::string_view semi("; "); -	static const std::string_view HEADER_PREFIX("HTTP_"); +	static const auto slash_pred = boost::algorithm::is_any_of("/"); +	constexpr std::string_view amp("&"); +	constexpr std::string_view semi("; "); +	constexpr std::string_view HEADER_PREFIX("HTTP_");  	CGI_CONST(REDIRECT_URL);  	CGI_CONST(SCRIPT_NAME);  	CGI_CONST(QUERY_STRING); @@ -46,43 +47,32 @@ namespace IceSpider {  	mapVars(const std::string_view & vn, const in & envmap, out & map, const std::string_view & sp) {  		auto qs = envmap.find(vn);  		if (qs != envmap.end()) { -			XWwwFormUrlEncoded::iterateVars(qs->second, [&map](const auto && k, const auto && v) { +			XWwwFormUrlEncoded::iterateVars(qs->second, [&map](auto && k, auto && v) {  				map.emplace(std::move(k), std::move(v));  			}, sp);  		}  	} -	template<typename Ex, typename Map> -	const std::string_view & -	findFirstOrElse(const Map &) -	{ -		throw Ex(); -	} -  	template<typename Ex, typename Map, typename ... Ks>  	const std::string_view &  	findFirstOrElse(const Map & map, const std::string_view & k, const Ks & ... ks)  	{ -		auto i = map.find(k); -		if (i == map.end()) { +		if (const auto i = map.find(k); i != map.end()) { +			return i->second; +		} +		if constexpr (sizeof...(ks)) {  			return findFirstOrElse<Ex>(map, ks...);  		} -		return i->second; -	} - -	bool CgiRequestBase::ciLess::operator() (const std::string_view & s1, const std::string_view & s2) const -	{ -		return lexicographical_compare(s1, s2, ba::is_iless()); +		throw Ex();  	}  	void  	CgiRequestBase::initialize()  	{ -		namespace ba = boost::algorithm;  		if (auto path = findFirstOrElse<Http400_BadRequest>(envmap, REDIRECT_URL, SCRIPT_NAME).substr(1);  				// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)  				!path.empty()) { -			ba::split(pathElements, path, ba::is_any_of("/"), ba::token_compress_off); +			ba::split(pathElements, path, slash_pred, ba::token_compress_off);  		}  		mapVars(QUERY_STRING, envmap, qsmap, amp); diff --git a/icespider/fcgi/cgiRequestBase.h b/icespider/fcgi/cgiRequestBase.h index fca2e41..88bc473 100644 --- a/icespider/fcgi/cgiRequestBase.h +++ b/icespider/fcgi/cgiRequestBase.h @@ -14,11 +14,8 @@ namespace IceSpider {  			void initialize();  		public: -			struct ciLess { -				bool operator()(const std::string_view & s1, const std::string_view & s2) const; -			};  			typedef std::map<std::string_view, const std::string_view> VarMap; -			typedef std::map<std::string_view, const std::string_view, ciLess> HdrMap; +			typedef std::map<std::string_view, const std::string_view, Slicer::case_less> HdrMap;  			const PathElements & getRequestPath() const override;  			PathElements & getRequestPath() override; diff --git a/icespider/testing/testRequest.cpp b/icespider/testing/testRequest.cpp index b866308..080c07e 100644 --- a/icespider/testing/testRequest.cpp +++ b/icespider/testing/testRequest.cpp @@ -4,6 +4,7 @@  #include <formatters.h>  namespace IceSpider { +	constexpr std::string_view slash("/");  	TestRequest::TestRequest(const Core * c, HttpMethod m, const std::string_view & p) :  		IHttpRequest(c),  		method(m) @@ -13,7 +14,7 @@ namespace IceSpider {  		// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)  		if (!path.empty()) {  			// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) -			ba::split(url, path, ba::is_any_of("/"), ba::token_compress_off); +			ba::split(url, path, ba::is_any_of(slash), ba::token_compress_off);  		}  	} diff --git a/icespider/unittests/testFcgi.cpp b/icespider/unittests/testFcgi.cpp index d543678..c77edeb 100644 --- a/icespider/unittests/testFcgi.cpp +++ b/icespider/unittests/testFcgi.cpp @@ -258,6 +258,54 @@ BOOST_AUTO_TEST_CASE( postxwwwformurlencoded_simple )  	BOOST_REQUIRE_EQUAL(314, n);  } +BOOST_AUTO_TEST_CASE( reqParsePerf ) +{ +	CharPtrPtrArray env ({ +		"CONTEXT_DOCUMENT_ROOT=/var/www/shared/vhosts/sys.randomdan.homeip.net", +		"CONTEXT_PREFIX=", +		"DOCUMENT_ROOT=/var/www/shared/vhosts/sys.randomdan.homeip.net", +		"GATEWAY_INTERFACE=CGI/1.1", +		"H2PUSH=on", +		"H2_PUSH=on", +		"H2_PUSHED=", +		"H2_PUSHED_ON=", +		"H2_STREAM_ID=1", +		"H2_STREAM_TAG=137-1", +		"HTTP2=on", +		"HTTPS=on", +		"HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", +		"HTTP_ACCEPT_ENCODING=gzip, deflate, br", +		"HTTP_ACCEPT_LANGUAGE=en,en-GB;q=0.9", +		"HTTP_HOST=sys.randomdan.homeip.net", +		"HTTP_SEC_FETCH_SITE=none", +		"HTTP_UPGRADE_INSECURE_REQUESTS=1", +		"HTTP_USER_AGENT=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", +		"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", +		"PWD=/var/www/shared/files/localhost", +		"QUERY_STRING=", +		"REMOTE_ADDR=10.10.0.189", +		"REMOTE_PORT=44030", +		"REQUEST_METHOD=GET", +		"REQUEST_SCHEME=https", +		"REQUEST_URI=/env.cgi", +		"SCRIPT_FILENAME=/var/www/shared/vhosts/sys.randomdan.homeip.net/env.cgi", +		"SCRIPT_NAME=/env.cgi", +		"SERVER_ADDR=fdc7:602:e9c5:b8f0::3", +		"SERVER_ADMIN=dan.goodliffe@randomdan.homeip.net", +		"SERVER_NAME=sys.randomdan.homeip.net", +		"SERVER_PORT=443", +		"SERVER_PROTOCOL=HTTP/2.0", +		"SERVER_SIGNATURE=<address>Apache/2.4.41 (Gentoo) mod_fcgid/2.3.9 PHP/7.2.23 OpenSSL/1.1.1d mod_perl/2.0.10 Perl/v5.30.0 Server at sys.randomdan.homeip.net Port 443</address>", +		"SERVER_SOFTWARE=Apache/2.4.41 (Gentoo) mod_fcgid/2.3.9 PHP/7.2.23 OpenSSL/1.1.1d mod_perl/2.0.10 Perl/v5.30.0", +		"SHLVL=0", +		"SSL_TLS_SNI=sys.randomdan.homeip.net", +	}); +	for (int x = 0; x < 10000; x +=1) { +		TestRequest req(this, env); +	} +} + +  BOOST_AUTO_TEST_CASE( postxwwwformurlencoded_dictionary )  {  	CharPtrPtrArray env ({ "SCRIPT_NAME=/", "REQUEST_METHOD=No", "CONTENT_TYPE=application/x-www-form-urlencoded" }); | 
