Testing performance enhancements by enabling transformations cache

Also reduce the utilization of dynamic cast.
This commit is contained in:
Felipe Zimmerle 2015-11-04 00:28:04 -03:00
parent e641c3cc17
commit 2ee5d4ca8f
12 changed files with 80 additions and 17 deletions

View File

@ -36,6 +36,7 @@ class Action {
: action_kind(2), : action_kind(2),
action(_action), action(_action),
name(_action), name(_action),
m_isNone(false),
temporaryAction(false) { temporaryAction(false) {
name.erase(0, 2); name.erase(0, 2);
} }
@ -43,6 +44,7 @@ class Action {
: action_kind(kind), : action_kind(kind),
action(_action), action(_action),
name(_action), name(_action),
m_isNone(false),
temporaryAction(false) { temporaryAction(false) {
name.erase(0, 2); name.erase(0, 2);
} }
@ -94,6 +96,7 @@ class Action {
virtual void fill_intervention(ModSecurityIntervention *intervention); virtual void fill_intervention(ModSecurityIntervention *intervention);
bool temporaryAction; bool temporaryAction;
bool m_isNone;
}; };

View File

@ -36,12 +36,19 @@ namespace transformations {
std::string HtmlEntityDecode::evaluate(std::string value, std::string HtmlEntityDecode::evaluate(std::string value,
Assay *assay) { Assay *assay) {
if (HtmlEntityDecodeInstantCache::getInstance().count(value) > 0) {
return HtmlEntityDecodeInstantCache::getInstance().at(value);
}
char *tmp = strdup(value.c_str()); char *tmp = strdup(value.c_str());
html_entities_decode_inplace((unsigned char *)tmp, value.size()); html_entities_decode_inplace((unsigned char *)tmp, value.size());
std::string ret(""); std::string ret("");
ret.assign(tmp); ret.assign(tmp);
free(tmp); free(tmp);
HtmlEntityDecodeInstantCache::getInstance().emplace(value, ret);
return ret; return ret;
} }

View File

@ -14,6 +14,7 @@
*/ */
#include <string> #include <string>
#include <unordered_map>
#include "actions/action.h" #include "actions/action.h"
#include "actions/transformations/transformation.h" #include "actions/transformations/transformation.h"
@ -29,6 +30,18 @@ namespace actions {
namespace transformations { namespace transformations {
class HtmlEntityDecodeInstantCache : public std::unordered_map<std::string, std::string> {
public:
static HtmlEntityDecodeInstantCache& getInstance() {
static HtmlEntityDecodeInstantCache instance;
return instance;
}
private:
HtmlEntityDecodeInstantCache() {};
};
class HtmlEntityDecode : public Transformation { class HtmlEntityDecode : public Transformation {
public: public:
explicit HtmlEntityDecode(std::string action) explicit HtmlEntityDecode(std::string action)

View File

@ -35,10 +35,18 @@ std::string LowerCase::evaluate(std::string value,
Assay *assay) { Assay *assay) {
std::locale loc; std::locale loc;
if (LowerCaseInstantCache::getInstance().count(value) > 0) {
return LowerCaseInstantCache::getInstance().at(value);
}
std::string orig_value = value;
for (std::string::size_type i=0; i < value.length(); ++i) { for (std::string::size_type i=0; i < value.length(); ++i) {
value[i] = std::tolower(value[i], loc); value[i] = std::tolower(value[i], loc);
} }
LowerCaseInstantCache::getInstance().emplace(orig_value, value);
return value; return value;
} }

View File

@ -14,6 +14,7 @@
*/ */
#include <string> #include <string>
#include <unordered_map>
#include "actions/action.h" #include "actions/action.h"
#include "actions/transformations/transformation.h" #include "actions/transformations/transformation.h"
@ -28,6 +29,17 @@ class Assay;
namespace actions { namespace actions {
namespace transformations { namespace transformations {
class LowerCaseInstantCache : public std::unordered_map<std::string, std::string> {
public:
static LowerCaseInstantCache& getInstance() {
static LowerCaseInstantCache instance;
return instance;
}
private:
LowerCaseInstantCache() {};
};
class LowerCase : public Transformation { class LowerCase : public Transformation {
public: public:

View File

@ -31,7 +31,8 @@ namespace transformations {
class None : public Transformation { class None : public Transformation {
public: public:
explicit None(std::string action) explicit None(std::string action)
: Transformation(action) { } : Transformation(action)
{ m_isNone = true; }
std::string evaluate(std::string exp, std::string evaluate(std::string exp,
Assay *assay) override; Assay *assay) override;

View File

@ -100,6 +100,10 @@ std::string UrlDecode::evaluate(std::string value,
int invalid_count; int invalid_count;
int changed; int changed;
if (UrlDecodeInstantCache::getInstance().count(value) > 0) {
return UrlDecodeInstantCache::getInstance().at(value);
}
val = (unsigned char *) malloc(sizeof(char) * value.size() + 1); val = (unsigned char *) malloc(sizeof(char) * value.size() + 1);
memcpy(val, value.c_str(), value.size() + 1); memcpy(val, value.c_str(), value.size() + 1);
val[value.size()] = '\0'; val[value.size()] = '\0';
@ -112,6 +116,8 @@ std::string UrlDecode::evaluate(std::string value,
free(val); free(val);
UrlDecodeInstantCache::getInstance().emplace(value, out);
return out; return out;
} }

View File

@ -14,6 +14,7 @@
*/ */
#include <string> #include <string>
#include <unordered_map>
#include "actions/action.h" #include "actions/action.h"
#include "actions/transformations/transformation.h" #include "actions/transformations/transformation.h"
@ -28,6 +29,18 @@ class Assay;
namespace actions { namespace actions {
namespace transformations { namespace transformations {
class UrlDecodeInstantCache : public std::unordered_map<std::string, std::string> {
public:
static UrlDecodeInstantCache& getInstance() {
static UrlDecodeInstantCache instance;
return instance;
}
private:
UrlDecodeInstantCache() {};
};
class UrlDecode : public Transformation { class UrlDecode : public Transformation {
public: public:
explicit UrlDecode(std::string action); explicit UrlDecode(std::string action);

View File

@ -140,8 +140,7 @@ bool Rule::evaluateActions(Assay *assay) {
bool containsDisruptive = false; bool containsDisruptive = false;
// int transformations = 0; // int transformations = 0;
for (Action *a : this->actions_runtime_pre) { for (Action *a : this->actions_runtime_pre) {
None *z = dynamic_cast<None *>(a); if (a->m_isNone) {
if (z != NULL) {
none++; none++;
} }
} }
@ -165,7 +164,6 @@ bool Rule::evaluateActions(Assay *assay) {
} }
for (Action *a : this->actions_runtime_pre) { for (Action *a : this->actions_runtime_pre) {
None *z = dynamic_cast<None *>(a);
/* /*
if (none == 0) { if (none == 0) {
value = a->evaluate(value, assay); value = a->evaluate(value, assay);
@ -175,7 +173,7 @@ bool Rule::evaluateActions(Assay *assay) {
transformations++; transformations++;
} }
*/ */
if (z != NULL) { if (a->m_isNone) {
none--; none--;
} }
} }
@ -281,9 +279,7 @@ bool Rule::evaluate(Assay *assay) {
std::list<std::string> exclusions; std::list<std::string> exclusions;
for (int i = 0; i < variables->size(); i++) { for (int i = 0; i < variables->size(); i++) {
Variable *variable = variables->at(i); Variable *variable = variables->at(i);
Exclusion *exl = dynamic_cast<Exclusion *>(variable); if (variable->m_isExclusion) {
if (exl != NULL) {
std::list<transaction::Variable *> *z = std::list<transaction::Variable *> *z =
variable->evaluate(assay); variable->evaluate(assay);
for (auto &y : *z) { for (auto &y : *z) {
@ -297,8 +293,7 @@ bool Rule::evaluate(Assay *assay) {
for (int i = 0; i < variables->size(); i++) { for (int i = 0; i < variables->size(); i++) {
int transformations = 0; int transformations = 0;
Variable *variable = variables->at(i); Variable *variable = variables->at(i);
Exclusion *exl = dynamic_cast<Exclusion *>(variable); if (variable->m_isExclusion) {
if (exl != NULL) {
continue; continue;
} }
@ -317,8 +312,7 @@ bool Rule::evaluate(Assay *assay) {
std::string value = v->m_value; std::string value = v->m_value;
int none = 0; int none = 0;
for (Action *a : this->actions_runtime_pre) { for (Action *a : this->actions_runtime_pre) {
None *z = dynamic_cast<None *>(a); if (a->m_isNone != NULL) {
if (z != NULL) {
none++; none++;
} }
} }
@ -342,7 +336,6 @@ bool Rule::evaluate(Assay *assay) {
} }
for (Action *a : this->actions_runtime_pre) { for (Action *a : this->actions_runtime_pre) {
None *z = dynamic_cast<None *>(a);
if (none == 0) { if (none == 0) {
value = a->evaluate(value, assay); value = a->evaluate(value, assay);
#ifndef NO_LOGS #ifndef NO_LOGS
@ -352,7 +345,7 @@ bool Rule::evaluate(Assay *assay) {
#endif #endif
transformations++; transformations++;
} }
if (z != NULL) { if (a->m_isNone != NULL) {
none--; none--;
} }
} }

View File

@ -31,7 +31,9 @@ namespace Variables {
Variable::Variable(std::string name) Variable::Variable(std::string name)
: m_name(name), : m_name(name),
m_collectionName("") { m_collectionName(""),
m_isExclusion(false),
m_isCount(false) {
if (m_name.at(0) == '\\') { if (m_name.at(0) == '\\') {
m_type = RegularExpression; m_type = RegularExpression;
@ -53,7 +55,9 @@ Variable::Variable(std::string name)
Variable::Variable(std::string name, VariableKind kind) Variable::Variable(std::string name, VariableKind kind)
: m_name(name), : m_name(name),
m_collectionName(""), m_collectionName(""),
m_kind(kind) { m_kind(kind),
m_isExclusion(false),
m_isCount(false) {
if (m_name.at(0) == '\\') { if (m_name.at(0) == '\\') {
m_type = RegularExpression; m_type = RegularExpression;

View File

@ -74,6 +74,8 @@ class Variable {
VariableType m_type; VariableType m_type;
VariableKind m_kind; VariableKind m_kind;
bool m_isExclusion;
bool m_isCount;
}; };

View File

@ -34,7 +34,8 @@ class Exclusion : public Variable {
public: public:
explicit Exclusion(Variable *v) explicit Exclusion(Variable *v)
: Variable(v->m_name), : Variable(v->m_name),
var(v) { } var(v)
{ m_isExclusion = true; }
std::list<transaction::Variable *> * std::list<transaction::Variable *> *
evaluate(Assay *assay) override; evaluate(Assay *assay) override;