diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-07-26 17:46:58 +0100 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-07-26 18:23:40 +0100 | 
| commit | 15a699fe507323d93f76dcff9af4f013d7965730 (patch) | |
| tree | 920ab218d28937fd129fb2035190d2623d4142e6 | |
| parent | getInput/OutputStream should be no discard (diff) | |
| download | icespider-15a699fe507323d93f76dcff9af4f013d7965730.tar.bz2 icespider-15a699fe507323d93f76dcff9af4f013d7965730.tar.xz icespider-15a699fe507323d93f76dcff9af4f013d7965730.zip | |
Simplified passing of CGI environment data
| -rw-r--r-- | icespider/fcgi/cgiRequest.cpp | 7 | ||||
| -rw-r--r-- | icespider/fcgi/cgiRequestBase.cpp | 8 | ||||
| -rw-r--r-- | icespider/fcgi/cgiRequestBase.h | 7 | ||||
| -rw-r--r-- | icespider/fcgi/fcgiRequest.cpp | 2 | ||||
| -rw-r--r-- | icespider/unittests/testFcgi.cpp | 231 | ||||
| -rw-r--r-- | icespider/unittests/testPerf.cpp | 15 | 
6 files changed, 119 insertions, 151 deletions
| diff --git a/icespider/fcgi/cgiRequest.cpp b/icespider/fcgi/cgiRequest.cpp index d416280..6dd5391 100644 --- a/icespider/fcgi/cgiRequest.cpp +++ b/icespider/fcgi/cgiRequest.cpp @@ -1,12 +1,11 @@  #include "cgiRequest.h"  #include <iostream> +#include <span>  namespace IceSpider { -	CgiRequest::CgiRequest(Core * c, int argc, char ** argv, char ** env) : CgiRequestBase(c, env) +	CgiRequest::CgiRequest(Core * c, int argc, char ** argv, char ** env) : +		CgiRequestBase(c, EnvNTL {env}, EnvArray {argv, static_cast<size_t>(argc)})  	{ -		for (; argc > 0;) { -			addenv(argv[--argc]); -		}  		initialize();  	} diff --git a/icespider/fcgi/cgiRequestBase.cpp b/icespider/fcgi/cgiRequestBase.cpp index 5cefc4e..a403317 100644 --- a/icespider/fcgi/cgiRequestBase.cpp +++ b/icespider/fcgi/cgiRequestBase.cpp @@ -33,10 +33,12 @@ namespace IceSpider {  	CGI_CONST(HTTP_COOKIE);  	CGI_CONST(REQUEST_METHOD); -	CgiRequestBase::CgiRequestBase(Core * c, const char * const * const env) : IHttpRequest(c) +	CgiRequestBase::CgiRequestBase(Core * c, const EnvArray envs, const EnvArray extra) : IHttpRequest(c)  	{ -		for (const char * const * e = env; *e; ++e) { -			addenv(*e); +		for (const auto & envdata : {envs, extra}) { +			for (const auto & e : envdata) { +				addenv(e); +			}  		}  	} diff --git a/icespider/fcgi/cgiRequestBase.h b/icespider/fcgi/cgiRequestBase.h index a7cc52d..1d91ea4 100644 --- a/icespider/fcgi/cgiRequestBase.h +++ b/icespider/fcgi/cgiRequestBase.h @@ -6,6 +6,7 @@  #include <ihttpRequest.h>  #include <iosfwd>  #include <maybeString.h> +#include <span>  #include <string_view>  // IWYU pragma: no_forward_declare AdHoc::case_less @@ -15,7 +16,11 @@ namespace IceSpider {  	class CgiRequestBase : public IHttpRequest {  	protected: -		CgiRequestBase(Core * c, const char * const * const env); +		using EnvArray = std::span<const char * const>; +		// Null terminated list, bsv will handle this and is convertible to span +		using EnvNTL = std::basic_string_view<const char * const>; + +		CgiRequestBase(Core * c, const EnvArray envs, const EnvArray extra = {});  		void addenv(const std::string_view);  		void initialize(); diff --git a/icespider/fcgi/fcgiRequest.cpp b/icespider/fcgi/fcgiRequest.cpp index 5692c65..2c467a7 100644 --- a/icespider/fcgi/fcgiRequest.cpp +++ b/icespider/fcgi/fcgiRequest.cpp @@ -2,7 +2,7 @@  namespace IceSpider {  	FcgiRequest::FcgiRequest(Core * c, FCGX_Request * r) : -		CgiRequestBase(c, r->envp), inputbuf(r->in), input(&inputbuf), outputbuf(r->out), output(&outputbuf) +		CgiRequestBase(c, EnvNTL {r->envp}), inputbuf(r->in), input(&inputbuf), outputbuf(r->out), output(&outputbuf)  	{  		initialize();  	} diff --git a/icespider/unittests/testFcgi.cpp b/icespider/unittests/testFcgi.cpp index e77e954..591ce78 100644 --- a/icespider/unittests/testFcgi.cpp +++ b/icespider/unittests/testFcgi.cpp @@ -53,7 +53,7 @@ namespace std {  class TestRequest : public IceSpider::CgiRequestBase {  public: -	TestRequest(IceSpider::Core * c, char ** env) : IceSpider::CgiRequestBase(c, env) +	TestRequest(IceSpider::Core * c, const EnvArray env) : IceSpider::CgiRequestBase(c, env)  	{  		initialize();  	} @@ -79,7 +79,7 @@ public:  class TestPayloadRequest : public TestRequest {  public: -	TestPayloadRequest(IceSpider::Core * c, char ** env, std::istream & s) : TestRequest(c, env), in(s) +	TestPayloadRequest(IceSpider::Core * c, const EnvArray env, std::istream & s) : TestRequest(c, env), in(s)  	{  		initialize();  	} @@ -94,37 +94,6 @@ private:  	std::istream & in;  }; -// NOLINTNEXTLINE(hicpp-special-member-functions) -class CharPtrPtrArray : public std::vector<char *> { -public: -	CharPtrPtrArray() -	{ -		push_back(nullptr); -	} - -	explicit CharPtrPtrArray(const std::vector<std::string> & a) -	{ -		for (const auto & e : a) { -			push_back(strdup(e.c_str())); -		} -		push_back(nullptr); -	} - -	~CharPtrPtrArray() -	{ -		for (const auto & e : *this) { -			// NOLINTNEXTLINE(hicpp-no-malloc) -			free(e); -		} -	} - -	// NOLINTNEXTLINE(hicpp-explicit-conversions) -	operator char **() -	{ -		return &front(); -	} -}; -  namespace std {  	// LCOV_EXCL_START assert failure helper only  	static std::ostream & @@ -143,63 +112,51 @@ BOOST_FIXTURE_TEST_SUITE(CgiRequestBase, IceSpider::CoreWithDefaultRouter);  BOOST_AUTO_TEST_CASE(NoEnvironment)  { -	BOOST_REQUIRE_THROW( -			{ -				CharPtrPtrArray env; -				TestRequest r(this, env); -			}, -			IceSpider::Http400_BadRequest); +	BOOST_REQUIRE_THROW({ TestRequest r(this, {}); }, IceSpider::Http400_BadRequest);  }  BOOST_AUTO_TEST_CASE(script_name_root)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/"}});  	BOOST_REQUIRE(r.getRequestPath().empty());  	BOOST_CHECK(!r.isSecure());  }  BOOST_AUTO_TEST_CASE(script_name_root_https)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "HTTPS=on"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/", "HTTPS=on"}});  	BOOST_REQUIRE(r.getRequestPath().empty());  	BOOST_CHECK(r.isSecure());  }  BOOST_AUTO_TEST_CASE(redirect_uri_root)  { -	CharPtrPtrArray env({"REDIRECT_URL=/"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"REDIRECT_URL=/"}});  	BOOST_REQUIRE(r.getRequestPath().empty());  }  BOOST_AUTO_TEST_CASE(script_name_foobar)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/foo/bar"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/foo/bar"}});  	BOOST_REQUIRE_EQUAL(IceSpider::PathElements({"foo", "bar"}), r.getRequestPath());  }  BOOST_AUTO_TEST_CASE(query_string_empty)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/foo/bar", "QUERY_STRING="}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/foo/bar", "QUERY_STRING="}});  	BOOST_REQUIRE(!r.getQueryStringParam(""));  }  BOOST_AUTO_TEST_CASE(query_string_one)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1"}});  	BOOST_REQUIRE(!r.getQueryStringParam(""));  	BOOST_REQUIRE_EQUAL("1", *r.getQueryStringParam("one"));  }  BOOST_AUTO_TEST_CASE(query_string_two)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1&two=2"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1&two=2"}});  	BOOST_REQUIRE(!r.getQueryStringParam(""));  	BOOST_REQUIRE_EQUAL("1", *r.getQueryStringParam("one"));  	BOOST_REQUIRE_EQUAL("2", *r.getQueryStringParam("two")); @@ -207,8 +164,7 @@ BOOST_AUTO_TEST_CASE(query_string_two)  BOOST_AUTO_TEST_CASE(query_string_three)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1&two=2&three=3"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1&two=2&three=3"}});  	BOOST_REQUIRE(!r.getQueryStringParam(""));  	BOOST_REQUIRE_EQUAL("1", *r.getQueryStringParam("one"));  	BOOST_REQUIRE_EQUAL("2", *r.getQueryStringParam("two")); @@ -217,8 +173,7 @@ BOOST_AUTO_TEST_CASE(query_string_three)  BOOST_AUTO_TEST_CASE(query_string_urlencoding)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/foo/bar", "QUERY_STRING=url+%65ncoded=%53tring%2e"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/foo/bar", "QUERY_STRING=url+%65ncoded=%53tring%2e"}});  	BOOST_REQUIRE(!r.getQueryStringParam(""));  	BOOST_REQUIRE(r.getQueryStringParam("url encoded"));  	BOOST_REQUIRE_EQUAL("String.", *r.getQueryStringParam("url encoded")); @@ -226,8 +181,7 @@ BOOST_AUTO_TEST_CASE(query_string_urlencoding)  BOOST_AUTO_TEST_CASE(query_string_three_emptyVal)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1&two=&three=3"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1&two=&three=3"}});  	BOOST_REQUIRE(!r.getQueryStringParam(""));  	BOOST_REQUIRE_EQUAL("1", *r.getQueryStringParam("one"));  	BOOST_REQUIRE_EQUAL("", *r.getQueryStringParam("two")); @@ -236,8 +190,7 @@ BOOST_AUTO_TEST_CASE(query_string_three_emptyVal)  BOOST_AUTO_TEST_CASE(query_string_three_noVal)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1&two&three=3"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/foo/bar", "QUERY_STRING=one=1&two&three=3"}});  	BOOST_REQUIRE(!r.getQueryStringParam(""));  	BOOST_REQUIRE_EQUAL("1", *r.getQueryStringParam("one"));  	BOOST_REQUIRE_EQUAL("", *r.getQueryStringParam("two")); @@ -246,112 +199,116 @@ BOOST_AUTO_TEST_CASE(query_string_three_noVal)  BOOST_AUTO_TEST_CASE(requestmethod_get)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "REQUEST_METHOD=GET"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/", "REQUEST_METHOD=GET"}});  	BOOST_REQUIRE_EQUAL(IceSpider::HttpMethod::GET, r.getRequestMethod());  }  BOOST_AUTO_TEST_CASE(requestmethod_post)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "REQUEST_METHOD=POST"}); -	TestRequest r(this, env); +	TestRequest r {this, {{"SCRIPT_NAME=/", "REQUEST_METHOD=POST"}}};  	BOOST_REQUIRE_EQUAL(IceSpider::HttpMethod::POST, r.getRequestMethod());  }  BOOST_AUTO_TEST_CASE(requestmethod_bad)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "REQUEST_METHOD=No"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/", "REQUEST_METHOD=No"}});  	BOOST_REQUIRE_THROW((void)r.getRequestMethod(), IceSpider::Http405_MethodNotAllowed);  }  BOOST_AUTO_TEST_CASE(requestmethod_missing)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/"}); -	TestRequest r(this, env); +	TestRequest r {this, {{"SCRIPT_NAME=/"}}};  	BOOST_REQUIRE_THROW((void)r.getRequestMethod(), IceSpider::Http400_BadRequest);  }  BOOST_AUTO_TEST_CASE(acceptheader)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "HTTP_ACCEPT=text/html"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/", "HTTP_ACCEPT=text/html"}});  	BOOST_REQUIRE_EQUAL("text/html", *r.getHeaderParam("ACCEPT"));  	BOOST_REQUIRE_EQUAL("text/html", *r.getHeaderParam(IceSpider::H::ACCEPT));  }  BOOST_AUTO_TEST_CASE(missingheader)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "HTTP_ACCEPT=text/html"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/", "HTTP_ACCEPT=text/html"}});  	BOOST_REQUIRE(!r.getHeaderParam("ACCEPT_LANGUAGE"));  }  BOOST_AUTO_TEST_CASE(postxwwwformurlencoded_simple)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "REQUEST_METHOD=No", "CONTENT_TYPE=application/x-www-form-urlencoded"});  	std::stringstream f("value=314"); -	TestPayloadRequest r(this, env, f); +	TestPayloadRequest r(this, +			{{ +					"SCRIPT_NAME=/", +					"REQUEST_METHOD=No", +					"CONTENT_TYPE=application/x-www-form-urlencoded", +			}}, +			f);  	auto n = r.getBody<int>();  	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); +		TestRequest req(this, +				{{ +						"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", +				}});  	}  }  BOOST_AUTO_TEST_CASE(postxwwwformurlencoded_dictionary)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "REQUEST_METHOD=No", "CONTENT_TYPE=application/x-www-form-urlencoded"});  	std::stringstream f("alpha=abcde&number=3.14&boolean=true&spaces=This+is+a%20string.&empty="); -	TestPayloadRequest r(this, env, f); +	TestPayloadRequest r(this, +			{{ +					"SCRIPT_NAME=/", +					"REQUEST_METHOD=No", +					"CONTENT_TYPE=application/x-www-form-urlencoded", +			}}, +			f);  	auto n = *r.getBody<IceSpider::StringMap>();  	BOOST_REQUIRE_EQUAL(5, n.size());  	BOOST_REQUIRE_EQUAL("abcde", n["alpha"]); @@ -363,9 +320,14 @@ BOOST_AUTO_TEST_CASE(postxwwwformurlencoded_dictionary)  BOOST_AUTO_TEST_CASE(postxwwwformurlencoded_complex)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "REQUEST_METHOD=No", "CONTENT_TYPE=application/x-www-form-urlencoded"});  	std::stringstream f("alpha=abcde&number=3.14&boolean=true&empty=&spaces=This+is+a%20string."); -	TestPayloadRequest r(this, env, f); +	TestPayloadRequest r(this, +			{{ +					"SCRIPT_NAME=/", +					"REQUEST_METHOD=No", +					"CONTENT_TYPE=application/x-www-form-urlencoded", +			}}, +			f);  	auto n = *r.getBody<TestFcgi::ComplexPtr>();  	BOOST_REQUIRE_EQUAL("abcde", n->alpha);  	BOOST_REQUIRE_EQUAL(3.14, n->number); @@ -376,9 +338,8 @@ BOOST_AUTO_TEST_CASE(postxwwwformurlencoded_complex)  BOOST_AUTO_TEST_CASE(postjson_complex)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "REQUEST_METHOD=No", "CONTENT_TYPE=application/json"}); -	std::stringstream f(R"J({"alpha":"abcde","number":3.14,"boolean":true,"empty":"","spaces":"This is a string."})J"); -	TestPayloadRequest r(this, env, f); +	std::stringstream f {R"J({"alpha":"abcde","number":3.14,"boolean":true,"empty":"","spaces":"This is a string."})J"}; +	TestPayloadRequest r(this, {{"SCRIPT_NAME=/", "REQUEST_METHOD=No", "CONTENT_TYPE=application/json"}}, f);  	auto n = *r.getBody<TestFcgi::ComplexPtr>();  	BOOST_REQUIRE_EQUAL("abcde", n->alpha);  	BOOST_REQUIRE_EQUAL(3.14, n->number); @@ -389,10 +350,9 @@ BOOST_AUTO_TEST_CASE(postjson_complex)  BOOST_AUTO_TEST_CASE(postjson_dictionary)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "REQUEST_METHOD=No", "CONTENT_TYPE=application/json"});  	std::stringstream f(  			R"J({"alpha":"abcde","number":"3.14","boolean":"true","empty":"","spaces":"This is a string."})J"); -	TestPayloadRequest r(this, env, f); +	TestPayloadRequest r(this, {{"SCRIPT_NAME=/", "REQUEST_METHOD=No", "CONTENT_TYPE=application/json"}}, f);  	auto n = *r.getBody<IceSpider::StringMap>();  	BOOST_REQUIRE_EQUAL(5, n.size());  	BOOST_REQUIRE_EQUAL("abcde", n["alpha"]); @@ -404,9 +364,13 @@ BOOST_AUTO_TEST_CASE(postjson_dictionary)  BOOST_AUTO_TEST_CASE(cookies)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/", "REQUEST_METHOD=No", "CONTENT_TYPE=application/json", -			"HTTP_COOKIE=valueA=1234; value+B=Something+with+spaces."}); -	TestRequest r(this, env); +	TestRequest r(this, +			{{ +					"SCRIPT_NAME=/", +					"REQUEST_METHOD=No", +					"CONTENT_TYPE=application/json", +					"HTTP_COOKIE=valueA=1234; value+B=Something+with+spaces.", +			}});  	BOOST_REQUIRE_EQUAL(1234, *r.IceSpider::IHttpRequest::getCookieParam<Ice::Int>("valueA"));  	BOOST_REQUIRE_EQUAL("Something with spaces.", *r.IceSpider::IHttpRequest::getCookieParam<std::string>("value B"));  	BOOST_REQUIRE(!r.IceSpider::IHttpRequest::getCookieParam<Ice::Int>("notAThing")); @@ -418,8 +382,7 @@ BOOST_AUTO_TEST_CASE(cookies)  BOOST_AUTO_TEST_CASE(response)  { -	CharPtrPtrArray env({"SCRIPT_NAME=/"}); -	TestRequest r(this, env); +	TestRequest r(this, {{"SCRIPT_NAME=/"}});  	r.response(200, "OK");  	BOOST_REQUIRE_EQUAL("Status: 200 OK\r\n\r\n", r.out.str());  } diff --git a/icespider/unittests/testPerf.cpp b/icespider/unittests/testPerf.cpp index 7a24faf..91ce437 100644 --- a/icespider/unittests/testPerf.cpp +++ b/icespider/unittests/testPerf.cpp @@ -8,7 +8,7 @@  class TestRequest : public IceSpider::CgiRequestBase {  public: -	TestRequest(IceSpider::Core * c, char ** env) : IceSpider::CgiRequestBase(c, env) +	TestRequest(IceSpider::Core * c, const EnvArray env) : IceSpider::CgiRequestBase(c, env)  	{  		initialize();  	} @@ -44,7 +44,6 @@ public:  			std::getline(f, line, '\n');  			push_back(strdup(line.c_str()));  		} -		push_back(nullptr);  	}  	~CharPtrPtrArray() @@ -62,14 +61,14 @@ BENCHMARK_F(CoreFixture, script_name_root)(benchmark::State & state)  {  	CharPtrPtrArray env(rootDir / "fixtures/env1");  	for (auto _ : state) { -		TestRequest r(this, &env.front()); +		TestRequest r(this, env);  	}  }  BENCHMARK_F(CoreFixture, is_secure)(benchmark::State & state)  {  	CharPtrPtrArray env(rootDir / "fixtures/env1"); -	TestRequest r(this, &env.front()); +	TestRequest r(this, env);  	for (auto _ : state) {  		benchmark::DoNotOptimize(r.isSecure());  	} @@ -78,7 +77,7 @@ BENCHMARK_F(CoreFixture, is_secure)(benchmark::State & state)  BENCHMARK_F(CoreFixture, get_env_param)(benchmark::State & state)  {  	CharPtrPtrArray env(rootDir / "fixtures/env1"); -	TestRequest r(this, &env.front()); +	TestRequest r(this, env);  	for (auto _ : state) {  		benchmark::DoNotOptimize(r.getEnv("REMOTE_PORT"));  	} @@ -87,7 +86,7 @@ BENCHMARK_F(CoreFixture, get_env_param)(benchmark::State & state)  BENCHMARK_F(CoreFixture, get_header_param)(benchmark::State & state)  {  	CharPtrPtrArray env(rootDir / "fixtures/env1"); -	TestRequest r(this, &env.front()); +	TestRequest r(this, env);  	for (auto _ : state) {  		benchmark::DoNotOptimize(r.getHeaderParam("user_agent"));  	} @@ -96,7 +95,7 @@ BENCHMARK_F(CoreFixture, get_header_param)(benchmark::State & state)  BENCHMARK_F(CoreFixture, get_query_string_param)(benchmark::State & state)  {  	CharPtrPtrArray env(rootDir / "fixtures/env1"); -	TestRequest r(this, &env.front()); +	TestRequest r(this, env);  	for (auto _ : state) {  		benchmark::DoNotOptimize(r.getQueryStringParam("utm_source"));  	} @@ -105,7 +104,7 @@ BENCHMARK_F(CoreFixture, get_query_string_param)(benchmark::State & state)  BENCHMARK_F(CoreFixture, get_cookie_param)(benchmark::State & state)  {  	CharPtrPtrArray env(rootDir / "fixtures/env1"); -	TestRequest r(this, &env.front()); +	TestRequest r(this, env);  	for (auto _ : state) {  		benchmark::DoNotOptimize(r.getQueryStringParam("utm_source"));  	} | 
