Abdandon the template RestBasicClient.

master
Chunting Gu 7 years ago
parent 360d09508e
commit ae9d4efcf1

@ -27,13 +27,13 @@ int main(int argc, char* argv[]) {
request.set_host(host); // Leave port to default value. request.set_host(host); // Leave port to default value.
request.Make(); request.Make();
webcc::HttpSslClient client;
// Verify the certificate of the peer or not. // Verify the certificate of the peer or not.
// See HttpSslClient::Request() for more details. // See HttpSslClient::Request() for more details.
bool ssl_verify = false; bool ssl_verify = false;
if (client.Request(request, ssl_verify)) { webcc::HttpSslClient client(ssl_verify);
if (client.Request(request)) {
std::cout << client.response()->content() << std::endl; std::cout << client.response()->content() << std::endl;
} else { } else {
std::cout << webcc::DescribeError(client.error()); std::cout << webcc::DescribeError(client.error());

@ -29,7 +29,6 @@ set(HEADERS
logger.h logger.h
queue.h queue.h
rest_async_client.h rest_async_client.h
rest_basic_client.h
rest_client.h rest_client.h
rest_request_handler.h rest_request_handler.h
rest_server.h rest_server.h
@ -55,6 +54,7 @@ set(SOURCES
http_server.cc http_server.cc
logger.cc logger.cc
rest_async_client.cc rest_async_client.cc
rest_client.cc
rest_request_handler.cc rest_request_handler.cc
rest_service_manager.cc rest_service_manager.cc
rest_service.cc rest_service.cc
@ -70,6 +70,7 @@ if(WEBCC_ENABLE_SSL)
set(SOURCES ${SOURCES} set(SOURCES ${SOURCES}
http_ssl_client.cc http_ssl_client.cc
rest_ssl_client.cc
) )
endif() endif()

@ -15,11 +15,12 @@ namespace ssl = boost::asio::ssl;
namespace webcc { namespace webcc {
HttpSslClient::HttpSslClient() HttpSslClient::HttpSslClient(bool ssl_verify)
: ssl_context_(ssl::context::sslv23), : ssl_context_(ssl::context::sslv23),
ssl_socket_(io_context_, ssl_context_), ssl_socket_(io_context_, ssl_context_),
buffer_(kBufferSize), buffer_(kBufferSize),
deadline_(io_context_), deadline_(io_context_),
ssl_verify_(ssl_verify),
timeout_seconds_(kMaxReadSeconds), timeout_seconds_(kMaxReadSeconds),
stopped_(false), stopped_(false),
timed_out_(false), timed_out_(false),
@ -34,7 +35,7 @@ void HttpSslClient::SetTimeout(int seconds) {
} }
} }
bool HttpSslClient::Request(const HttpRequest& request, bool ssl_verify) { bool HttpSslClient::Request(const HttpRequest& request) {
io_context_.restart(); io_context_.restart();
response_.reset(new HttpResponse()); response_.reset(new HttpResponse());
@ -48,7 +49,7 @@ bool HttpSslClient::Request(const HttpRequest& request, bool ssl_verify) {
return false; return false;
} }
if ((error_ = Handshake(request.host(), ssl_verify)) != kNoError) { if ((error_ = Handshake(request.host())) != kNoError) {
return false; return false;
} }
@ -95,8 +96,8 @@ Error HttpSslClient::Connect(const HttpRequest& request) {
} }
// NOTE: Don't check timeout. It doesn't make much sense. // NOTE: Don't check timeout. It doesn't make much sense.
Error HttpSslClient::Handshake(const std::string& host, bool ssl_verify) { Error HttpSslClient::Handshake(const std::string& host) {
if (ssl_verify) { if (ssl_verify_) {
ssl_socket_.set_verify_mode(ssl::verify_peer); ssl_socket_.set_verify_mode(ssl::verify_peer);
} else { } else {
ssl_socket_.set_verify_mode(ssl::verify_none); ssl_socket_.set_verify_mode(ssl::verify_none);

@ -23,7 +23,11 @@ namespace webcc {
// Don't use the same HttpClient object in multiple threads. // Don't use the same HttpClient object in multiple threads.
class HttpSslClient { class HttpSslClient {
public: public:
HttpSslClient(); // NOTE:
// SSL verification (ssl_verify=true) needs CA certificates to be found
// in the default verify paths of OpenSSL. On Windows, it means you need to
// set environment variable SSL_CERT_FILE properly.
HttpSslClient(bool ssl_verify = true);
~HttpSslClient() = default; ~HttpSslClient() = default;
@ -34,10 +38,7 @@ class HttpSslClient {
void SetTimeout(int seconds); void SetTimeout(int seconds);
// Connect to server, send request, wait until response is received. // Connect to server, send request, wait until response is received.
// NOTE: SSL verification (ssl_verify=true) needs CA certificates to be found bool Request(const HttpRequest& request);
// in the default verify paths of OpenSSL. On Windows, it means you need to
// set environment variable SSL_CERT_FILE properly.
bool Request(const HttpRequest& request, bool ssl_verify = true);
HttpResponsePtr response() const { return response_; } HttpResponsePtr response() const { return response_; }
@ -48,7 +49,7 @@ class HttpSslClient {
private: private:
Error Connect(const HttpRequest& request); Error Connect(const HttpRequest& request);
Error Handshake(const std::string& host, bool ssl_verify); Error Handshake(const std::string& host);
Error SendReqeust(const HttpRequest& request); Error SendReqeust(const HttpRequest& request);
@ -73,6 +74,9 @@ class HttpSslClient {
boost::asio::deadline_timer deadline_; boost::asio::deadline_timer deadline_;
// Verify the certificate of the peer (remote server) or not.
bool ssl_verify_;
// 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_;

@ -1,123 +0,0 @@
#ifndef WEBCC_REST_BASIC_CLIENT_H_
#define WEBCC_REST_BASIC_CLIENT_H_
#include <cassert>
#include <string>
#include <utility> // for move()
#include "webcc/globals.h"
#include "webcc/http_request.h"
#include "webcc/http_response.h"
namespace webcc {
template <class HttpClientType>
class RestBasicClient {
public:
// If |port| is empty, |host| will be checked to see if it contains port or
// not (separated by ':').
explicit RestBasicClient(const std::string& host,
const std::string& port = "")
: host_(host), port_(port) {
if (port_.empty()) {
std::size_t i = host_.find_last_of(':');
if (i != std::string::npos) {
port_ = host_.substr(i + 1);
host_ = host_.substr(0, i);
}
}
}
~RestBasicClient() = default;
WEBCC_DELETE_COPY_ASSIGN(RestBasicClient);
void SetTimeout(int seconds) {
http_client_.SetTimeout(seconds);
}
// NOTE:
// The return value of the following methods (Get, Post, etc.) only indicates
// if the socket communication is successful or not. Check error() and
// timed_out() for more information if it's failed. Check response_status()
// instead for the HTTP status code.
// HTTP GET request.
inline bool Get(const std::string& url) {
return Request(kHttpGet, url, "");
}
// HTTP POST request.
inline bool Post(const std::string& url, std::string&& content) {
return Request(kHttpPost, url, std::move(content));
}
// HTTP PUT request.
inline bool Put(const std::string& url, std::string&& content) {
return Request(kHttpPut, url, std::move(content));
}
// HTTP PATCH request.
inline bool Patch(const std::string& url, std::string&& content) {
return Request(kHttpPatch, url, std::move(content));
}
// HTTP DELETE request.
inline bool Delete(const std::string& url) {
return Request(kHttpDelete, url, "");
}
HttpResponsePtr response() const {
return http_client_.response();
}
int response_status() const {
assert(response());
return response()->status();
}
const std::string& response_content() const {
assert(response());
return response()->content();
}
bool timed_out() const {
return http_client_.timed_out();
}
Error error() const {
return http_client_.error();
}
private:
bool Request(const std::string& method, const std::string& url,
std::string&& content) {
HttpRequest http_request;
http_request.set_method(method);
http_request.set_url(url);
http_request.set_host(host_, port_);
if (!content.empty()) {
http_request.SetContent(std::move(content), true);
http_request.SetContentType(kAppJsonUtf8);
}
http_request.Make();
if (!http_client_.Request(http_request)) {
return false;
}
return true;
}
std::string host_;
std::string port_;
HttpClientType http_client_;
};
} // namespace webcc
#endif // WEBCC_REST_BASIC_CLIENT_H_

@ -0,0 +1,38 @@
#include "webcc/rest_client.h"
namespace webcc {
RestClient::RestClient(const std::string& host, const std::string& port)
: host_(host), port_(port) {
if (port_.empty()) {
std::size_t i = host_.find_last_of(':');
if (i != std::string::npos) {
port_ = host_.substr(i + 1);
host_ = host_.substr(0, i);
}
}
}
bool RestClient::Request(const std::string& method, const std::string& url,
std::string&& content) {
HttpRequest http_request;
http_request.set_method(method);
http_request.set_url(url);
http_request.set_host(host_, port_);
if (!content.empty()) {
http_request.SetContent(std::move(content), true);
http_request.SetContentType(kAppJsonUtf8);
}
http_request.Make();
if (!http_client_.Request(http_request)) {
return false;
}
return true;
}
} // namespace webcc

@ -1,12 +1,89 @@
#ifndef WEBCC_REST_CLIENT_H_ #ifndef WEBCC_REST_CLIENT_H_
#define WEBCC_REST_CLIENT_H_ #define WEBCC_REST_CLIENT_H_
#include "webcc/rest_basic_client.h" #include <cassert>
#include <string>
#include <utility> // for move()
#include "webcc/globals.h"
#include "webcc/http_client.h" #include "webcc/http_client.h"
#include "webcc/http_request.h"
#include "webcc/http_response.h"
namespace webcc { namespace webcc {
typedef RestBasicClient<HttpClient> RestClient; class RestClient {
public:
// If |port| is empty, |host| will be checked to see if it contains port or
// not (separated by ':').
explicit RestClient(const std::string& host,
const std::string& port = "");
~RestClient() = default;
WEBCC_DELETE_COPY_ASSIGN(RestClient);
void SetTimeout(int seconds) {
http_client_.SetTimeout(seconds);
}
// NOTE:
// The return value of the following methods (Get, Post, etc.) only indicates
// if the socket communication is successful or not. Check error() and
// timed_out() for more information if it's failed. Check response_status()
// instead for the HTTP status code.
inline bool Get(const std::string& url) {
return Request(kHttpGet, url, "");
}
inline bool Post(const std::string& url, std::string&& content) {
return Request(kHttpPost, url, std::move(content));
}
inline bool Put(const std::string& url, std::string&& content) {
return Request(kHttpPut, url, std::move(content));
}
inline bool Patch(const std::string& url, std::string&& content) {
return Request(kHttpPatch, url, std::move(content));
}
inline bool Delete(const std::string& url) {
return Request(kHttpDelete, url, "");
}
HttpResponsePtr response() const {
return http_client_.response();
}
int response_status() const {
assert(response());
return response()->status();
}
const std::string& response_content() const {
assert(response());
return response()->content();
}
bool timed_out() const {
return http_client_.timed_out();
}
Error error() const {
return http_client_.error();
}
private:
bool Request(const std::string& method, const std::string& url,
std::string&& content);
std::string host_;
std::string port_;
HttpClient http_client_;
};
} // namespace webcc } // namespace webcc

@ -0,0 +1,39 @@
#include "webcc/rest_ssl_client.h"
namespace webcc {
RestSslClient::RestSslClient(const std::string& host, const std::string& port,
bool ssl_verify)
: host_(host), port_(port), http_client_(ssl_verify) {
if (port_.empty()) {
std::size_t i = host_.find_last_of(':');
if (i != std::string::npos) {
port_ = host_.substr(i + 1);
host_ = host_.substr(0, i);
}
}
}
bool RestSslClient::Request(const std::string& method, const std::string& url,
std::string&& content) {
HttpRequest http_request;
http_request.set_method(method);
http_request.set_url(url);
http_request.set_host(host_, port_);
if (!content.empty()) {
http_request.SetContent(std::move(content), true);
http_request.SetContentType(kAppJsonUtf8);
}
http_request.Make();
if (!http_client_.Request(http_request)) {
return false;
}
return true;
}
} // namespace webcc

@ -1,12 +1,91 @@
#ifndef WEBCC_REST_SSL_CLIENT_H_ #ifndef WEBCC_REST_SSL_CLIENT_H_
#define WEBCC_REST_SSL_CLIENT_H_ #define WEBCC_REST_SSL_CLIENT_H_
#include "webcc/rest_basic_client.h" #include <cassert>
#include <string>
#include <utility> // for move()
#include "webcc/globals.h"
#include "webcc/http_request.h"
#include "webcc/http_response.h"
#include "webcc/http_ssl_client.h" #include "webcc/http_ssl_client.h"
namespace webcc { namespace webcc {
typedef RestBasicClient<HttpSslClient> RestSslClient; class RestSslClient {
public:
// If |port| is empty, |host| will be checked to see if it contains port or
// not (separated by ':').
explicit RestSslClient(const std::string& host,
const std::string& port = "",
bool ssl_verify = true);
~RestSslClient() = default;
WEBCC_DELETE_COPY_ASSIGN(RestSslClient);
void SetTimeout(int seconds) {
http_client_.SetTimeout(seconds);
}
// NOTE:
// The return value of the following methods (Get, Post, etc.) only indicates
// if the socket communication is successful or not. Check error() and
// timed_out() for more information if it's failed. Check response_status()
// instead for the HTTP status code.
inline bool Get(const std::string& url) {
return Request(kHttpGet, url, "");
}
inline bool Post(const std::string& url, std::string&& content) {
return Request(kHttpPost, url, std::move(content));
}
inline bool Put(const std::string& url, std::string&& content) {
return Request(kHttpPut, url, std::move(content));
}
inline bool Patch(const std::string& url, std::string&& content) {
return Request(kHttpPatch, url, std::move(content));
}
inline bool Delete(const std::string& url) {
return Request(kHttpDelete, url, "");
}
HttpResponsePtr response() const {
return http_client_.response();
}
int response_status() const {
assert(response());
return response()->status();
}
const std::string& response_content() const {
assert(response());
return response()->content();
}
bool timed_out() const {
return http_client_.timed_out();
}
Error error() const {
return http_client_.error();
}
private:
bool Request(const std::string& method,
const std::string& url,
std::string&& content);
std::string host_;
std::string port_;
HttpSslClient http_client_;
};
} // namespace webcc } // namespace webcc

Loading…
Cancel
Save