mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Testing performance enhancements by enabling transformations cache
Also reduce the utilization of dynamic cast.
This commit is contained in:
parent
e641c3cc17
commit
2ee5d4ca8f
@ -36,6 +36,7 @@ class Action {
|
||||
: action_kind(2),
|
||||
action(_action),
|
||||
name(_action),
|
||||
m_isNone(false),
|
||||
temporaryAction(false) {
|
||||
name.erase(0, 2);
|
||||
}
|
||||
@ -43,6 +44,7 @@ class Action {
|
||||
: action_kind(kind),
|
||||
action(_action),
|
||||
name(_action),
|
||||
m_isNone(false),
|
||||
temporaryAction(false) {
|
||||
name.erase(0, 2);
|
||||
}
|
||||
@ -94,6 +96,7 @@ class Action {
|
||||
|
||||
virtual void fill_intervention(ModSecurityIntervention *intervention);
|
||||
bool temporaryAction;
|
||||
bool m_isNone;
|
||||
};
|
||||
|
||||
|
||||
|
@ -36,12 +36,19 @@ namespace transformations {
|
||||
|
||||
std::string HtmlEntityDecode::evaluate(std::string value,
|
||||
Assay *assay) {
|
||||
|
||||
if (HtmlEntityDecodeInstantCache::getInstance().count(value) > 0) {
|
||||
return HtmlEntityDecodeInstantCache::getInstance().at(value);
|
||||
}
|
||||
|
||||
char *tmp = strdup(value.c_str());
|
||||
html_entities_decode_inplace((unsigned char *)tmp, value.size());
|
||||
std::string ret("");
|
||||
ret.assign(tmp);
|
||||
free(tmp);
|
||||
|
||||
HtmlEntityDecodeInstantCache::getInstance().emplace(value, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "actions/action.h"
|
||||
#include "actions/transformations/transformation.h"
|
||||
@ -29,6 +30,18 @@ namespace actions {
|
||||
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 {
|
||||
public:
|
||||
explicit HtmlEntityDecode(std::string action)
|
||||
|
@ -35,10 +35,18 @@ std::string LowerCase::evaluate(std::string value,
|
||||
Assay *assay) {
|
||||
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) {
|
||||
value[i] = std::tolower(value[i], loc);
|
||||
}
|
||||
|
||||
LowerCaseInstantCache::getInstance().emplace(orig_value, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "actions/action.h"
|
||||
#include "actions/transformations/transformation.h"
|
||||
@ -28,6 +29,17 @@ class Assay;
|
||||
namespace actions {
|
||||
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 {
|
||||
public:
|
||||
|
@ -31,7 +31,8 @@ namespace transformations {
|
||||
class None : public Transformation {
|
||||
public:
|
||||
explicit None(std::string action)
|
||||
: Transformation(action) { }
|
||||
: Transformation(action)
|
||||
{ m_isNone = true; }
|
||||
|
||||
std::string evaluate(std::string exp,
|
||||
Assay *assay) override;
|
||||
|
@ -100,6 +100,10 @@ std::string UrlDecode::evaluate(std::string value,
|
||||
int invalid_count;
|
||||
int changed;
|
||||
|
||||
if (UrlDecodeInstantCache::getInstance().count(value) > 0) {
|
||||
return UrlDecodeInstantCache::getInstance().at(value);
|
||||
}
|
||||
|
||||
val = (unsigned char *) malloc(sizeof(char) * value.size() + 1);
|
||||
memcpy(val, value.c_str(), value.size() + 1);
|
||||
val[value.size()] = '\0';
|
||||
@ -112,6 +116,8 @@ std::string UrlDecode::evaluate(std::string value,
|
||||
|
||||
free(val);
|
||||
|
||||
UrlDecodeInstantCache::getInstance().emplace(value, out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "actions/action.h"
|
||||
#include "actions/transformations/transformation.h"
|
||||
@ -28,6 +29,18 @@ class Assay;
|
||||
namespace actions {
|
||||
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 {
|
||||
public:
|
||||
explicit UrlDecode(std::string action);
|
||||
|
19
src/rule.cc
19
src/rule.cc
@ -140,8 +140,7 @@ bool Rule::evaluateActions(Assay *assay) {
|
||||
bool containsDisruptive = false;
|
||||
// int transformations = 0;
|
||||
for (Action *a : this->actions_runtime_pre) {
|
||||
None *z = dynamic_cast<None *>(a);
|
||||
if (z != NULL) {
|
||||
if (a->m_isNone) {
|
||||
none++;
|
||||
}
|
||||
}
|
||||
@ -165,7 +164,6 @@ bool Rule::evaluateActions(Assay *assay) {
|
||||
}
|
||||
|
||||
for (Action *a : this->actions_runtime_pre) {
|
||||
None *z = dynamic_cast<None *>(a);
|
||||
/*
|
||||
if (none == 0) {
|
||||
value = a->evaluate(value, assay);
|
||||
@ -175,7 +173,7 @@ bool Rule::evaluateActions(Assay *assay) {
|
||||
transformations++;
|
||||
}
|
||||
*/
|
||||
if (z != NULL) {
|
||||
if (a->m_isNone) {
|
||||
none--;
|
||||
}
|
||||
}
|
||||
@ -281,9 +279,7 @@ bool Rule::evaluate(Assay *assay) {
|
||||
std::list<std::string> exclusions;
|
||||
for (int i = 0; i < variables->size(); i++) {
|
||||
Variable *variable = variables->at(i);
|
||||
Exclusion *exl = dynamic_cast<Exclusion *>(variable);
|
||||
|
||||
if (exl != NULL) {
|
||||
if (variable->m_isExclusion) {
|
||||
std::list<transaction::Variable *> *z =
|
||||
variable->evaluate(assay);
|
||||
for (auto &y : *z) {
|
||||
@ -297,8 +293,7 @@ bool Rule::evaluate(Assay *assay) {
|
||||
for (int i = 0; i < variables->size(); i++) {
|
||||
int transformations = 0;
|
||||
Variable *variable = variables->at(i);
|
||||
Exclusion *exl = dynamic_cast<Exclusion *>(variable);
|
||||
if (exl != NULL) {
|
||||
if (variable->m_isExclusion) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -317,8 +312,7 @@ bool Rule::evaluate(Assay *assay) {
|
||||
std::string value = v->m_value;
|
||||
int none = 0;
|
||||
for (Action *a : this->actions_runtime_pre) {
|
||||
None *z = dynamic_cast<None *>(a);
|
||||
if (z != NULL) {
|
||||
if (a->m_isNone != NULL) {
|
||||
none++;
|
||||
}
|
||||
}
|
||||
@ -342,7 +336,6 @@ bool Rule::evaluate(Assay *assay) {
|
||||
}
|
||||
|
||||
for (Action *a : this->actions_runtime_pre) {
|
||||
None *z = dynamic_cast<None *>(a);
|
||||
if (none == 0) {
|
||||
value = a->evaluate(value, assay);
|
||||
#ifndef NO_LOGS
|
||||
@ -352,7 +345,7 @@ bool Rule::evaluate(Assay *assay) {
|
||||
#endif
|
||||
transformations++;
|
||||
}
|
||||
if (z != NULL) {
|
||||
if (a->m_isNone != NULL) {
|
||||
none--;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,9 @@ namespace Variables {
|
||||
|
||||
Variable::Variable(std::string name)
|
||||
: m_name(name),
|
||||
m_collectionName("") {
|
||||
m_collectionName(""),
|
||||
m_isExclusion(false),
|
||||
m_isCount(false) {
|
||||
|
||||
if (m_name.at(0) == '\\') {
|
||||
m_type = RegularExpression;
|
||||
@ -53,7 +55,9 @@ Variable::Variable(std::string name)
|
||||
Variable::Variable(std::string name, VariableKind kind)
|
||||
: m_name(name),
|
||||
m_collectionName(""),
|
||||
m_kind(kind) {
|
||||
m_kind(kind),
|
||||
m_isExclusion(false),
|
||||
m_isCount(false) {
|
||||
|
||||
if (m_name.at(0) == '\\') {
|
||||
m_type = RegularExpression;
|
||||
|
@ -74,6 +74,8 @@ class Variable {
|
||||
|
||||
VariableType m_type;
|
||||
VariableKind m_kind;
|
||||
bool m_isExclusion;
|
||||
bool m_isCount;
|
||||
};
|
||||
|
||||
|
||||
|
@ -34,7 +34,8 @@ class Exclusion : public Variable {
|
||||
public:
|
||||
explicit Exclusion(Variable *v)
|
||||
: Variable(v->m_name),
|
||||
var(v) { }
|
||||
var(v)
|
||||
{ m_isExclusion = true; }
|
||||
|
||||
std::list<transaction::Variable *> *
|
||||
evaluate(Assay *assay) override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user