From: Scott Cantor Date: Thu, 30 Nov 2006 20:36:06 +0000 (+0000) Subject: Revert design decision to multiplex handlers. X-Git-Tag: 2.0-alpha1~209 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;h=a4a56b9a4b268c299a3235f577ef673c3286fc26;p=shibboleth%2Fcpp-sp.git Revert design decision to multiplex handlers. --- diff --git a/shib-target/shib-ini.cpp b/shib-target/shib-ini.cpp index d694386..e6567fb 100644 --- a/shib-target/shib-ini.cpp +++ b/shib-target/shib-ini.cpp @@ -76,7 +76,7 @@ namespace shibtarget { const IHandler* getDefaultAssertionConsumerService() const; const IHandler* getAssertionConsumerServiceByIndex(unsigned short index) const; Iterator getAssertionConsumerServicesByBinding(const XMLCh* binding) const; - Iterator getHandlers(const char* path) const; + const IHandler* getHandler(const char* path) const; // Provides filter to exclude special config elements. short acceptNode(const DOMNode* node) const; @@ -100,7 +100,7 @@ namespace shibtarget { vector m_handlerProps; // maps location (path info) to applicable handlers - map > m_handlerMap; + map m_handlerMap; // maps unique indexes to consumer services map m_acsIndexMap; @@ -450,21 +450,26 @@ XMLApplication::XMLApplication( delete hprops; hprops=NULL; } - if (!hprops) + + const char* location=hprops ? hprops->getString("Location").second : NULL; + if (!location) { + delete hprops; + hprops=NULL; + handler=saml::XML::getNextSiblingElement(handler); continue; + } // Save off the objects after giving the property set to the handler for its use. hobj->setProperties(hprops); m_handlers.push_back(hobj); m_handlerProps.push_back(hprops); - // Check for it in the location map. - const char* location=hprops->getString("Location").second; - if (m_handlerMap.count(location)==0) - m_handlerMap[location]=vector(1,hobj); + // Insert into location map. + if (*location == '/') + m_handlerMap[location]=hobj; else - m_handlerMap[location].push_back(hobj); - + m_handlerMap[string("/") + location]=hobj; + // If it's an ACS or SI, handle index/id mappings and defaulting. if (saml::XML::isElementNamed(handler,shibtarget::XML::SAML2META_NS,SHIBT_L(AssertionConsumerService))) { // Map it. @@ -512,9 +517,9 @@ XMLApplication::XMLApplication( // If no handlers defined at the root, assume a legacy configuration. if (!m_base && m_handlers.empty()) { - // A legacy config installs a SAML POST handler and a Shib session-initiator - // at the root handler location. We use the Sessions element itself as the - // IPropertySet. + // A legacy config installs a SAML POST handler at the root handler location. + // We use the Sessions element itself as the IPropertySet. + auto_ptr_char b1(Constants::SHIB_SESSIONINIT_PROFILE_URI); IPlugIn* hplug=shibConf.getPlugMgr().newPlugin(b1.get(),propcheck->getElement()); IHandler* h1=dynamic_cast(hplug); @@ -526,11 +531,10 @@ XMLApplication::XMLApplication( } h1->setProperties(propcheck); m_handlers.push_back(h1); - m_handlerMap[""]=vector(1,h1); m_sessionInitDefault=h1; auto_ptr_char b2(SAMLBrowserProfile::BROWSER_POST); - hplug=shibConf.getPlugMgr().newPlugin(b1.get(),propcheck->getElement()); + hplug=shibConf.getPlugMgr().newPlugin(b2.get(),propcheck->getElement()); IHandler* h2=dynamic_cast(hplug); if (!h2) { delete hplug; @@ -540,7 +544,7 @@ XMLApplication::XMLApplication( } h2->setProperties(propcheck); m_handlers.push_back(h2); - m_handlerMap[""].push_back(h2); + m_handlerMap[""] = h2; m_acsDefault=h2; } @@ -938,13 +942,13 @@ Iterator XMLApplication::getAssertionConsumerServicesByBinding( return m_base ? m_base->getAssertionConsumerServicesByBinding(binding) : EMPTY(const IHandler*); } -Iterator XMLApplication::getHandlers(const char* path) const +const IHandler* XMLApplication::getHandler(const char* path) const { string wrap(path); - map >::const_iterator i=m_handlerMap.find(wrap.substr(0,wrap.find('?'))); + map::const_iterator i=m_handlerMap.find(wrap.substr(0,wrap.find('?'))); if (i!=m_handlerMap.end()) return i->second; - return m_base ? m_base->getHandlers(path) : EMPTY(const IHandler*); + return m_base ? m_base->getHandler(path) : NULL; } ReloadableXMLFileImpl* XMLConfig::newImplementation(const char* pathname, bool first) const diff --git a/shib-target/shib-target.cpp b/shib-target/shib-target.cpp index 9f6545c..3c6156b 100644 --- a/shib-target/shib-target.cpp +++ b/shib-target/shib-target.cpp @@ -341,33 +341,27 @@ pair ShibTarget::doHandler(void) // We dispatch based on our path info. We know the request URL begins with or equals the handler URL, // so the path info is the next character (or null). - pair hret; - Iterator handlers=m_priv->m_app->getHandlers(targetURL + strlen(handlerURL)); - - if (handlers.size()==0) + const IHandler* handler=m_priv->m_app->getHandler(targetURL + strlen(handlerURL)); + if (!handler) throw SAMLException("Shibboleth handler invoked at an unconfigured location."); - while (handlers.hasNext()) { - const IHandler* handler=handlers.next(); - - if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SAML2META_NS,SHIBT_L(AssertionConsumerService))) - procState = "Session Creation Error"; - else if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SessionInitiator))) - procState = "Session Initiator Error"; - else if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SAML2META_NS,SHIBT_L(SingleLogoutService))) - procState = "Session Termination Error"; - else if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SHIBTARGET_NS,SHIBT_L(DiagnosticService))) - procState = "Diagnostics Error"; - else - procState = "Extension Service Error"; - hret=handler->run(this); - - // Did the handler run successfully? - if (hret.first) - return hret; - } - - throw SAMLException("Configured Shibboleth handler(s) failed to fully process the request."); + if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SAML2META_NS,SHIBT_L(AssertionConsumerService))) + procState = "Session Creation Error"; + else if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SessionInitiator))) + procState = "Session Initiator Error"; + else if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SAML2META_NS,SHIBT_L(SingleLogoutService))) + procState = "Session Termination Error"; + else if (saml::XML::isElementNamed(handler->getProperties()->getElement(),shibtarget::XML::SHIBTARGET_NS,SHIBT_L(DiagnosticService))) + procState = "Diagnostics Error"; + else + procState = "Extension Service Error"; + pair hret=handler->run(this); + + // Did the handler run successfully? + if (hret.first) + return hret; + + throw SAMLException("Configured Shibboleth handler failed to process the request."); } catch (MetadataException& e) { mlp.insert(e); diff --git a/shib-target/shib-target.h b/shib-target/shib-target.h index 1547628..ff5bcf9 100644 --- a/shib-target/shib-target.h +++ b/shib-target/shib-target.h @@ -133,8 +133,8 @@ namespace shibtarget { virtual const IHandler* getAssertionConsumerServiceByIndex(unsigned short index) const=0; virtual saml::Iterator getAssertionConsumerServicesByBinding(const XMLCh* binding) const=0; - // Used by dispatcher to locate the handler(s) for a request - virtual saml::Iterator getHandlers(const char* path) const=0; + // Used by dispatcher to locate the handler for a request + virtual const IHandler* getHandler(const char* path) const=0; virtual ~IApplication() {} };