Working version of new handler configuration and supporting files.
[shibboleth/cpp-sp.git] / shibsp / binding / impl / XMLProtocolProvider.cpp
index 327a18f..5099e18 100644 (file)
@@ -41,11 +41,12 @@ using namespace std;
 \r
 namespace shibsp {\r
 \r
-    static const XMLCh _id[] =                  UNICODE_LITERAL_2(i,d);\r
-    static const XMLCh Binding[] =              UNICODE_LITERAL_7(B,i,n,d,i,n,g);\r
-    static const XMLCh Protocol[] =             UNICODE_LITERAL_8(P,r,o,t,o,c,o,l);\r
-    static const XMLCh Protocols[] =            UNICODE_LITERAL_9(P,r,o,t,o,c,o,l,s);\r
-    static const XMLCh Service[] =              UNICODE_LITERAL_7(S,e,r,v,i,c,e);\r
+    static const XMLCh _id[] =          UNICODE_LITERAL_2(i,d);\r
+    static const XMLCh Binding[] =      UNICODE_LITERAL_7(B,i,n,d,i,n,g);\r
+    static const XMLCh Initiator[] =    UNICODE_LITERAL_9(I,n,i,t,i,a,t,o,r);\r
+    static const XMLCh Protocol[] =     UNICODE_LITERAL_8(P,r,o,t,o,c,o,l);\r
+    static const XMLCh Protocols[] =    UNICODE_LITERAL_9(P,r,o,t,o,c,o,l,s);\r
+    static const XMLCh Service[] =      UNICODE_LITERAL_7(S,e,r,v,i,c,e);\r
 \r
 #if defined (_MSC_VER)\r
     #pragma warning( push )\r
@@ -80,7 +81,7 @@ namespace shibsp {
 \r
     private:\r
         DOMDocument* m_document;\r
-        // Map of protocol/service pair to a service propset plus an array of Binding propsets.\r
+        // Map of protocol/service pair to an Initiator propset plus an array of Binding propsets.\r
         typedef map< pair<string,string>, pair< PropertySet*,vector<const PropertySet*> > > protmap_t;\r
         protmap_t m_map;\r
 \r
@@ -100,16 +101,14 @@ namespace shibsp {
             delete m_impl;\r
         }\r
 \r
-        const PropertySet* getService(const char* protocol, const char* service) const {\r
+        const PropertySet* getInitiator(const char* protocol, const char* service) const {\r
             XMLProtocolProviderImpl::protmap_t::const_iterator i = m_impl->m_map.find(pair<string,string>(protocol,service));\r
             return (i != m_impl->m_map.end()) ? i->second.first : nullptr;\r
         }\r
 \r
         const vector<const PropertySet*>& getBindings(const char* protocol, const char* service) const {\r
             XMLProtocolProviderImpl::protmap_t::const_iterator i = m_impl->m_map.find(pair<string,string>(protocol,service));\r
-            if (i != m_impl->m_map.end())\r
-                return i->second.second;\r
-            throw ConfigurationException("ProtocolProvider can't return bindings for undefined protocol and service.");\r
+            return (i != m_impl->m_map.end()) ? i->second.second : m_noBindings;\r
         }\r
 \r
     protected:\r
@@ -117,6 +116,7 @@ namespace shibsp {
         pair<bool,DOMElement*> background_load();\r
 \r
     private:\r
+        static vector<const PropertySet*> m_noBindings;\r
         XMLProtocolProviderImpl* m_impl;\r
     };\r
 \r
@@ -143,6 +143,8 @@ ProtocolProvider::~ProtocolProvider()
 {\r
 }\r
 \r
+vector<const PropertySet*> XMLProtocolProvider::m_noBindings;\r
+\r
 XMLProtocolProviderImpl::XMLProtocolProviderImpl(const DOMElement* e, Category& log) : m_document(nullptr)\r
 {\r
 #ifdef _DEBUG\r
@@ -160,22 +162,26 @@ XMLProtocolProviderImpl::XMLProtocolProviderImpl(const DOMElement* e, Category&
             const DOMElement* svc = XMLHelper::getFirstChildElement(e, SHIB2SPPROTOCOLS_NS, Service);\r
             while (svc) {\r
                 string svcid = XMLHelper::getAttrString(svc, nullptr, _id);\r
-                if (!svcid.empty()) {\r
+                if (!svcid.empty() && m_map.count(make_pair(id,svcid)) == 0) {\r
                     pair< PropertySet*,vector<const PropertySet*> >& entry = m_map[make_pair(id,svcid)];\r
-                    if (!entry.first) {\r
-                        // Wrap the Service in a propset.\r
-                        DOMPropertySet* svcprop = new DOMPropertySet();\r
-                        entry.first = svcprop;\r
-                        svcprop->load(svc, &log, this);\r
-\r
-                        // Walk the Bindings.\r
-                        const DOMElement* bind = XMLHelper::getFirstChildElement(svc, SHIB2SPPROTOCOLS_NS, Binding);\r
-                        while (bind) {\r
-                            DOMPropertySet* bindprop = new DOMPropertySet();\r
-                            entry.second.push_back(bindprop);\r
-                            bindprop->load(bind, &log, this);\r
-                            bind = XMLHelper::getNextSiblingElement(bind, SHIB2SPPROTOCOLS_NS, Binding);\r
-                        }\r
+                    // Wrap the Initiator in a propset, if any.\r
+                    const DOMElement* child = XMLHelper::getFirstChildElement(svc, SHIB2SPPROTOCOLS_NS, Initiator);\r
+                    if (child) {\r
+                        DOMPropertySet* initprop = new DOMPropertySet();\r
+                        entry.first = initprop;\r
+                        initprop->load(child, nullptr, this);\r
+                    }\r
+                    else {\r
+                        entry.first = nullptr;\r
+                    }\r
+\r
+                    // Walk the Bindings.\r
+                    child = XMLHelper::getFirstChildElement(svc, SHIB2SPPROTOCOLS_NS, Binding);\r
+                    while (child) {\r
+                        DOMPropertySet* bindprop = new DOMPropertySet();\r
+                        entry.second.push_back(bindprop);\r
+                        bindprop->load(child, nullptr, this);\r
+                        child = XMLHelper::getNextSiblingElement(child, SHIB2SPPROTOCOLS_NS, Binding);\r
                     }\r
                 }\r
                 svc = XMLHelper::getNextSiblingElement(svc, SHIB2SPPROTOCOLS_NS, Service);\r