18#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO
24const std::regex_constants::syntax_option_type
DefaultFlags = std::regex_constants::ECMAScript;
26bool FilterStore::FilterOp::operator<(
const FilterOp& rhs)
const
28 return filterRecord.mOrder < rhs.filterRecord.mOrder;
35 while ( !key.
empty() )
44 if(filter.filterRecord.mActionData.find(
"$") ==
Data::npos)
46 flags |= std::regex_constants::nosubs;
49 if(!filter.filterRecord.mCondition1Regex.empty())
53 filter.pcond1 =
new std::regex(filter.filterRecord.mCondition1Regex.c_str(),
flags);
55 catch (std::regex_error&)
58 ErrLog( <<
"Condition1Regex has invalid match expression: "
59 << filter.filterRecord.mCondition1Regex);
64 if(!filter.filterRecord.mCondition2Regex.empty())
68 filter.pcond2 =
new std::regex(filter.filterRecord.mCondition2Regex.c_str(),
flags);
70 catch (std::regex_error&)
73 ErrLog( <<
"Condition2Regex has invalid match expression: "
74 << filter.filterRecord.mCondition2Regex);
79 mFilterOperators.insert(filter);
83 mCursor = mFilterOperators.begin();
88 for(FilterOpList::iterator i = mFilterOperators.begin(); i != mFilterOperators.end(); i++)
99 mFilterOperators.clear();
117 Key key = buildKey(cond1Header, cond1Regex, cond2Header, cond2Regex, method, event);
119 if(findKey(key))
return false;
121 filter.filterRecord.mCondition1Header = cond1Header;
122 filter.filterRecord.mCondition1Regex = cond1Regex;
123 filter.filterRecord.mCondition2Header = cond2Header;
124 filter.filterRecord.mCondition2Regex = cond2Regex;
125 filter.filterRecord.mMethod = method;
126 filter.filterRecord.mEvent = event;
127 filter.filterRecord.mAction = action;
128 filter.filterRecord.mActionData = actionData;
129 filter.filterRecord.mOrder = order;
131 if(!mDb.
addFilter(key , filter.filterRecord))
140 if(filter.filterRecord.mActionData.find(
"$") ==
Data::npos)
142 flags |= std::regex_constants::nosubs;
144 if(!filter.filterRecord.mCondition1Regex.empty())
148 filter.pcond1 =
new std::regex(filter.filterRecord.mCondition1Regex.c_str(),
flags);
150 catch (std::regex_error&)
152 delete filter.pcond1;
156 if(!filter.filterRecord.mCondition2Regex.empty())
160 filter.pcond2 =
new std::regex(filter.filterRecord.mCondition2Regex.c_str(),
flags);
162 catch (std::regex_error&)
164 delete filter.pcond2;
171 mFilterOperators.insert( filter );
173 mCursor = mFilterOperators.begin();
202 Key key = buildKey(cond1Header, cond1Regex, cond2Header, cond2Regex, method, event);
214 FilterOpList::iterator it = mFilterOperators.begin();
215 while (it != mFilterOperators.end())
219 FilterOpList::iterator i = it;
229 mFilterOperators.erase(i);
237 mCursor = mFilterOperators.begin();
253 return addFilter(cond1Header, cond1Regex, cond2Header, cond2Regex, method, event, action, actionData, order);
261 mCursor = mFilterOperators.begin();
262 if ( mCursor == mFilterOperators.end() )
271FilterStore::findKey(
const Key& key)
274 if ( mCursor != mFilterOperators.end() )
276 if ( mCursor->key == key )
283 mCursor = mFilterOperators.begin();
284 while ( mCursor != mFilterOperators.end() )
286 if ( mCursor->key == key )
307 if ( mCursor == mFilterOperators.end() )
324 return mCursor->filterRecord;
328FilterStore::getHeaderFromSipMessage(
const SipMessage& msg,
const Data& headerName, list<Data>& headerList)
345 it->toShareData(headerData);
355 for(StringCategories::const_iterator it = exHeaders.begin(); it != exHeaders.end(); it++)
357 headerList.push_back(it->value());
364FilterStore::applyRegex(
int conditionNum,
const Data& header,
const Data& match, std::regex *_regex,
Data& rewrite)
372 if(!std::regex_search(header.
c_str(), matches, *_regex))
378 DebugLog( <<
" Filter matched: header=" << header <<
", regex=" << match);
382 for (
int i=1; i<(int)matches.size(); i++)
384 Data subExp(matches[i]);
385 DebugLog( <<
" subExpression[" <<i <<
"]="<< subExp );
394 const char* a = pb.position();
395 pb.skipToChars(
Data(
"$") +
char(
'0' + conditionNum) +
char(
'0' + i));
421 if(mFilterOperators.empty())
return false;
428 for (FilterOpList::iterator it = mFilterOperators.begin();
429 it != mFilterOperators.end(); it++)
437 DebugLog( <<
" Skipped - method did not match" );
445 DebugLog( <<
" Skipped - event did not match" );
451 list<Data> condition1Headers;
452 list<Data> condition2Headers;
459 list<Data>::iterator hit = condition1Headers.begin();
461 for(; hit != condition1Headers.end() && match ==
false; hit++)
468 DebugLog( <<
" Skipped - request did not match first condition: " << request.
brief());
477 list<Data>::iterator hit = condition2Headers.begin();
479 for(; hit != condition2Headers.end() && match ==
false; hit++)
486 DebugLog( <<
" Skipped - request did not match second condition: " << request.
brief());
507 for (FilterOpList::iterator it = mFilterOperators.begin();
508 it != mFilterOperators.end(); it++)
516 if(!applyRegex(1, cond1Header, rec.
mCondition1Regex, it->pcond1, actionData))
525 if(!applyRegex(2, cond2Header, rec.
mCondition2Regex, it->pcond2, actionData))
541FilterStore::buildKey(
const resip::Data& cond1Header,
548 Data pKey = cond1Header +
":" + cond1Regex +
":" +
549 cond2Header +
":" + cond2Regex +
":" +
550 method +
":" + event;
const std::regex_constants::syntax_option_type DefaultFlags
#define resip_assert(x)
This file needs to work for both C and C++ code.
static const struct nv flags[]
resip::Data mCondition1Header
resip::Data mCondition2Regex
resip::Data mCondition2Header
resip::Data mCondition1Regex
virtual Key nextFilterKey()
virtual bool addFilter(const Key &key, const FilterRecord &rec)
virtual void eraseFilter(const Key &key)
virtual FilterRecord getFilter(const Key &key) const
virtual Key firstFilterKey()
bool updateFilter(const resip::Data &originalKey, const resip::Data &cond1Header, const resip::Data &cond1Regex, const resip::Data &cond2Header, const resip::Data &cond2Regex, const resip::Data &method, const resip::Data &event, short action, const resip::Data &actionData, const short order)
FilterStore(AbstractDb &db)
bool addFilter(const resip::Data &cond1Header, const resip::Data &cond1Regex, const resip::Data &cond2Header, const resip::Data &cond2Regex, const resip::Data &method, const resip::Data &event, short action, const resip::Data &actionData, const short order)
void eraseFilter(const resip::Data &cond1Header, const resip::Data &cond1Regex, const resip::Data &cond2Header, const resip::Data &cond2Regex, const resip::Data &method, const resip::Data &event)
bool test(const resip::Data &cond1Header, const resip::Data &cond2Header, short &action, resip::Data &actionData)
bool process(const resip::SipMessage &request, short &action, resip::Data &actionData)
AbstractDb::FilterRecord getFilterRecord(const resip::Data &key)
An iostream that operates on an existing Data.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
static const Data Empty
Constant that represents a zero-length data.
const char * c_str() const
Returns a null-terminated string representing.
bool empty() const noexcept
Checks whether the Data is empty.
size_type size() const noexcept
Returns the number of bytes in this Data.
static Data from(const T &x)
Converts from arbitrary other type to Data.
size_type find(const Data &match, size_type start=0) const
Finds a specified sequence of bytes in this Data.
static const size_type npos
Represents an impossible position; returned to indicate failure to find.
virtual Brief brief() const
return a facet for brief encoding of message
Provides string-parsing functionality with protection from buffer overflow.
Represents a SIP message.
const Data & methodStr() const
Returns a string containing the SIP method for the message.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
const HeaderFieldValueList * getRawHeader(Headers::Type headerType) const
typeless header interface
This Class is used to implement a primitive form of RPC using loose XML formatting.
dcm! – add UnusedChecking(_enum) below;
bool isEqualNoCase(const Data &left, const Data &right)