summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2019-11-12 16:16:37 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2019-11-12 16:16:37 +0000
commit6bdc9fe7ff98f6d76fc9f959b8c39e993a064216 (patch)
treed7d444fd5c0b3385ca18a85b65ffef7835c0e268
parentModernize build (diff)
downloadicespider-6bdc9fe7ff98f6d76fc9f959b8c39e993a064216.tar.bz2
icespider-6bdc9fe7ff98f6d76fc9f959b8c39e993a064216.tar.xz
icespider-6bdc9fe7ff98f6d76fc9f959b8c39e993a064216.zip
Performance fixesicespider-0.6.2
-rw-r--r--icespider/common/pathparts.cpp3
-rw-r--r--icespider/core/xwwwFormUrlEncoded.h2
-rw-r--r--icespider/fcgi/cgiRequestBase.cpp32
-rw-r--r--icespider/fcgi/cgiRequestBase.h5
-rw-r--r--icespider/testing/testRequest.cpp3
-rw-r--r--icespider/unittests/testFcgi.cpp48
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" });