For urls with partially matched names dispatcher always calls method registered for shorter
GoogleCodeExporter opened this issue · 0 comments
GoogleCodeExporter commented
Sorry, not even sure if this project is at least partially supported so I just
leave here short description and solution... Just in case.
So, for urls like /url and /url1 no mater what you add for mapping allways will
be called method mapped for /url
dispatcher.AddMapping("/url", HttpPost, new
HttpHandlerConnector<VoteServer>(this,&VoteServer::urlMethod), true);
dispatcher.AddMapping("/url1", HttpPost, new
HttpHandlerConnector<VoteServer>(this,&VoteServer::url1Method), true);
So if I access http://serverip:serverport/url1 VoteServer::url1Method will be
called.
This happens cause URIDispatcher::Handle method checks length bla bla bla you
know it yourself. So there is a very easy solution. Cause map orders methods by
string length (actually alphabetically but whatever) and url is actually
dispatchMap key reversing dispatchMap iteration solves everything. Methods are
now iterated from longest to shortest.
So here are the fixes. Basically I just changed iterator to reverse_iterator
and begin() end() to rbegin() rend(). And just in case made the same changes
for HostDispatcher.
void HostDispatcher::Handle(HttpServerContext* context)
{
for(map<string,Mapping>::reverse_iterator iter=dispatchMap.rbegin();iter!=dispatchMap.rend();iter++)
{
if((context->requestHeader.host.length()>=iter->first.length())&&(context->requestHeader.host.compare(context->requestHeader.host.length()-iter->first.length(),iter->first.length(),iter->first)==0))
{
context->requestHeader.host.erase(context->requestHeader.host.length()-iter->first.length());
if(context->requestHeader.host[context->requestHeader.host.length()-1]=='.')
context->requestHeader.host.resize(context->requestHeader.host.length()-1);
Invoke(iter->first,context);
return;
}
}
if(!defaultHandler.empty())
Invoke(defaultHandler,context);
else
throw HttpException(HttpNotFound,"Not found.");
}
void URIDispatcher::Handle(HttpServerContext* context)
{
for(map<string,Mapping>::reverse_iterator iter=dispatchMap.rbegin();iter!=dispatchMap.rend();iter++)
{
if((context->requestHeader.resource.length()>=iter->first.length())&&(context->requestHeader.resource.compare(0,iter->first.length(),iter->first)==0))
{
context->requestHeader.resource.erase(0,iter->first.length());
Invoke(iter->first,context);
return;
}
}
if(!defaultHandler.empty())
Invoke(defaultHandler,context);
else
throw HttpException(HttpNotFound,"Not found.");
}
Hope this will help...
Good luck!
Original issue reported on code.google.com by alexandr...@gmail.com
on 29 May 2013 at 11:57