#define __xmltooling_soaptrans_h__
#include <xmltooling/base.h>
+
+#include <string>
#include <iostream>
namespace xmltooling {
#endif
/**
+ * Installs (or clears) a pointer to an object used for cache management of the
+ * content being accessed. The lifetime of the object must be longer than the lifetime
+ * of this object.
+ *
+ * @param cacheTag optional pointer to string used for cache management
+ */
+ virtual bool setCacheTag(std::string* cacheTag=NULL);
+
+ /**
* Sets an implementation-specific transport provider option.
*
* <p>Requires knowledge of the underlying SOAPTransport implementation.
* @return MIME type of response, or an empty string
*/
virtual std::string getContentType() const=0;
+
+ /**
+ * Returns the status code of the response.
+ *
+ * @return transport status code, or 0 if unknown
+ */
+ virtual long getStatusCode() const;
};
#ifndef XMLTOOLING_NO_XMLSEC
#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_authenticated(false) {
+ m_ssl_callback(NULL), m_ssl_userptr(NULL), m_chunked(true), m_authenticated(false), m_cacheTag(NULL) {
m_handle = g_CURLPool->get(addr);
curl_easy_setopt(m_handle,CURLOPT_URL,addr.m_endpoint);
curl_easy_setopt(m_handle,CURLOPT_CONNECTTIMEOUT,15);
return true;
}
+ bool setCacheTag(string* cacheTag) {
+ m_cacheTag = cacheTag;
+ return true;
+ }
+
bool setProviderOption(const char* provider, const char* option, const char* value) {
if (!provider || strcmp(provider, "CURL"))
return false;
}
string getContentType() const;
+ long getStatusCode() const;
bool setRequestHeader(const char* name, const char* val) {
string temp(name);
void* m_ssl_userptr;
bool m_chunked;
bool m_authenticated;
+ string* m_cacheTag;
friend size_t XMLTOOL_DLLLOCAL curl_header_hook(void* ptr, size_t size, size_t nmemb, void* stream);
friend CURLcode XMLTOOL_DLLLOCAL xml_ssl_ctx_callback(CURL* curl, SSL_CTX* ssl_ctx, void* userptr);
return content_type ? content_type : "";
}
+long CURLSOAPTransport::getStatusCode() const
+{
+ long code=200;
+ if (curl_easy_getinfo(m_handle, CURLINFO_RESPONSE_CODE, &code) != CURLE_OK)
+ code = 200;
+ return code;
+}
+
void CURLSOAPTransport::send(istream* in)
{
#ifdef _DEBUG
if (log_curl.isDebugEnabled())
curl_easy_setopt(m_handle,CURLOPT_VERBOSE,1);
+ // Check for cache tag.
+ if (m_cacheTag && !m_cacheTag->empty()) {
+ string hdr("If-None-Match: ");
+ hdr += *m_cacheTag;
+ m_headers = curl_slist_append(m_headers, hdr.c_str());
+ }
+
// Set request headers.
curl_easy_setopt(m_handle,CURLOPT_HTTPHEADER,m_headers);
string("CURLSOAPTransport failed while contacting SOAP endpoint (") + m_endpoint + "): " +
(curl_errorbuf[0] ? curl_errorbuf : "no further information available"));
}
+
+ // Check for outgoing cache tag.
+ if (m_cacheTag) {
+ const vector<string>& tags = getResponseHeader("ETag");
+ if (!tags.empty())
+ *m_cacheTag = tags.front();
+ }
}
// callback to buffer headers from server
return false;
}
+bool SOAPTransport::setCacheTag(string* cacheTag)
+{
+ return false;
+}
+
+void SOAPTransport::send(istream* in)
+{
+ if (!in)
+ throw IOException("SOAP transport does not support an empty request body.");
+ return send(*in);
+}
+
+long SOAPTransport::getStatusCode() const
+{
+ return 0;
+}
+
HTTPSOAPTransport::HTTPSOAPTransport()
{
}
m_transport=NULL;
}
-void SOAPTransport::send(istream* in)
-{
- if (!in)
- throw IOException("SOAP transport does not support an empty request body.");
- return send(*in);
-}
-
void SOAPClient::send(const Envelope& env, const SOAPTransport::Address& addr)
{
// Prepare a transport object.