|
reSIProcate/repro
9694
|
#include <RouteStore.hxx>

Classes | |
| class | RouteOp |
Public Types | |
| typedef std::vector< resip::Uri > | UriList |
| typedef resip::Data | Key |
Public Member Functions | |
| RouteStore (AbstractDb &db) | |
| ~RouteStore () | |
| bool | addRoute (const resip::Data &method, const resip::Data &event, const resip::Data &matchingPattern, const resip::Data &rewriteExpression, const int order) |
| void | eraseRoute (const resip::Data &method, const resip::Data &event, const resip::Data &matchingPattern) |
| void | eraseRoute (const resip::Data &key) |
| bool | updateRoute (const resip::Data &originalKey, const resip::Data &method, const resip::Data &event, const resip::Data &matchingPattern, const resip::Data &rewriteExpression, const int order) |
| AbstractDb::RouteRecord | getRouteRecord (const resip::Data &key) |
| Key | getFirstKey () |
| Key | getNextKey (Key &key) |
| UriList | process (const resip::Uri &ruri, const resip::Data &method, const resip::Data &event) |
Private Types | |
| typedef std::multiset< RouteOp > | RouteOpList |
Private Member Functions | |
| bool | findKey (const Key &key) |
| Key | buildKey (const resip::Data &method, const resip::Data &event, const resip::Data &matchingPattern) const |
Private Attributes | |
| AbstractDb & | mDb |
| resip::RWMutex | mMutex |
| RouteOpList | mRouteOperators |
| RouteOpList::iterator | mCursor |
Definition at line 23 of file RouteStore.hxx.
| typedef resip::Data repro::RouteStore::Key |
Definition at line 27 of file RouteStore.hxx.
typedef std::multiset<RouteOp> repro::RouteStore::RouteOpList [private] |
Definition at line 78 of file RouteStore.hxx.
| typedef std::vector<resip::Uri> repro::RouteStore::UriList |
Definition at line 26 of file RouteStore.hxx.
| RouteStore::RouteStore | ( | AbstractDb & | db | ) |
Definition at line 24 of file RouteStore.cxx.
: mDb(db) { Key key = mDb.firstRouteKey(); while ( !key.empty() ) { RouteOp route; route.routeRecord = mDb.getRoute(key); route.key = key; route.preq = 0; if(!route.routeRecord.mMatchingPattern.empty()) { int flags = REG_EXTENDED; if(route.routeRecord.mRewriteExpression.find("$") == Data::npos) { flags |= REG_NOSUB; } route.preq = new regex_t; int ret = regcomp(route.preq, route.routeRecord.mMatchingPattern.c_str(), flags); if(ret != 0) { delete route.preq; ErrLog(<< "Routing rule has invalid match expression: " << route.routeRecord.mMatchingPattern); route.preq = 0; } } mRouteOperators.insert( route ); key = mDb.nextRouteKey(); } mCursor = mRouteOperators.begin(); }
| RouteStore::~RouteStore | ( | ) |
Definition at line 61 of file RouteStore.cxx.
{
for(RouteOpList::iterator i = mRouteOperators.begin(); i != mRouteOperators.end(); i++)
{
if ( i->preq )
{
regfree ( i->preq );
delete i->preq;
// !abr! Can't modify elements in a set
// i->preq = 0;
}
}
mRouteOperators.clear();
}
| bool RouteStore::addRoute | ( | const resip::Data & | method, |
| const resip::Data & | event, | ||
| const resip::Data & | matchingPattern, | ||
| const resip::Data & | rewriteExpression, | ||
| const int | order | ||
| ) |
Definition at line 80 of file RouteStore.cxx.
{
InfoLog( << "Add route" );
RouteOp route;
Key key = buildKey(method, event, matchingPattern);
if(findKey(key)) return false;
route.routeRecord.mMethod = method;
route.routeRecord.mEvent = event;
route.routeRecord.mMatchingPattern = matchingPattern;
route.routeRecord.mRewriteExpression = rewriteExpression;
route.routeRecord.mOrder = order;
if(!mDb.addRoute(key , route.routeRecord))
{
return false;
}
route.key = key;
route.preq = 0;
if( !route.routeRecord.mMatchingPattern.empty() )
{
int flags = REG_EXTENDED;
if( route.routeRecord.mRewriteExpression.find("$") == Data::npos )
{
flags |= REG_NOSUB;
}
route.preq = new regex_t;
int ret = regcomp( route.preq, route.routeRecord.mMatchingPattern.c_str(), flags );
if( ret != 0 )
{
delete route.preq;
route.preq = 0;
}
}
{
WriteLock lock(mMutex);
mRouteOperators.insert( route );
}
mCursor = mRouteOperators.begin();
return true;
}
| RouteStore::Key RouteStore::buildKey | ( | const resip::Data & | method, |
| const resip::Data & | event, | ||
| const resip::Data & | matchingPattern | ||
| ) | const [private] |
Definition at line 413 of file RouteStore.cxx.
{
// missing mOrder
// Data pKey = Data(order) + ":" + method + ":" + event + ":" + matchingPattern;
Data pKey = method+":"+event+":"+matchingPattern;
return pKey;
}
| void RouteStore::eraseRoute | ( | const resip::Data & | method, |
| const resip::Data & | event, | ||
| const resip::Data & | matchingPattern | ||
| ) |
Definition at line 151 of file RouteStore.cxx.
{
Key key = buildKey(method, event, matchingPattern);
eraseRoute(key);
}
| void RouteStore::eraseRoute | ( | const resip::Data & | key | ) |
Definition at line 161 of file RouteStore.cxx.
{
mDb.eraseRoute(key);
{
WriteLock lock(mMutex);
RouteOpList::iterator it = mRouteOperators.begin();
while ( it != mRouteOperators.end() )
{
if (it->key == key )
{
RouteOpList::iterator i = it;
it++;
if ( i->preq )
{
regfree ( i->preq );
delete i->preq;
// !abr! Can't modify elements in a set
//i->preq = 0;
}
mRouteOperators.erase(i);
}
else
{
it++;
}
}
}
mCursor = mRouteOperators.begin(); // reset the cursor since it may have been on deleted route
}
| bool RouteStore::findKey | ( | const Key & | key | ) | [private] |
Definition at line 224 of file RouteStore.cxx.
{
// check if cursor happens to be at the key
if ( mCursor != mRouteOperators.end() )
{
if ( mCursor->key == key )
{
return true;
}
}
// search for the key
mCursor = mRouteOperators.begin();
while ( mCursor != mRouteOperators.end() )
{
if ( mCursor->key == key )
{
return true; // found the key
}
mCursor++;
}
return false; // key was not found
}
| RouteStore::Key RouteStore::getFirstKey | ( | ) |
Definition at line 210 of file RouteStore.cxx.
{
ReadLock lock(mMutex);
mCursor = mRouteOperators.begin();
if ( mCursor == mRouteOperators.end() )
{
return Key( Data::Empty );
}
return mCursor->key;
}
| RouteStore::Key RouteStore::getNextKey | ( | Key & | key | ) |
| AbstractDb::RouteRecord RouteStore::getRouteRecord | ( | const resip::Data & | key | ) |
Definition at line 270 of file RouteStore.cxx.
{
ReadLock lock(mMutex);
if (!findKey(key))
{
return AbstractDb::RouteRecord();
}
return mCursor->routeRecord;
}
| RouteStore::UriList RouteStore::process | ( | const resip::Uri & | ruri, |
| const resip::Data & | method, | ||
| const resip::Data & | event | ||
| ) |
Definition at line 283 of file RouteStore.cxx.
{
RouteStore::UriList targetSet;
if(mRouteOperators.empty()) return targetSet; // If there are no routes bail early to save a few cycles (size check is atomic enough, we don't need a lock)
ReadLock lock(mMutex);
for (RouteOpList::iterator it = mRouteOperators.begin();
it != mRouteOperators.end(); it++)
{
DebugLog( << "Consider route " // << *it
<< " reqUri=" << ruri
<< " method=" << method
<< " event=" << event );
const AbstractDb::RouteRecord& rec = it->routeRecord;
if(!rec.mMethod.empty())
{
if(!isEqualNoCase(rec.mMethod,method))
{
DebugLog( << " Skipped - method did not match" );
continue;
}
}
if(!rec.mEvent.empty())
{
if(!isEqualNoCase(rec.mEvent, event))
{
DebugLog( << " Skipped - event did not match" );
continue;
}
}
const Data& rewrite = rec.mRewriteExpression;
const Data& match = rec.mMatchingPattern;
if ( it->preq )
{
int ret;
// TODO - !cj! www.pcre.org looks like it has better performance
// !mbg! is this true now that the compiled regexp is used?
Data uri;
{
DataStream s(uri);
s << ruri;
s.flush();
}
const int nmatch=10;
regmatch_t pmatch[nmatch];
ret = regexec(it->preq, uri.c_str(), nmatch, pmatch, 0/*eflags*/);
if ( ret != 0 )
{
// did not match
DebugLog( << " Skipped - request URI "<< uri << " did not match " << match );
continue;
}
DebugLog( << " Route matched" );
Data target = rewrite;
if ( rewrite.find("$") != Data::npos )
{
for ( int i=1; i<nmatch; i++)
{
if ( pmatch[i].rm_so != -1 )
{
Data subExp(uri.substr(pmatch[i].rm_so,
pmatch[i].rm_eo-pmatch[i].rm_so));
DebugLog( << " subExpression[" <<i <<"]="<< subExp );
Data result;
{
DataStream s(result);
ParseBuffer pb(target);
while (true)
{
const char* a = pb.position();
pb.skipToChars( Data("$") + char('0'+i) );
if ( pb.eof() )
{
s << pb.data(a);
break;
}
else
{
s << pb.data(a);
pb.skipN(2);
s << subExp;
}
}
s.flush();
}
target = result;
}
}
}
Uri targetUri;
try
{
targetUri = Uri(target);
}
catch( BaseException& )
{
ErrLog( << "Routing rule transform " << rewrite << " gave invalid URI " << target );
try
{
targetUri = Uri( Data("sip:")+target);
}
catch( BaseException& )
{
ErrLog( << "Routing rule transform " << rewrite << " gave invalid URI sip:" << target );
continue;
}
}
targetSet.push_back( targetUri );
}
}
return targetSet;
}
| bool RouteStore::updateRoute | ( | const resip::Data & | originalKey, |
| const resip::Data & | method, | ||
| const resip::Data & | event, | ||
| const resip::Data & | matchingPattern, | ||
| const resip::Data & | rewriteExpression, | ||
| const int | order | ||
| ) |
Definition at line 197 of file RouteStore.cxx.
{
eraseRoute(originalKey);
return addRoute(method, event, matchingPattern, rewriteExpression, order);
}
RouteOpList::iterator repro::RouteStore::mCursor [private] |
Definition at line 80 of file RouteStore.hxx.
AbstractDb& repro::RouteStore::mDb [private] |
Definition at line 66 of file RouteStore.hxx.
resip::RWMutex repro::RouteStore::mMutex [private] |
Definition at line 77 of file RouteStore.hxx.
Definition at line 79 of file RouteStore.hxx.
1.7.5.1