Code refactoring.
This commit is contained in:
@@ -3,7 +3,6 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "boost/lexical_cast.hpp"
|
|
||||||
#include "boost/thread/thread.hpp"
|
#include "boost/thread/thread.hpp"
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);
|
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);
|
||||||
|
|
||||||
unsigned short port = std::atoi(argv[1]);
|
std::uint16_t port = static_cast<std::uint16_t>(std::atoi(argv[1]));
|
||||||
|
|
||||||
int sleep_seconds = 0;
|
int sleep_seconds = 0;
|
||||||
if (argc >= 3) {
|
if (argc >= 3) {
|
||||||
@@ -56,7 +56,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
server.Run();
|
server.Run();
|
||||||
|
|
||||||
} catch (std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << "Exception: " << e.what() << std::endl;
|
std::cerr << "Exception: " << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "calc_client.h"
|
#include "calc_client.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "boost/lexical_cast.hpp"
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
|
|
||||||
// Set to 0 to test our own calculator server created with webcc.
|
// Set to 0 to test our own calculator server created with webcc.
|
||||||
@@ -80,8 +81,8 @@ bool CalcClient::Calc(const std::string& operation,
|
|||||||
|
|
||||||
// Convert the result from string to double.
|
// Convert the result from string to double.
|
||||||
try {
|
try {
|
||||||
*result = boost::lexical_cast<double>(result_str);
|
*result = std::stod(result_str);
|
||||||
} catch (boost::bad_lexical_cast&) {
|
} catch (const std::exception&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#include "calc_service.h"
|
#include "calc_service.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// Sleep several seconds for the client to test timeout control.
|
// Sleep several seconds for the client to test timeout control.
|
||||||
#define SLEEP_FOR_TIMEOUT_TEST 0
|
#define SLEEP_FOR_TIMEOUT_TEST 0
|
||||||
|
|
||||||
#include "boost/lexical_cast.hpp"
|
|
||||||
|
|
||||||
#if SLEEP_FOR_TIMEOUT_TEST
|
#if SLEEP_FOR_TIMEOUT_TEST
|
||||||
#include "boost/thread/thread.hpp"
|
#include "boost/thread/thread.hpp"
|
||||||
#endif
|
#endif
|
||||||
@@ -82,10 +83,10 @@ bool CalcService::GetParameters(const webcc::SoapRequest& soap_request,
|
|||||||
double* x,
|
double* x,
|
||||||
double* y) {
|
double* y) {
|
||||||
try {
|
try {
|
||||||
*x = boost::lexical_cast<double>(soap_request.GetParameter("x"));
|
*x = std::stod(soap_request.GetParameter("x"));
|
||||||
*y = boost::lexical_cast<double>(soap_request.GetParameter("y"));
|
*y = std::stod(soap_request.GetParameter("y"));
|
||||||
|
|
||||||
} catch (boost::bad_lexical_cast& e) {
|
} catch (const std::exception& e) {
|
||||||
LOG_ERRO("Parameter cast error: %s", e.what());
|
LOG_ERRO("Parameter cast error: %s", e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);
|
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);
|
||||||
|
|
||||||
unsigned short port = std::atoi(argv[1]);
|
std::uint16_t port = static_cast<std::uint16_t>(std::atoi(argv[1]));
|
||||||
|
|
||||||
std::size_t workers = 2;
|
std::size_t workers = 2;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
server.Run();
|
server.Run();
|
||||||
|
|
||||||
} catch (std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << "Exception: " << e.what() << std::endl;
|
std::cerr << "Exception: " << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
# Don't use any deprecated definitions (e.g., io_service).
|
# Don't use any deprecated definitions (e.g., io_service).
|
||||||
add_definitions(-DBOOST_ASIO_NO_DEPRECATED)
|
add_definitions(-DBOOST_ASIO_NO_DEPRECATED)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(SRCS
|
set(SRCS
|
||||||
async_http_client.cc
|
async_http_client.cc
|
||||||
async_http_client.h
|
async_http_client.h
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ extern void AdjustBufferSize(std::size_t content_length,
|
|||||||
|
|
||||||
AsyncHttpClient::AsyncHttpClient(boost::asio::io_context& io_context)
|
AsyncHttpClient::AsyncHttpClient(boost::asio::io_context& io_context)
|
||||||
: socket_(io_context),
|
: socket_(io_context),
|
||||||
|
resolver_(new tcp::resolver(io_context)),
|
||||||
buffer_(kBufferSize),
|
buffer_(kBufferSize),
|
||||||
|
deadline_(io_context),
|
||||||
timeout_seconds_(kMaxReceiveSeconds),
|
timeout_seconds_(kMaxReceiveSeconds),
|
||||||
deadline_(io_context) {
|
stopped_(false),
|
||||||
resolver_.reset(new tcp::resolver(io_context));
|
timed_out_(false) {
|
||||||
response_.reset(new HttpResponse());
|
|
||||||
response_parser_.reset(new HttpResponseParser(response_.get()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Error AsyncHttpClient::Request(std::shared_ptr<HttpRequest> request,
|
Error AsyncHttpClient::Request(std::shared_ptr<HttpRequest> request,
|
||||||
@@ -31,6 +31,9 @@ Error AsyncHttpClient::Request(std::shared_ptr<HttpRequest> request,
|
|||||||
assert(request);
|
assert(request);
|
||||||
assert(response_handler);
|
assert(response_handler);
|
||||||
|
|
||||||
|
response_.reset(new HttpResponse());
|
||||||
|
response_parser_.reset(new HttpResponseParser(response_.get()));
|
||||||
|
|
||||||
LOG_VERB("HTTP request:\n%s", request->Dump(4, "> ").c_str());
|
LOG_VERB("HTTP request:\n%s", request->Dump(4, "> ").c_str());
|
||||||
|
|
||||||
request_ = request;
|
request_ = request;
|
||||||
@@ -53,8 +56,10 @@ Error AsyncHttpClient::Request(std::shared_ptr<HttpRequest> request,
|
|||||||
|
|
||||||
void AsyncHttpClient::Stop() {
|
void AsyncHttpClient::Stop() {
|
||||||
stopped_ = true;
|
stopped_ = true;
|
||||||
|
|
||||||
boost::system::error_code ignored_ec;
|
boost::system::error_code ignored_ec;
|
||||||
socket_.close(ignored_ec);
|
socket_.close(ignored_ec);
|
||||||
|
|
||||||
deadline_.cancel();
|
deadline_.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +77,8 @@ void AsyncHttpClient::ResolveHandler(boost::system::error_code ec,
|
|||||||
// Start the deadline actor. You will note that we're not setting any
|
// Start the deadline actor. You will note that we're not setting any
|
||||||
// particular deadline here. Instead, the connect and input actors will
|
// particular deadline here. Instead, the connect and input actors will
|
||||||
// update the deadline prior to each asynchronous operation.
|
// update the deadline prior to each asynchronous operation.
|
||||||
deadline_.async_wait(std::bind(&AsyncHttpClient::CheckDeadline, this));
|
deadline_.async_wait(std::bind(&AsyncHttpClient::CheckDeadline,
|
||||||
|
shared_from_this()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +116,6 @@ void AsyncHttpClient::ConnectHandler(boost::system::error_code ec,
|
|||||||
// of the asynchronous operation. If the socket is closed at this time then
|
// of the asynchronous operation. If the socket is closed at this time then
|
||||||
// the timeout handler must have run first.
|
// the timeout handler must have run first.
|
||||||
LOG_WARN("Connect timed out.");
|
LOG_WARN("Connect timed out.");
|
||||||
|
|
||||||
// Try the next available endpoint.
|
// Try the next available endpoint.
|
||||||
AsyncConnect(++endpoint_iter);
|
AsyncConnect(++endpoint_iter);
|
||||||
} else if (ec) {
|
} else if (ec) {
|
||||||
@@ -118,7 +123,6 @@ void AsyncHttpClient::ConnectHandler(boost::system::error_code ec,
|
|||||||
// We need to close the socket used in the previous connection attempt
|
// We need to close the socket used in the previous connection attempt
|
||||||
// before starting a new one.
|
// before starting a new one.
|
||||||
socket_.close();
|
socket_.close();
|
||||||
|
|
||||||
// Try the next available endpoint.
|
// Try the next available endpoint.
|
||||||
AsyncConnect(++endpoint_iter);
|
AsyncConnect(++endpoint_iter);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
|
// Request handler/callback.
|
||||||
typedef std::function<void(HttpResponsePtr, Error, bool)> HttpResponseHandler;
|
typedef std::function<void(HttpResponsePtr, Error, bool)> HttpResponseHandler;
|
||||||
|
|
||||||
class AsyncHttpClient : public std::enable_shared_from_this<AsyncHttpClient> {
|
class AsyncHttpClient : public std::enable_shared_from_this<AsyncHttpClient> {
|
||||||
@@ -57,29 +58,26 @@ class AsyncHttpClient : public std::enable_shared_from_this<AsyncHttpClient> {
|
|||||||
|
|
||||||
void CheckDeadline();
|
void CheckDeadline();
|
||||||
|
|
||||||
bool stopped_ = false;
|
|
||||||
bool timed_out_ = false;
|
|
||||||
|
|
||||||
tcp::socket socket_;
|
tcp::socket socket_;
|
||||||
|
|
||||||
std::shared_ptr<HttpRequest> request_;
|
|
||||||
|
|
||||||
std::unique_ptr<tcp::resolver> resolver_;
|
std::unique_ptr<tcp::resolver> resolver_;
|
||||||
tcp::resolver::results_type endpoints_;
|
tcp::resolver::results_type endpoints_;
|
||||||
|
|
||||||
|
std::shared_ptr<HttpRequest> request_;
|
||||||
std::vector<char> buffer_;
|
std::vector<char> buffer_;
|
||||||
|
|
||||||
std::unique_ptr<HttpResponseParser> response_parser_;
|
|
||||||
|
|
||||||
HttpResponsePtr response_;
|
HttpResponsePtr response_;
|
||||||
|
std::unique_ptr<HttpResponseParser> response_parser_;
|
||||||
HttpResponseHandler response_handler_;
|
HttpResponseHandler response_handler_;
|
||||||
|
|
||||||
|
// Timer for the timeout control.
|
||||||
|
boost::asio::deadline_timer deadline_;
|
||||||
|
|
||||||
// Maximum seconds to wait before the client cancels the operation.
|
// Maximum seconds to wait before the client cancels the operation.
|
||||||
// Only for receiving response from server.
|
// Only for receiving response from server.
|
||||||
int timeout_seconds_;
|
int timeout_seconds_;
|
||||||
|
|
||||||
// Timer for the timeout control.
|
bool stopped_;
|
||||||
boost::asio::deadline_timer deadline_;
|
bool timed_out_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<AsyncHttpClient> HttpAsyncClientPtr;
|
typedef std::shared_ptr<AsyncHttpClient> HttpAsyncClientPtr;
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
|
AsyncRestClient::AsyncRestClient(boost::asio::io_context& io_context,
|
||||||
|
const std::string& host,
|
||||||
|
const std::string& port)
|
||||||
|
: io_context_(io_context), host_(host), port_(port), timeout_seconds_(0) {
|
||||||
|
}
|
||||||
|
|
||||||
void AsyncRestClient::Request(const std::string& method,
|
void AsyncRestClient::Request(const std::string& method,
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
const std::string& content,
|
const std::string& content,
|
||||||
@@ -21,6 +27,11 @@ void AsyncRestClient::Request(const std::string& method,
|
|||||||
request->Build();
|
request->Build();
|
||||||
|
|
||||||
HttpAsyncClientPtr http_client(new AsyncHttpClient(io_context_));
|
HttpAsyncClientPtr http_client(new AsyncHttpClient(io_context_));
|
||||||
|
|
||||||
|
if (timeout_seconds_ > 0) {
|
||||||
|
http_client->set_timeout_seconds(timeout_seconds_);
|
||||||
|
}
|
||||||
|
|
||||||
http_client->Request(request, response_handler_);
|
http_client->Request(request, response_handler_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,18 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "webcc/globals.h"
|
|
||||||
#include "webcc/async_http_client.h"
|
#include "webcc/async_http_client.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
class AsyncRestClient {
|
class AsyncRestClient {
|
||||||
public:
|
public:
|
||||||
AsyncRestClient(boost::asio::io_context& io_context,
|
AsyncRestClient(boost::asio::io_context& io_context, // NOLINT
|
||||||
const std::string& host, const std::string& port)
|
const std::string& host,
|
||||||
: io_context_(io_context), host_(host), port_(port) {
|
const std::string& port);
|
||||||
|
|
||||||
|
void set_timeout_seconds(int timeout_seconds) {
|
||||||
|
timeout_seconds_ = timeout_seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get(const std::string& url,
|
void Get(const std::string& url,
|
||||||
@@ -50,9 +52,14 @@ class AsyncRestClient {
|
|||||||
HttpResponseHandler response_handler);
|
HttpResponseHandler response_handler);
|
||||||
|
|
||||||
boost::asio::io_context& io_context_;
|
boost::asio::io_context& io_context_;
|
||||||
|
|
||||||
std::string host_;
|
std::string host_;
|
||||||
std::string port_;
|
std::string port_;
|
||||||
|
|
||||||
HttpResponseHandler response_handler_;
|
HttpResponseHandler response_handler_;
|
||||||
|
|
||||||
|
// Timeout in seconds; only effective when > 0.
|
||||||
|
int timeout_seconds_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webcc
|
} // namespace webcc
|
||||||
|
|||||||
+21
-25
@@ -6,27 +6,31 @@ namespace webcc {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// NOTE:
|
// NOTE: Field names are case-insensitive.
|
||||||
// Field names are case-insensitive.
|
// See https://stackoverflow.com/a/5259004 for more details.
|
||||||
// See: https://stackoverflow.com/a/5259004
|
const std::string kHost = "Host";
|
||||||
const std::string kContentType = "Content-Type";
|
const std::string kContentType = "Content-Type";
|
||||||
const std::string kContentLength = "Content-Length";
|
const std::string kContentLength = "Content-Length";
|
||||||
const std::string kSoapAction = "SOAPAction";
|
|
||||||
const std::string kHost = "Host";
|
|
||||||
|
|
||||||
|
#ifdef WEBCC_ENABLE_SOAP
|
||||||
|
const std::string kSoapAction = "SOAPAction";
|
||||||
|
#endif // WEBCC_ENABLE_SOAP
|
||||||
|
|
||||||
|
const std::string kTextJsonUtf8 = "text/json; charset=utf-8";
|
||||||
|
|
||||||
|
#ifdef WEBCC_ENABLE_SOAP
|
||||||
// According to www.w3.org when placing SOAP messages in HTTP bodies, the HTTP
|
// According to www.w3.org when placing SOAP messages in HTTP bodies, the HTTP
|
||||||
// Content-type header must be chosen as "application/soap+xml" [RFC 3902].
|
// Content-type header must be chosen as "application/soap+xml" [RFC 3902].
|
||||||
// But in practice, many web servers cannot understand it.
|
// But in practice, many web servers cannot understand it.
|
||||||
// See: https://www.w3.org/TR/2007/REC-soap12-part0-20070427/#L26854
|
// See: https://www.w3.org/TR/2007/REC-soap12-part0-20070427/#L26854
|
||||||
const std::string kTextXmlUtf8 = "text/xml; charset=utf-8";
|
const std::string kTextXmlUtf8 = "text/xml; charset=utf-8";
|
||||||
|
#endif // WEBCC_ENABLE_SOAP
|
||||||
|
|
||||||
const std::string kTextJsonUtf8 = "text/json; charset=utf-8";
|
const std::string kHttpHead = "HEAD";
|
||||||
|
const std::string kHttpGet = "GET";
|
||||||
const std::string kHttpHead = "HEAD";
|
const std::string kHttpPost = "POST";
|
||||||
const std::string kHttpGet = "GET";
|
const std::string kHttpPatch = "PATCH";
|
||||||
const std::string kHttpPost = "POST";
|
const std::string kHttpPut = "PUT";
|
||||||
const std::string kHttpPatch = "PATCH";
|
|
||||||
const std::string kHttpPut = "PUT";
|
|
||||||
const std::string kHttpDelete = "DELETE";
|
const std::string kHttpDelete = "DELETE";
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -65,35 +69,27 @@ Parameter::Parameter(const std::string& key, std::string&& value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Parameter::Parameter(const std::string& key, int value)
|
Parameter::Parameter(const std::string& key, int value)
|
||||||
: key_(key) {
|
: key_(key), value_(std::to_string(value)) {
|
||||||
value_ = std::to_string(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Parameter::Parameter(const std::string& key, double value)
|
Parameter::Parameter(const std::string& key, double value)
|
||||||
: key_(key) {
|
: key_(key), value_(std::to_string(value)) {
|
||||||
value_ = std::to_string(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Parameter::Parameter(const std::string& key, bool value)
|
Parameter::Parameter(const std::string& key, bool value)
|
||||||
: key_(key) {
|
: key_(key), value_(value ? "true" : "false") {
|
||||||
value_ = value ? "true" : "false";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Parameter::Parameter(Parameter&& rhs)
|
Parameter::Parameter(Parameter&& rhs)
|
||||||
: key_(std::move(rhs.key_)),
|
: key_(std::move(rhs.key_)), value_(std::move(rhs.value_)) {
|
||||||
value_(std::move(rhs.value_)) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Parameter& Parameter::operator=(Parameter&& rhs) {
|
Parameter& Parameter::operator=(Parameter&& rhs) {
|
||||||
if (this != &rhs) {
|
if (&rhs != this) {
|
||||||
key_ = std::move(rhs.key_);
|
key_ = std::move(rhs.key_);
|
||||||
value_ = std::move(rhs.value_);
|
value_ = std::move(rhs.value_);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Parameter::ToString() const {
|
|
||||||
return key_ + "=" + value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webcc
|
} // namespace webcc
|
||||||
|
|||||||
+17
-19
@@ -23,18 +23,25 @@ const std::size_t kBufferSize = 1024;
|
|||||||
const std::size_t kInvalidLength = static_cast<std::size_t>(-1);
|
const std::size_t kInvalidLength = static_cast<std::size_t>(-1);
|
||||||
|
|
||||||
// Timeout seconds.
|
// Timeout seconds.
|
||||||
|
// TODO
|
||||||
const int kMaxConnectSeconds = 10;
|
const int kMaxConnectSeconds = 10;
|
||||||
const int kMaxSendSeconds = 10;
|
const int kMaxSendSeconds = 30;
|
||||||
const int kMaxReceiveSeconds = 30;
|
const int kMaxReceiveSeconds = 30;
|
||||||
|
|
||||||
|
extern const std::string kHost;
|
||||||
extern const std::string kContentType;
|
extern const std::string kContentType;
|
||||||
extern const std::string kContentLength;
|
extern const std::string kContentLength;
|
||||||
extern const std::string kSoapAction;
|
|
||||||
extern const std::string kHost;
|
|
||||||
|
|
||||||
extern const std::string kTextXmlUtf8;
|
#ifdef WEBCC_ENABLE_SOAP
|
||||||
|
extern const std::string kSoapAction;
|
||||||
|
#endif // WEBCC_ENABLE_SOAP
|
||||||
|
|
||||||
extern const std::string kTextJsonUtf8;
|
extern const std::string kTextJsonUtf8;
|
||||||
|
|
||||||
|
#ifdef WEBCC_ENABLE_SOAP
|
||||||
|
extern const std::string kTextXmlUtf8;
|
||||||
|
#endif // WEBCC_ENABLE_SOAP
|
||||||
|
|
||||||
// HTTP methods (verbs) in string ("HEAD", "GET", etc.).
|
// HTTP methods (verbs) in string ("HEAD", "GET", etc.).
|
||||||
// NOTE: Don't use enum to avoid converting back and forth.
|
// NOTE: Don't use enum to avoid converting back and forth.
|
||||||
extern const std::string kHttpHead;
|
extern const std::string kHttpHead;
|
||||||
@@ -99,25 +106,16 @@ class Parameter {
|
|||||||
// Use "= default" if drop the support of VS 2013.
|
// Use "= default" if drop the support of VS 2013.
|
||||||
Parameter& operator=(Parameter&& rhs);
|
Parameter& operator=(Parameter&& rhs);
|
||||||
|
|
||||||
const std::string& key() const {
|
const std::string& key() const { return key_; }
|
||||||
return key_;
|
const std::string& value() const { return value_; }
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& value() const {
|
const char* c_key() const { return key_.c_str(); }
|
||||||
return value_;
|
const char* c_value() const { return value_.c_str(); }
|
||||||
}
|
|
||||||
|
|
||||||
const char* c_key() const {
|
std::string ToString() const {
|
||||||
return key_.c_str();
|
return key_ + "=" + value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* c_value() const {
|
|
||||||
return value_.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return "key=value" string.
|
|
||||||
std::string ToString() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string key_;
|
std::string key_;
|
||||||
std::string value_;
|
std::string value_;
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
#include "boost/lambda/lambda.hpp"
|
#include "boost/lambda/lambda.hpp"
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
#include "webcc/http_request.h"
|
|
||||||
#include "webcc/http_response.h"
|
|
||||||
|
|
||||||
// NOTE:
|
// NOTE:
|
||||||
// The timeout control is inspired by the following Asio example:
|
// The timeout control is inspired by the following Asio example:
|
||||||
@@ -34,17 +32,20 @@ void AdjustBufferSize(std::size_t content_length, std::vector<char>* buffer) {
|
|||||||
std::size_t min_buffer_size = content_length / kMaxTimes;
|
std::size_t min_buffer_size = content_length / kMaxTimes;
|
||||||
if (min_buffer_size > buffer->size()) {
|
if (min_buffer_size > buffer->size()) {
|
||||||
buffer->resize(std::min(min_buffer_size, kMaxBufferSize));
|
buffer->resize(std::min(min_buffer_size, kMaxBufferSize));
|
||||||
LOG_INFO("Resize read buffer to %d.", buffer->size());
|
LOG_INFO("Resize read buffer to %u.", buffer->size());
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Keep the current buffer size (%d).", buffer->size());
|
LOG_INFO("Keep the current buffer size: %u.", buffer->size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpClient::HttpClient()
|
HttpClient::HttpClient()
|
||||||
: socket_(io_context_),
|
: socket_(io_context_),
|
||||||
buffer_(kBufferSize),
|
buffer_(kBufferSize),
|
||||||
|
deadline_(io_context_),
|
||||||
timeout_seconds_(kMaxReceiveSeconds),
|
timeout_seconds_(kMaxReceiveSeconds),
|
||||||
deadline_(io_context_) {
|
stopped_(false),
|
||||||
|
timed_out_(false),
|
||||||
|
error_(kNoError) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpClient::Request(const HttpRequest& request) {
|
bool HttpClient::Request(const HttpRequest& request) {
|
||||||
@@ -189,7 +190,7 @@ void HttpClient::DoReadResponse(Error* error) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("Read data, length: %d.", length);
|
LOG_INFO("Read data, length: %u.", length);
|
||||||
|
|
||||||
bool content_length_parsed = response_parser_->content_length_parsed();
|
bool content_length_parsed = response_parser_->content_length_parsed();
|
||||||
|
|
||||||
|
|||||||
+9
-11
@@ -19,7 +19,6 @@ namespace webcc {
|
|||||||
class HttpClient {
|
class HttpClient {
|
||||||
public:
|
public:
|
||||||
HttpClient();
|
HttpClient();
|
||||||
|
|
||||||
~HttpClient() = default;
|
~HttpClient() = default;
|
||||||
|
|
||||||
DELETE_COPY_AND_ASSIGN(HttpClient);
|
DELETE_COPY_AND_ASSIGN(HttpClient);
|
||||||
@@ -31,10 +30,10 @@ class HttpClient {
|
|||||||
|
|
||||||
HttpResponsePtr response() const { return response_; }
|
HttpResponsePtr response() const { return response_; }
|
||||||
|
|
||||||
Error error() const { return error_; }
|
|
||||||
|
|
||||||
bool timed_out() const { return timed_out_; }
|
bool timed_out() const { return timed_out_; }
|
||||||
|
|
||||||
|
Error error() const { return error_; }
|
||||||
|
|
||||||
// Connect to server, send request, wait until response is received.
|
// Connect to server, send request, wait until response is received.
|
||||||
bool Request(const HttpRequest& request);
|
bool Request(const HttpRequest& request);
|
||||||
|
|
||||||
@@ -53,7 +52,6 @@ class HttpClient {
|
|||||||
void CheckDeadline();
|
void CheckDeadline();
|
||||||
|
|
||||||
boost::asio::io_context io_context_;
|
boost::asio::io_context io_context_;
|
||||||
|
|
||||||
boost::asio::ip::tcp::socket socket_;
|
boost::asio::ip::tcp::socket socket_;
|
||||||
|
|
||||||
std::vector<char> buffer_;
|
std::vector<char> buffer_;
|
||||||
@@ -61,18 +59,18 @@ class HttpClient {
|
|||||||
HttpResponsePtr response_;
|
HttpResponsePtr response_;
|
||||||
std::unique_ptr<HttpResponseParser> response_parser_;
|
std::unique_ptr<HttpResponseParser> response_parser_;
|
||||||
|
|
||||||
Error error_ = kNoError;
|
boost::asio::deadline_timer deadline_;
|
||||||
|
|
||||||
bool stopped_ = false;
|
|
||||||
|
|
||||||
// If the error was caused by timeout or not.
|
|
||||||
bool timed_out_ = false;
|
|
||||||
|
|
||||||
// Maximum seconds to wait before the client cancels the operation.
|
// Maximum seconds to wait before the client cancels the operation.
|
||||||
// Only for receiving response from server.
|
// Only for receiving response from server.
|
||||||
int timeout_seconds_;
|
int timeout_seconds_;
|
||||||
|
|
||||||
boost::asio::deadline_timer deadline_;
|
bool stopped_;
|
||||||
|
|
||||||
|
// If the error was caused by timeout or not.
|
||||||
|
bool timed_out_;
|
||||||
|
|
||||||
|
Error error_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webcc
|
} // namespace webcc
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ void HttpConnection::AsyncWrite() {
|
|||||||
void HttpConnection::WriteHandler(boost::system::error_code ec,
|
void HttpConnection::WriteHandler(boost::system::error_code ec,
|
||||||
std::size_t length) {
|
std::size_t length) {
|
||||||
if (!ec) {
|
if (!ec) {
|
||||||
LOG_INFO("Response has been sent back.");
|
LOG_INFO("Response has been sent back, length: %u.", length);
|
||||||
|
|
||||||
// Initiate graceful connection closure.
|
// Initiate graceful connection closure.
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class HttpRequestHandler;
|
|||||||
|
|
||||||
class HttpConnection : public std::enable_shared_from_this<HttpConnection> {
|
class HttpConnection : public std::enable_shared_from_this<HttpConnection> {
|
||||||
public:
|
public:
|
||||||
HttpConnection(boost::asio::ip::tcp::socket socket,
|
HttpConnection(boost::asio::ip::tcp::socket socket, // Will be moved
|
||||||
HttpRequestHandler* handler);
|
HttpRequestHandler* handler);
|
||||||
|
|
||||||
~HttpConnection() = default;
|
~HttpConnection() = default;
|
||||||
|
|||||||
@@ -10,8 +10,7 @@
|
|||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
class HttpHeader {
|
struct HttpHeader {
|
||||||
public:
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
@@ -21,20 +20,15 @@ class HttpMessage {
|
|||||||
public:
|
public:
|
||||||
virtual ~HttpMessage() = default;
|
virtual ~HttpMessage() = default;
|
||||||
|
|
||||||
const std::string& start_line() const {
|
const std::string& start_line() const { return start_line_; }
|
||||||
return start_line_;
|
|
||||||
}
|
|
||||||
void set_start_line(const std::string& start_line) {
|
void set_start_line(const std::string& start_line) {
|
||||||
start_line_ = start_line;
|
start_line_ = start_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t content_length() const {
|
std::size_t content_length() const { return content_length_; }
|
||||||
return content_length_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& content() const {
|
const std::string& content() const { return content_; }
|
||||||
return content_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetHeader(const std::string& name, const std::string& value);
|
void SetHeader(const std::string& name, const std::string& value);
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -1,7 +1,6 @@
|
|||||||
#include "webcc/http_parser.h"
|
#include "webcc/http_parser.h"
|
||||||
|
|
||||||
#include "boost/algorithm/string.hpp"
|
#include "boost/algorithm/string.hpp"
|
||||||
#include "boost/lexical_cast.hpp"
|
|
||||||
|
|
||||||
#include "webcc/http_message.h"
|
#include "webcc/http_message.h"
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
@@ -111,23 +110,24 @@ void HttpParser::ParseContentLength(const std::string& line) {
|
|||||||
std::string value = line.substr(pos);
|
std::string value = line.substr(pos);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
content_length_ = boost::lexical_cast<std::size_t>(value);
|
content_length_ = static_cast<std::size_t>(std::stoul(value));
|
||||||
LOG_INFO("Content length: %d", content_length_);
|
} catch (const std::exception& e) {
|
||||||
|
|
||||||
// Reserve memory to avoid frequent reallocation when append.
|
|
||||||
try {
|
|
||||||
content_.reserve(content_length_);
|
|
||||||
} catch (std::exception& e) {
|
|
||||||
LOG_ERRO("Failed to reserve content memory: %s.", e.what());
|
|
||||||
}
|
|
||||||
} catch (boost::bad_lexical_cast&) {
|
|
||||||
LOG_ERRO("Invalid content length: %s.", value.c_str());
|
LOG_ERRO("Invalid content length: %s.", value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_INFO("Content length: %u.", content_length_);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Reserve memory to avoid frequent reallocation when append.
|
||||||
|
content_.reserve(content_length_);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
LOG_ERRO("Failed to reserve content memory: %s.", e.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpParser::Finish() {
|
void HttpParser::Finish() {
|
||||||
// Move temp content to message.
|
// Move content to message.
|
||||||
message_->SetContent(std::move(content_));
|
message_->SetContent(std::move(content_));
|
||||||
finished_ = true;
|
finished_ = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ class HttpParser {
|
|||||||
// The result HTTP message.
|
// The result HTTP message.
|
||||||
HttpMessage* message_;
|
HttpMessage* message_;
|
||||||
|
|
||||||
Error error_;
|
|
||||||
|
|
||||||
// Data waiting to be parsed.
|
// Data waiting to be parsed.
|
||||||
std::string pending_data_;
|
std::string pending_data_;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,17 @@
|
|||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace misc_strings {
|
||||||
|
|
||||||
|
const char NAME_VALUE_SEPARATOR[] = { ':', ' ' };
|
||||||
|
const char CRLF[] = { '\r', '\n' };
|
||||||
|
|
||||||
|
} // misc_strings
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void HttpRequest::SetHost(const std::string& host, const std::string& port) {
|
void HttpRequest::SetHost(const std::string& host, const std::string& port) {
|
||||||
host_ = host;
|
host_ = host;
|
||||||
port_ = port;
|
port_ = port;
|
||||||
@@ -22,13 +33,6 @@ void HttpRequest::Build() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace misc_strings {
|
|
||||||
|
|
||||||
const char NAME_VALUE_SEPARATOR[] = { ':', ' ' };
|
|
||||||
const char CRLF[] = { '\r', '\n' };
|
|
||||||
|
|
||||||
} // misc_strings
|
|
||||||
|
|
||||||
// ATTENTION: The buffers don't hold the memory!
|
// ATTENTION: The buffers don't hold the memory!
|
||||||
std::vector<boost::asio::const_buffer> HttpRequest::ToBuffers() const {
|
std::vector<boost::asio::const_buffer> HttpRequest::ToBuffers() const {
|
||||||
assert(!start_line_.empty());
|
assert(!start_line_.empty());
|
||||||
|
|||||||
@@ -19,29 +19,14 @@ class HttpRequest : public HttpMessage {
|
|||||||
|
|
||||||
virtual ~HttpRequest() = default;
|
virtual ~HttpRequest() = default;
|
||||||
|
|
||||||
const std::string& method() const {
|
const std::string& method() const { return method_; }
|
||||||
return method_;
|
void set_method(const std::string& method) { method_ = method; }
|
||||||
}
|
|
||||||
|
|
||||||
void set_method(const std::string& method) {
|
const std::string& url() const { return url_; }
|
||||||
method_ = method;
|
void set_url(const std::string& url) { url_ = url; }
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& url() const {
|
const std::string& host() const { return host_; }
|
||||||
return url_;
|
const std::string& port() const { return port_; }
|
||||||
}
|
|
||||||
|
|
||||||
void set_url(const std::string& url) {
|
|
||||||
url_ = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& host() const {
|
|
||||||
return host_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& port() const {
|
|
||||||
return port_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set host name and port number.
|
// Set host name and port number.
|
||||||
// The |host| is a descriptive name or a numeric IP address. The |port| is
|
// The |host| is a descriptive name or a numeric IP address. The |port| is
|
||||||
|
|||||||
@@ -13,16 +13,13 @@ namespace webcc {
|
|||||||
|
|
||||||
class HttpResponse : public HttpMessage {
|
class HttpResponse : public HttpMessage {
|
||||||
public:
|
public:
|
||||||
HttpResponse() = default;
|
HttpResponse() : status_(HttpStatus::kOK) {
|
||||||
|
}
|
||||||
|
|
||||||
~HttpResponse() override = default;
|
~HttpResponse() override = default;
|
||||||
|
|
||||||
int status() const {
|
int status() const { return status_; }
|
||||||
return status_;
|
void set_status(int status) { status_ = status; }
|
||||||
}
|
|
||||||
|
|
||||||
void set_status(int status) {
|
|
||||||
status_ = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the response into a vector of buffers. The buffers do not own the
|
// Convert the response into a vector of buffers. The buffers do not own the
|
||||||
// underlying memory blocks, therefore the response object must remain valid
|
// underlying memory blocks, therefore the response object must remain valid
|
||||||
@@ -33,7 +30,7 @@ class HttpResponse : public HttpMessage {
|
|||||||
static HttpResponse Fault(HttpStatus::Enum status);
|
static HttpResponse Fault(HttpStatus::Enum status);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int status_ = HttpStatus::kOK;
|
int status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<HttpResponse> HttpResponsePtr;
|
typedef std::shared_ptr<HttpResponse> HttpResponsePtr;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#include "webcc/http_response_parser.h"
|
#include "webcc/http_response_parser.h"
|
||||||
|
|
||||||
#include "boost/lexical_cast.hpp"
|
|
||||||
|
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
#include "webcc/http_response.h"
|
#include "webcc/http_response.h"
|
||||||
|
|
||||||
@@ -34,8 +32,8 @@ bool HttpResponseParser::ParseStartLine(const std::string& line) {
|
|||||||
std::string status_str = line.substr(off, pos - off);
|
std::string status_str = line.substr(off, pos - off);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
response_->set_status(boost::lexical_cast<int>(status_str));
|
response_->set_status(std::stoi(status_str));
|
||||||
} catch (boost::bad_lexical_cast&) {
|
} catch (const std::exception&) {
|
||||||
LOG_ERRO("Invalid HTTP status: %s", status_str.c_str());
|
LOG_ERRO("Invalid HTTP status: %s", status_str.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ using tcp = boost::asio::ip::tcp;
|
|||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
HttpServer::HttpServer(unsigned short port, std::size_t workers)
|
HttpServer::HttpServer(std::uint16_t port, std::size_t workers)
|
||||||
: signals_(io_context_) , workers_(workers) {
|
: signals_(io_context_) , workers_(workers) {
|
||||||
// Register to handle the signals that indicate when the server should exit.
|
// Register to handle the signals that indicate when the server should exit.
|
||||||
// It is safe to register for the same signal multiple times in a program,
|
// It is safe to register for the same signal multiple times in a program,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class HttpRequestHandler;
|
|||||||
// NOTE: Only support IPv4.
|
// NOTE: Only support IPv4.
|
||||||
class HttpServer {
|
class HttpServer {
|
||||||
public:
|
public:
|
||||||
HttpServer(unsigned short port, std::size_t workers);
|
HttpServer(std::uint16_t port, std::size_t workers);
|
||||||
|
|
||||||
virtual ~HttpServer() = default;
|
virtual ~HttpServer() = default;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -56,7 +56,7 @@ namespace bfs = boost::filesystem;
|
|||||||
|
|
||||||
static bfs::path InitLogPath(const std::string& dir) {
|
static bfs::path InitLogPath(const std::string& dir) {
|
||||||
if (dir.empty()) {
|
if (dir.empty()) {
|
||||||
return bfs::current_path() / WEBCC_LOG_FILE;
|
return bfs::current_path() / WEBCC_LOG_FILE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
bfs::path path = bfs::path(dir);
|
bfs::path path = bfs::path(dir);
|
||||||
@@ -67,7 +67,7 @@ static bfs::path InitLogPath(const std::string& dir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
path /= WEBCC_LOG_FILE;
|
path /= WEBCC_LOG_FILE_NAME;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -8,18 +8,21 @@
|
|||||||
#include <cstring> // for strrchr()
|
#include <cstring> // for strrchr()
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define WEBCC_VERB 0
|
// Log levels.
|
||||||
|
#define WEBCC_VERB 0 // Similar to DEBUG in other projects.
|
||||||
#define WEBCC_INFO 1
|
#define WEBCC_INFO 1
|
||||||
#define WEBCC_WARN 2
|
#define WEBCC_WARN 2
|
||||||
#define WEBCC_ERRO 3
|
#define WEBCC_ERRO 3
|
||||||
#define WEBCC_FATA 4
|
#define WEBCC_FATA 4
|
||||||
|
|
||||||
// Default log level.
|
// Default log level.
|
||||||
|
// You have to define a proper log level in CMakeLists.txt, e.g.,
|
||||||
|
// add_definitions(-DWEBCC_LOG_LEVEL=2)
|
||||||
#ifndef WEBCC_LOG_LEVEL
|
#ifndef WEBCC_LOG_LEVEL
|
||||||
#define WEBCC_LOG_LEVEL WEBCC_WARN
|
#define WEBCC_LOG_LEVEL WEBCC_WARN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WEBCC_LOG_FILE "webcc.log"
|
#define WEBCC_LOG_FILE_NAME "webcc.log"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
@@ -129,7 +132,7 @@ void LogWrite(int level, const char* file, int line, const char* format, ...);
|
|||||||
|
|
||||||
#else // WEBCC_ENABLE_LOG == 0
|
#else // WEBCC_ENABLE_LOG == 0
|
||||||
|
|
||||||
#define WEBCC_LOG_INIT(modes)
|
#define WEBCC_LOG_INIT(dir, modes)
|
||||||
|
|
||||||
#if (defined(WIN32) || defined(_WIN64))
|
#if (defined(WIN32) || defined(_WIN64))
|
||||||
#define LOG_VERB(format, ...)
|
#define LOG_VERB(format, ...)
|
||||||
|
|||||||
@@ -5,10 +5,19 @@
|
|||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
|
|
||||||
|
RestClient::RestClient(const std::string& host, const std::string& port)
|
||||||
|
: host_(host),
|
||||||
|
port_(port),
|
||||||
|
timeout_seconds_(0),
|
||||||
|
timed_out_(false),
|
||||||
|
error_(kNoError) {
|
||||||
|
}
|
||||||
|
|
||||||
bool RestClient::Request(const std::string& method,
|
bool RestClient::Request(const std::string& method,
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
const std::string& content) {
|
const std::string& content) {
|
||||||
response_.reset();
|
response_.reset();
|
||||||
|
|
||||||
error_ = kNoError;
|
error_ = kNoError;
|
||||||
timed_out_ = false;
|
timed_out_ = false;
|
||||||
|
|
||||||
|
|||||||
+16
-14
@@ -11,9 +11,11 @@ namespace webcc {
|
|||||||
|
|
||||||
class RestClient {
|
class RestClient {
|
||||||
public:
|
public:
|
||||||
RestClient(const std::string& host, const std::string& port)
|
RestClient(const std::string& host, const std::string& port);
|
||||||
: host_(host), port_(port) {
|
|
||||||
}
|
~RestClient() = default;
|
||||||
|
|
||||||
|
DELETE_COPY_AND_ASSIGN(RestClient);
|
||||||
|
|
||||||
void set_timeout_seconds(int timeout_seconds) {
|
void set_timeout_seconds(int timeout_seconds) {
|
||||||
timeout_seconds_ = timeout_seconds;
|
timeout_seconds_ = timeout_seconds;
|
||||||
@@ -31,27 +33,27 @@ class RestClient {
|
|||||||
return response_->content();
|
return response_->content();
|
||||||
}
|
}
|
||||||
|
|
||||||
Error error() const { return error_; }
|
|
||||||
|
|
||||||
bool timed_out() const { return timed_out_; }
|
bool timed_out() const { return timed_out_; }
|
||||||
|
|
||||||
bool Get(const std::string& url) {
|
Error error() const { return error_; }
|
||||||
|
|
||||||
|
inline bool Get(const std::string& url) {
|
||||||
return Request(kHttpGet, url, "");
|
return Request(kHttpGet, url, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Post(const std::string& url, const std::string& content) {
|
inline bool Post(const std::string& url, const std::string& content) {
|
||||||
return Request(kHttpPost, url, content);
|
return Request(kHttpPost, url, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Put(const std::string& url, const std::string& content) {
|
inline bool Put(const std::string& url, const std::string& content) {
|
||||||
return Request(kHttpPut, url, content);
|
return Request(kHttpPut, url, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Patch(const std::string& url, const std::string& content) {
|
inline bool Patch(const std::string& url, const std::string& content) {
|
||||||
return Request(kHttpPatch, url, content);
|
return Request(kHttpPatch, url, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Delete(const std::string& url) {
|
inline bool Delete(const std::string& url) {
|
||||||
return Request(kHttpDelete, url, "");
|
return Request(kHttpDelete, url, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,14 +66,14 @@ class RestClient {
|
|||||||
std::string port_;
|
std::string port_;
|
||||||
|
|
||||||
// Timeout in seconds; only effective when > 0.
|
// Timeout in seconds; only effective when > 0.
|
||||||
int timeout_seconds_ = 0;
|
int timeout_seconds_;
|
||||||
|
|
||||||
HttpResponsePtr response_;
|
HttpResponsePtr response_;
|
||||||
|
|
||||||
Error error_ = kNoError;
|
|
||||||
|
|
||||||
// If the error was caused by timeout or not.
|
// If the error was caused by timeout or not.
|
||||||
bool timed_out_ = false;
|
bool timed_out_;
|
||||||
|
|
||||||
|
Error error_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webcc
|
} // namespace webcc
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace webcc {
|
|||||||
|
|
||||||
class RestServer : public HttpServer {
|
class RestServer : public HttpServer {
|
||||||
public:
|
public:
|
||||||
RestServer(unsigned short port, std::size_t workers)
|
RestServer(std::uint16_t port, std::size_t workers)
|
||||||
: HttpServer(port, workers) {
|
: HttpServer(port, workers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ class RestListService : public RestService {
|
|||||||
protected:
|
protected:
|
||||||
RestListService() = default;
|
RestListService() = default;
|
||||||
|
|
||||||
virtual bool Get(const UrlQuery& query,
|
virtual bool Get(const UrlQuery& query, std::string* response_content) {
|
||||||
std::string* response_content) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ class SoapClient {
|
|||||||
bool timed_out() const { return timed_out_; }
|
bool timed_out() const { return timed_out_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SoapClient() = default;
|
SoapClient() : timeout_seconds_(0), timed_out_(false) {
|
||||||
|
}
|
||||||
|
|
||||||
// A generic wrapper to make a call.
|
// A generic wrapper to make a call.
|
||||||
// NOTE: The parameters should be movable.
|
// NOTE: The parameters should be movable.
|
||||||
@@ -27,10 +28,10 @@ class SoapClient {
|
|||||||
std::string* result);
|
std::string* result);
|
||||||
|
|
||||||
// Timeout in seconds; only effective when > 0.
|
// Timeout in seconds; only effective when > 0.
|
||||||
int timeout_seconds_ = 0;
|
int timeout_seconds_;
|
||||||
|
|
||||||
// If the error was caused by timeout or not.
|
// If the error was caused by timeout or not.
|
||||||
bool timed_out_ = false;
|
bool timed_out_;
|
||||||
|
|
||||||
SoapNamespace soapenv_ns_; // SOAP envelope namespace.
|
SoapNamespace soapenv_ns_; // SOAP envelope namespace.
|
||||||
SoapNamespace service_ns_; // Namespace for your web service.
|
SoapNamespace service_ns_; // Namespace for your web service.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace webcc {
|
|||||||
|
|
||||||
class SoapServer : public HttpServer {
|
class SoapServer : public HttpServer {
|
||||||
public:
|
public:
|
||||||
SoapServer(unsigned short port, std::size_t workers)
|
SoapServer(std::uint16_t port, std::size_t workers)
|
||||||
: HttpServer(port, workers) {
|
: HttpServer(port, workers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user