From 89cd55d63b109670f615c5adc941d93f0872be52 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Sun, 19 Sep 2010 01:47:48 +0000 Subject: [PATCH] Dispatch remoted messages through SP interface to support non-plugin extensions. --- shibsp/ServiceProvider.cpp | 33 +++++++++++++++++++++++++++++++- shibsp/ServiceProvider.h | 31 ++++++++++++++++++++++++++++++ shibsp/remoting/impl/ListenerService.cpp | 13 +++++++++---- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/shibsp/ServiceProvider.cpp b/shibsp/ServiceProvider.cpp index 0e5b3da..30e4423 100644 --- a/shibsp/ServiceProvider.cpp +++ b/shibsp/ServiceProvider.cpp @@ -174,10 +174,41 @@ SecurityPolicyProvider* ServiceProvider::getSecurityPolicyProvider(bool required { if (required) throw ConfigurationException("No SecurityPolicyProvider available."); - return NULL; + return nullptr; } #endif +Remoted* ServiceProvider::regListener(const char* address, Remoted* listener) +{ + Remoted* ret=nullptr; + map::const_iterator i=m_listenerMap.find(address); + if (i!=m_listenerMap.end()) + ret=i->second; + m_listenerMap[address]=listener; + Category::getInstance(SHIBSP_LOGCAT".ServiceProvider").info("registered remoted message endpoint (%s)",address); + return ret; +} + +bool ServiceProvider::unregListener(const char* address, Remoted* current, Remoted* restore) +{ + map::const_iterator i=m_listenerMap.find(address); + if (i!=m_listenerMap.end() && i->second==current) { + if (restore) + m_listenerMap[address]=restore; + else + m_listenerMap.erase(address); + Category::getInstance(SHIBSP_LOGCAT".ServiceProvider").info("unregistered remoted message endpoint (%s)",address); + return true; + } + return false; +} + +Remoted* ServiceProvider::lookupListener(const char *address) const +{ + map::const_iterator i=m_listenerMap.find(address); + return (i==m_listenerMap.end()) ? nullptr : i->second; +} + pair ServiceProvider::doAuthentication(SPRequest& request, bool handler) const { #ifdef _DEBUG diff --git a/shibsp/ServiceProvider.h b/shibsp/ServiceProvider.h index 59f75a4..f3003c4 100644 --- a/shibsp/ServiceProvider.h +++ b/shibsp/ServiceProvider.h @@ -43,6 +43,7 @@ namespace shibsp { class SHIBSP_API Application; class SHIBSP_API Handler; class SHIBSP_API ListenerService; + class SHIBSP_API Remoted; class SHIBSP_API RequestMapper; class SHIBSP_API SessionCache; class SHIBSP_API SPRequest; @@ -205,6 +206,36 @@ namespace shibsp { * @return a pair containing a "request completed" indicator and a server-specific response code */ virtual std::pair doHandler(SPRequest& request) const; + + /** + * Register for a message. Returns existing remote service, allowing message hooking. + * + * @param address message address to register + * @param svc pointer to remote service + * @return previous service registered for message, if any + */ + virtual Remoted* regListener(const char* address, Remoted* svc); + + /** + * Unregisters service from an address, possibly restoring an original. + * + * @param address message address to modify + * @param current pointer to unregistering service + * @param restore service to "restore" registration for + * @return true iff the current service was still registered + */ + virtual bool unregListener(const char* address, Remoted* current, Remoted* restore=nullptr); + + /** + * Returns current service registered at an address, if any. + * + * @param address message address to access + * @return registered service, or nullptr + */ + virtual Remoted* lookupListener(const char* address) const; + + private: + std::map m_listenerMap; }; /** diff --git a/shibsp/remoting/impl/ListenerService.cpp b/shibsp/remoting/impl/ListenerService.cpp index f0df7a4..2b1cd62 100644 --- a/shibsp/remoting/impl/ListenerService.cpp +++ b/shibsp/remoting/impl/ListenerService.cpp @@ -105,10 +105,15 @@ void ListenerService::receive(DDF &in, ostream& out) out << outmsg; } - Locker locker(SPConfig::getConfig().getServiceProvider()); - Remoted* dest=lookup(in.name()); - if (!dest) - throw ListenerException("No destination registered for incoming message addressed to ($1).",params(1,in.name())); + // Two stage lookup, on the listener itself, and the SP interface. + ServiceProvider* sp = SPConfig::getConfig().getServiceProvider(); + Locker locker(sp); + Remoted* dest = lookup(in.name()); + if (!dest) { + dest = sp->lookupListener(in.name()); + if (!dest) + throw ListenerException("No destination registered for incoming message addressed to ($1).", params(1,in.name())); + } dest->receive(in, out); } -- 2.1.4