CPPOST-15 - Adds APIs to support advanced metadata providers.
[shibboleth/cpp-sp.git] / shibsp / handler / impl / StatusHandler.cpp
index 0b8215a..41e9f1f 100644 (file)
@@ -31,6 +31,7 @@
 using namespace shibsp;
 #ifndef SHIBSP_LITE
 # include "SessionCache.h"
+# include "metadata/MetadataProviderCriteria.h"
 # include <saml/version.h>
 using namespace opensaml::saml2md;
 using namespace opensaml;
@@ -86,6 +87,16 @@ namespace shibsp {
     vector<string> g_NoCerts;
 #endif
 
+    static char _x2c(const char *what)
+    {
+        register char digit;
+
+        digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
+        digit *= 16;
+        digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
+        return(digit);
+    }
+
     class DummyRequest : public HTTPRequest
     {
     public:
@@ -129,7 +140,35 @@ namespace shibsp {
             else {
                 m_hostname.assign(url, slash - url);
             }
-            m_uri = slash;
+
+            while (*slash) {
+                if (*slash == '?') {
+                    m_uri += slash;
+                    break;
+                }
+                else if (*slash == ';') {
+                    // If this is Java being stupid, skip everything up to the query string, if any.
+                    if (!strncmp(slash, ";jsessionid=", 12)) {
+                        if (slash = strchr(slash, '?'))
+                            m_uri += slash;
+                        break;
+                    }
+                    else {
+                        m_uri += *slash;
+                    }
+                }
+                else if (*slash != '%') {
+                    m_uri += *slash;
+                }
+                else {
+                    ++slash;
+                    if (!isxdigit(*slash) || !isxdigit(*(slash+1)))
+                        throw invalid_argument("Bad request, contained unsupported encoded characters.");
+                    m_uri += _x2c(slash);
+                    ++slash;
+                }
+                ++slash;
+            }
         }
 
         ~DummyRequest() {
@@ -383,7 +422,18 @@ pair<bool,long> StatusHandler::processMessage(
             status = "<Partial/>";
         }
 
-        s << "<Application id='" << application.getId() << "' entityID='" << application.getString("entityID").second << "'/>";
+        const PropertySet* relyingParty=NULL;
+        param=httpRequest.getParameter("entityID");
+        if (param) {
+            MetadataProvider* m = application.getMetadataProvider();
+            Locker mlock(m);
+            relyingParty = application.getRelyingParty(m->getEntityDescriptor(MetadataProviderCriteria(application, param)).first);
+        }
+        else {
+            relyingParty = &application;
+        }
+
+        s << "<Application id='" << application.getId() << "' entityID='" << relyingParty->getString("entityID").second << "'/>";
 
         s << "<Handlers>";
         vector<const Handler*> handlers;
@@ -396,14 +446,6 @@ pair<bool,long> StatusHandler::processMessage(
         }
         s << "</Handlers>";
 
-        const PropertySet* relyingParty=NULL;
-        param=httpRequest.getParameter("entityID");
-        if (param) {
-            Locker mlock(application.getMetadataProvider());
-            relyingParty = application.getRelyingParty(application.getMetadataProvider()->getEntityDescriptor(param));
-        }
-        if (!relyingParty)
-            relyingParty = application.getRelyingParty(NULL);
         CredentialResolver* credResolver=application.getCredentialResolver();
         if (credResolver) {
             Locker credLocker(credResolver);
@@ -445,6 +487,6 @@ pair<bool,long> StatusHandler::processMessage(
     httpResponse.setContentType("text/xml");
     return make_pair(true, httpResponse.sendResponse(s));
 #else
-    return make_pair(false,0);
+    return make_pair(false,0L);
 #endif
 }