From: Scott Cantor Date: Thu, 16 Aug 2007 03:19:55 +0000 (+0000) Subject: Add "sender" to SOAP APIs to avoid reuse of connections across apps. X-Git-Tag: 1.0-beta1~15 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-xmltooling.git;a=commitdiff_plain;h=3801ea7943567d42ec76b430d8aacfe1244b7985 Add "sender" to SOAP APIs to avoid reuse of connections across apps. --- diff --git a/xmltooling/XMLToolingConfig.h b/xmltooling/XMLToolingConfig.h index cb558a0..bd49bc5 100644 --- a/xmltooling/XMLToolingConfig.h +++ b/xmltooling/XMLToolingConfig.h @@ -25,6 +25,7 @@ #include #include +#include #include #ifndef XMLTOOLING_NO_XMLSEC @@ -43,7 +44,6 @@ namespace xmltooling { namespace xmltooling { - class XMLTOOL_API SOAPTransport; class XMLTOOL_API TemplateEngine; class XMLTOOL_API URLEncoder; #ifndef XMLTOOLING_LITE @@ -290,7 +290,7 @@ namespace xmltooling { * *

The factory interface takes a peer name/endpoint pair. */ - PluginManager > SOAPTransportManager; + PluginManager SOAPTransportManager; }; }; diff --git a/xmltooling/soap/SOAPClient.h b/xmltooling/soap/SOAPClient.h index 6e27d40..963c396 100644 --- a/xmltooling/soap/SOAPClient.h +++ b/xmltooling/soap/SOAPClient.h @@ -63,7 +63,7 @@ namespace soap11 { /** * Sends the supplied envelope to the identified recipient/endpoint. - * + * *

The client object will instantiate a transport layer object * appropriate for the endpoint URL provided and supply it to the * prepareTransport() method below. @@ -73,10 +73,9 @@ namespace soap11 { * in a subclass-specific version of the prepareTransport() method. * * @param env SOAP envelope to send - * @param peerName name of peer - * @param endpoint URL of endpoint to recieve message + * @param addr addressing information */ - virtual void send(const Envelope& env, const char* peerName, const char* endpoint); + virtual void send(const Envelope& env, const xmltooling::SOAPTransport::Address& addr); /** * Returns the response message, if any. As long as a response is diff --git a/xmltooling/soap/SOAPTransport.h b/xmltooling/soap/SOAPTransport.h index 6e95a05..8c41378 100644 --- a/xmltooling/soap/SOAPTransport.h +++ b/xmltooling/soap/SOAPTransport.h @@ -46,7 +46,31 @@ namespace xmltooling { SOAPTransport() {} public: virtual ~SOAPTransport() {} - + + /** + * A simple structure to capture SOAP addressing information. + */ + struct XMLTOOL_API Address { + /** + * Constructor. + * + * @param from name of sender + * @param to name of recipient + * @param endpoint endpoint URL + */ + Address(const char* from, const char* to, const char* endpoint) : m_from(from), m_to(to), m_endpoint(endpoint) { + } + + /** Name of sender. */ + const char* m_from; + + /** Name of recipient. */ + const char* m_to; + + /** Endpoint URL. */ + const char* m_endpoint; + }; + /** * Indicates whether transport provides confidentiality. * diff --git a/xmltooling/soap/impl/CURLSOAPTransport.cpp b/xmltooling/soap/impl/CURLSOAPTransport.cpp index 116d196..2ab5e3a 100644 --- a/xmltooling/soap/impl/CURLSOAPTransport.cpp +++ b/xmltooling/soap/impl/CURLSOAPTransport.cpp @@ -49,8 +49,8 @@ namespace xmltooling { m_log(Category::getInstance(XMLTOOLING_LOGCAT".SOAPTransport.CURLPool")) {} ~CURLPool(); - CURL* get(const char* to, const char* endpoint); - void put(const char* to, const char* endpoint, CURL* handle); + CURL* get(const SOAPTransport::Address& addr); + void put(const char* from, const char* to, const char* endpoint, CURL* handle); private: typedef map > poolmap_t; @@ -66,14 +66,15 @@ namespace xmltooling { class XMLTOOL_DLLLOCAL CURLSOAPTransport : public HTTPSOAPTransport, public OpenSSLSOAPTransport { public: - CURLSOAPTransport(const char* peerName, const char* endpoint) - : m_peerName(peerName ? peerName : ""), m_endpoint(endpoint), m_handle(NULL), m_headers(NULL), + CURLSOAPTransport(const Address& addr) + : m_sender(addr.m_from ? addr.m_from : ""), m_peerName(addr.m_to ? addr.m_to : ""), m_endpoint(addr.m_endpoint), + m_handle(NULL), m_headers(NULL), #ifndef XMLTOOLING_NO_XMLSEC m_cred(NULL), m_trustEngine(NULL), m_peerResolver(NULL), m_mandatory(false), #endif m_ssl_callback(NULL), m_ssl_userptr(NULL), m_chunked(true), m_secure(false) { - m_handle = g_CURLPool->get(peerName, endpoint); - curl_easy_setopt(m_handle,CURLOPT_URL,endpoint); + m_handle = g_CURLPool->get(addr); + curl_easy_setopt(m_handle,CURLOPT_URL,addr.m_endpoint); curl_easy_setopt(m_handle,CURLOPT_CONNECTTIMEOUT,15); curl_easy_setopt(m_handle,CURLOPT_TIMEOUT,30); curl_easy_setopt(m_handle,CURLOPT_HTTPAUTH,0); @@ -87,7 +88,7 @@ namespace xmltooling { curl_slist_free_all(m_headers); curl_easy_setopt(m_handle,CURLOPT_ERRORBUFFER,NULL); curl_easy_setopt(m_handle,CURLOPT_PRIVATE,m_secure ? "secure" : NULL); // Save off security "state". - g_CURLPool->put(m_peerName.c_str(), m_endpoint.c_str(), m_handle); + g_CURLPool->put(m_sender.c_str(), m_peerName.c_str(), m_endpoint.c_str(), m_handle); } bool isConfidential() const { @@ -193,7 +194,7 @@ namespace xmltooling { private: // per-call state - string m_peerName,m_endpoint,m_simplecreds; + string m_sender,m_peerName,m_endpoint,m_simplecreds; CURL* m_handle; stringstream m_stream; struct curl_slist* m_headers; @@ -225,9 +226,9 @@ namespace xmltooling { int XMLTOOL_DLLLOCAL verify_callback(X509_STORE_CTX* x509_ctx, void* arg); #endif - SOAPTransport* CURLSOAPTransportFactory(const pair& dest) + SOAPTransport* CURLSOAPTransportFactory(const SOAPTransport::Address& addr) { - return new CURLSOAPTransport(dest.first, dest.second); + return new CURLSOAPTransport(addr); } }; @@ -258,14 +259,19 @@ CURLPool::~CURLPool() delete m_lock; } -CURL* CURLPool::get(const char* to, const char* endpoint) +CURL* CURLPool::get(const SOAPTransport::Address& addr) { #ifdef _DEBUG xmltooling::NDC("get"); #endif - m_log.debug("getting connection handle to %s", endpoint); + m_log.debug("getting connection handle to %s", addr.m_endpoint); + string key(addr.m_endpoint); + if (addr.m_from) + key = key + '|' + addr.m_from; + if (addr.m_to) + key = key + '|' + addr.m_to; m_lock->lock(); - poolmap_t::iterator i=m_bindingMap.find(string(to) + "|" + endpoint); + poolmap_t::iterator i=m_bindingMap.find(key); if (i!=m_bindingMap.end()) { // Move this pool to the front of the list. @@ -304,9 +310,13 @@ CURL* CURLPool::get(const char* to, const char* endpoint) return handle; } -void CURLPool::put(const char* to, const char* endpoint, CURL* handle) +void CURLPool::put(const char* from, const char* to, const char* endpoint, CURL* handle) { - string key = string(to) + "|" + endpoint; + string key(endpoint); + if (from) + key = key + '|' + from; + if (to) + key = key + '|' + to; m_lock->lock(); poolmap_t::iterator i=m_bindingMap.find(key); if (i==m_bindingMap.end()) diff --git a/xmltooling/soap/impl/SOAPClient.cpp b/xmltooling/soap/impl/SOAPClient.cpp index 23d9b8c..fdca645 100644 --- a/xmltooling/soap/impl/SOAPClient.cpp +++ b/xmltooling/soap/impl/SOAPClient.cpp @@ -46,14 +46,14 @@ void SOAPClient::reset() m_transport=NULL; } -void SOAPClient::send(const Envelope& env, const char* peerName, const char* endpoint) +void SOAPClient::send(const Envelope& env, const SOAPTransport::Address& addr) { // Prepare a transport object. - const char* pch = strchr(endpoint,':'); + const char* pch = strchr(addr.m_endpoint,':'); if (!pch) throw IOException("SOAP endpoint was not a URL."); - string scheme(endpoint, pch-endpoint); - m_transport = XMLToolingConfig::getConfig().SOAPTransportManager.newPlugin(scheme.c_str(), make_pair(peerName,endpoint)); + string scheme(addr.m_endpoint, pch-addr.m_endpoint); + m_transport = XMLToolingConfig::getConfig().SOAPTransportManager.newPlugin(scheme.c_str(), addr); prepareTransport(*m_transport); // Serialize envelope.