Support to use SOAP 1.1 or 1.2.
This commit is contained in:
@@ -12,10 +12,11 @@ namespace webcc {
|
||||
|
||||
SoapAsyncClient::SoapAsyncClient(boost::asio::io_context& io_context,
|
||||
const std::string& host,
|
||||
const std::string& port)
|
||||
const std::string& port,
|
||||
SoapVersion soap_version)
|
||||
: io_context_(io_context),
|
||||
host_(host), port_(port),
|
||||
soapenv_ns_(kSoapEnvNamespace),
|
||||
soap_version_(soap_version),
|
||||
format_raw_(true), timeout_seconds_(0) {
|
||||
if (port_.empty()) {
|
||||
std::size_t i = host_.find_last_of(':');
|
||||
@@ -35,7 +36,13 @@ void SoapAsyncClient::Request(const std::string& operation,
|
||||
|
||||
SoapRequest soap_request;
|
||||
|
||||
soap_request.set_soapenv_ns(soapenv_ns_);
|
||||
// Set SOAP envelope namespace according to SOAP version.
|
||||
if (soap_version_ == kSoapV11) {
|
||||
soap_request.set_soapenv_ns(kSoapEnvNamespaceV11);
|
||||
} else {
|
||||
soap_request.set_soapenv_ns(kSoapEnvNamespaceV12);
|
||||
}
|
||||
|
||||
soap_request.set_service_ns(service_ns_);
|
||||
|
||||
soap_request.set_operation(operation);
|
||||
@@ -52,7 +59,13 @@ void SoapAsyncClient::Request(const std::string& operation,
|
||||
http_request->set_method(kHttpPost);
|
||||
http_request->set_url(url_);
|
||||
http_request->SetContent(std::move(http_content), true);
|
||||
http_request->SetContentType(kTextXmlUtf8);
|
||||
|
||||
if (soap_version_ == kSoapV11) {
|
||||
http_request->SetContentType(kTextXmlUtf8);
|
||||
} else {
|
||||
http_request->SetContentType(kAppSoapXmlUtf8);
|
||||
}
|
||||
|
||||
http_request->SetHost(host_, port_);
|
||||
http_request->SetHeader(kSoapAction, operation);
|
||||
http_request->UpdateStartLine();
|
||||
|
||||
@@ -19,7 +19,8 @@ class SoapAsyncClient {
|
||||
// If |port| is empty, |host| will be checked to see if it contains port or
|
||||
// not (separated by ':').
|
||||
SoapAsyncClient(boost::asio::io_context& io_context, // NOLINT
|
||||
const std::string& host, const std::string& port = "");
|
||||
const std::string& host, const std::string& port = "",
|
||||
SoapVersion soap_version = kSoapV12);
|
||||
|
||||
~SoapAsyncClient() = default;
|
||||
|
||||
@@ -59,11 +60,13 @@ class SoapAsyncClient {
|
||||
std::string host_;
|
||||
std::string port_; // Leave this empty to use default 80.
|
||||
|
||||
SoapVersion soap_version_;
|
||||
|
||||
// Request URL.
|
||||
std::string url_;
|
||||
|
||||
SoapNamespace soapenv_ns_; // SOAP envelope namespace.
|
||||
SoapNamespace service_ns_; // Namespace for your web service.
|
||||
// Namespace for your web service.
|
||||
SoapNamespace service_ns_;
|
||||
|
||||
// Response result XML node name.
|
||||
// E.g., "Result".
|
||||
|
||||
+17
-4
@@ -8,9 +8,10 @@
|
||||
|
||||
namespace webcc {
|
||||
|
||||
SoapClient::SoapClient(const std::string& host, const std::string& port)
|
||||
SoapClient::SoapClient(const std::string& host, const std::string& port,
|
||||
SoapVersion soap_version)
|
||||
: host_(host), port_(port),
|
||||
soapenv_ns_(kSoapEnvNamespace),
|
||||
soap_version_(soap_version),
|
||||
format_raw_(true), error_(kNoError) {
|
||||
if (port_.empty()) {
|
||||
std::size_t i = host_.find_last_of(':');
|
||||
@@ -32,7 +33,13 @@ bool SoapClient::Request(const std::string& operation,
|
||||
|
||||
SoapRequest soap_request;
|
||||
|
||||
soap_request.set_soapenv_ns(soapenv_ns_);
|
||||
// Set SOAP envelope namespace according to SOAP version.
|
||||
if (soap_version_ == kSoapV11) {
|
||||
soap_request.set_soapenv_ns(kSoapEnvNamespaceV11);
|
||||
} else {
|
||||
soap_request.set_soapenv_ns(kSoapEnvNamespaceV12);
|
||||
}
|
||||
|
||||
soap_request.set_service_ns(service_ns_);
|
||||
|
||||
soap_request.set_operation(operation);
|
||||
@@ -49,7 +56,13 @@ bool SoapClient::Request(const std::string& operation,
|
||||
http_request.set_method(kHttpPost);
|
||||
http_request.set_url(url_);
|
||||
http_request.SetContent(std::move(http_content), true);
|
||||
http_request.SetContentType(kTextXmlUtf8);
|
||||
|
||||
if (soap_version_ == kSoapV11) {
|
||||
http_request.SetContentType(kTextXmlUtf8);
|
||||
} else {
|
||||
http_request.SetContentType(kAppSoapXmlUtf8);
|
||||
}
|
||||
|
||||
http_request.SetHost(host_, port_);
|
||||
http_request.SetHeader(kSoapAction, operation);
|
||||
http_request.UpdateStartLine();
|
||||
|
||||
+6
-3
@@ -14,7 +14,8 @@ class SoapClient {
|
||||
public:
|
||||
// If |port| is empty, |host| will be checked to see if it contains port or
|
||||
// not (separated by ':').
|
||||
explicit SoapClient(const std::string& host, const std::string& port = "");
|
||||
explicit SoapClient(const std::string& host, const std::string& port = "",
|
||||
SoapVersion soap_version = kSoapV12);
|
||||
|
||||
~SoapClient() = default;
|
||||
|
||||
@@ -56,11 +57,13 @@ class SoapClient {
|
||||
std::string host_;
|
||||
std::string port_; // Leave this empty to use default 80.
|
||||
|
||||
SoapVersion soap_version_;
|
||||
|
||||
// Request URL.
|
||||
std::string url_;
|
||||
|
||||
SoapNamespace soapenv_ns_; // SOAP envelope namespace.
|
||||
SoapNamespace service_ns_; // Namespace for your web service.
|
||||
// Namespace for your web service.
|
||||
SoapNamespace service_ns_;
|
||||
|
||||
// Response result XML node name.
|
||||
// E.g., "Result".
|
||||
|
||||
+16
-1
@@ -9,10 +9,25 @@ const std::string kSoapAction = "SOAPAction";
|
||||
// But in practice, many web servers cannot understand it.
|
||||
// See: https://www.w3.org/TR/2007/REC-soap12-part0-20070427/#L26854
|
||||
const std::string kTextXmlUtf8 = "text/xml; charset=utf-8";
|
||||
const std::string kAppSoapXmlUtf8 = "application/soap+xml; charset=utf-8";
|
||||
|
||||
const SoapNamespace kSoapEnvNamespace{
|
||||
// NOTE:
|
||||
// According to HTTP 1.1 RFC7231, the following examples are all equivalent,
|
||||
// but the first is preferred for consistency:
|
||||
// text/html;charset=utf-8
|
||||
// text/html;charset=UTF-8
|
||||
// Text/HTML;Charset="utf-8"
|
||||
// text/html; charset="utf-8"
|
||||
// See: https://tools.ietf.org/html/rfc7231#section-3.1.1.1
|
||||
|
||||
const SoapNamespace kSoapEnvNamespaceV11{
|
||||
"soap",
|
||||
"http://schemas.xmlsoap.org/soap/envelope/"
|
||||
};
|
||||
|
||||
const SoapNamespace kSoapEnvNamespaceV12{
|
||||
"soap",
|
||||
"http://www.w3.org/2003/05/soap-envelope"
|
||||
};
|
||||
|
||||
} // namespace webcc
|
||||
|
||||
+10
-3
@@ -11,11 +11,17 @@ namespace webcc {
|
||||
extern const std::string kSoapAction;
|
||||
|
||||
extern const std::string kTextXmlUtf8;
|
||||
extern const std::string kAppSoapXmlUtf8;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
enum SoapVersion {
|
||||
kSoapV11,
|
||||
kSoapV12,
|
||||
};
|
||||
|
||||
// XML namespace name/url pair.
|
||||
// E.g., { "soap", "http://schemas.xmlsoap.org/soap/envelope/" }
|
||||
// E.g., { "soap", "http://www.w3.org/2003/05/soap-envelope" }
|
||||
struct SoapNamespace {
|
||||
std::string name;
|
||||
std::string url;
|
||||
@@ -25,8 +31,9 @@ struct SoapNamespace {
|
||||
}
|
||||
};
|
||||
|
||||
// CSoap's default namespace for SOAP Envelope.
|
||||
extern const SoapNamespace kSoapEnvNamespace;
|
||||
// Default namespaces for SOAP Envelope.
|
||||
extern const SoapNamespace kSoapEnvNamespaceV11;
|
||||
extern const SoapNamespace kSoapEnvNamespaceV12;
|
||||
|
||||
} // namespace webcc
|
||||
|
||||
|
||||
@@ -30,6 +30,15 @@ void SoapRequestHandler::HandleSession(HttpSessionPtr session) {
|
||||
}
|
||||
|
||||
SoapResponse soap_response;
|
||||
|
||||
// Set SOAP envelope namespace according to SOAP version.
|
||||
// NOTE: This could be overwritten by service->Handle() anyway.
|
||||
if (soap_version_ == kSoapV11) {
|
||||
soap_response.set_soapenv_ns(kSoapEnvNamespaceV11);
|
||||
} else {
|
||||
soap_response.set_soapenv_ns(kSoapEnvNamespaceV12);
|
||||
}
|
||||
|
||||
if (!service->Handle(soap_request, &soap_response)) {
|
||||
session->SendResponse(HttpStatus::kBadRequest);
|
||||
return;
|
||||
@@ -37,7 +46,13 @@ void SoapRequestHandler::HandleSession(HttpSessionPtr session) {
|
||||
|
||||
std::string content;
|
||||
soap_response.ToXml(format_raw_, indent_str_, &content);
|
||||
session->SetResponseContent(std::move(content), kTextXmlUtf8);
|
||||
|
||||
if (soap_version_ == kSoapV11) {
|
||||
session->SetResponseContent(std::move(content), kTextXmlUtf8);
|
||||
} else {
|
||||
session->SetResponseContent(std::move(content), kAppSoapXmlUtf8);
|
||||
}
|
||||
|
||||
session->SendResponse(HttpStatus::kOK);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
#include <string>
|
||||
|
||||
#include "webcc/http_request_handler.h"
|
||||
#include "webcc/soap_globals.h"
|
||||
|
||||
namespace webcc {
|
||||
|
||||
class SoapRequestHandler : public HttpRequestHandler {
|
||||
public:
|
||||
SoapRequestHandler() : format_raw_(true) {}
|
||||
explicit SoapRequestHandler(SoapVersion soap_version)
|
||||
: soap_version_(soap_version),
|
||||
format_raw_(true) {
|
||||
}
|
||||
|
||||
~SoapRequestHandler() override = default;
|
||||
|
||||
@@ -30,6 +34,9 @@ class SoapRequestHandler : public HttpRequestHandler {
|
||||
typedef std::map<std::string, SoapServicePtr> UrlServiceMap;
|
||||
UrlServiceMap url_service_map_;
|
||||
|
||||
// Default to kSoapV12.
|
||||
SoapVersion soap_version_;
|
||||
|
||||
// Format response XML without any indentation or line breaks.
|
||||
bool format_raw_;
|
||||
|
||||
|
||||
+4
-2
@@ -12,8 +12,10 @@ namespace webcc {
|
||||
|
||||
class SoapServer : public HttpServer {
|
||||
public:
|
||||
SoapServer(std::uint16_t port, std::size_t workers)
|
||||
: HttpServer(port, workers) {
|
||||
SoapServer(std::uint16_t port, std::size_t workers,
|
||||
SoapVersion soap_version = kSoapV12)
|
||||
: HttpServer(port, workers),
|
||||
request_handler_(soap_version) {
|
||||
}
|
||||
|
||||
~SoapServer() override = default;
|
||||
|
||||
Reference in New Issue
Block a user