Forbit to create http async clients on stack since they are derived from std::shared_from_this.

master
Chunting Gu 6 years ago
parent 43eaf90621
commit d42556ce5a

@ -2,22 +2,21 @@
#include "json/json.h" #include "json/json.h"
#include "webcc/rest_ssl_client.h"
#include "webcc/logger.h" #include "webcc/logger.h"
#include "webcc/rest_ssl_client.h"
const bool kSslVerify = false; const bool kSslVerify = false;
#define PRINT_CONTENT 0 #define PRINT_CONTENT 0
static Json::Value StringToJson(const std::string& str) { static Json::Value StringToJson(const std::string& str) {
Json::Value json; Json::Value json;
Json::CharReaderBuilder builder; Json::CharReaderBuilder builder;
std::stringstream stream(str); std::stringstream stream(str);
std::string errs; std::string errors;
if (!Json::parseFromStream(builder, stream, &json, &errs)) { if (!Json::parseFromStream(builder, stream, &json, &errors)) {
std::cerr << errs << std::endl; std::cerr << errors << std::endl;
} }
return json; return json;

@ -9,12 +9,10 @@
// Only HttpBin.org has this issue. // Only HttpBin.org has this issue.
static void Test(boost::asio::io_context& io_context) { static void Test(boost::asio::io_context& io_context) {
auto request = webcc::HttpRequest::Make(webcc::kHttpGet, "/get", auto request = webcc::HttpRequest::New(webcc::kHttpGet, "/get",
"httpbin.org"); "httpbin.org");
webcc::HttpAsyncClientPtr client{ auto client = webcc::HttpAsyncClient::New(io_context);
new webcc::HttpAsyncClient(io_context)
};
client->SetTimeout(3); client->SetTimeout(3);

@ -14,8 +14,8 @@ static void PrintError(const webcc::HttpClient& client) {
int main() { int main() {
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE); WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);
auto request = webcc::HttpRequest::Make(webcc::kHttpGet, "/get", auto request = webcc::HttpRequest::New(webcc::kHttpGet, "/get",
"httpbin.org"); "httpbin.org");
webcc::HttpClient client; webcc::HttpClient client;

@ -26,15 +26,13 @@ int main(int argc, char* argv[]) {
boost::asio::io_context io_context; boost::asio::io_context io_context;
// Leave port to default value. // Leave port to default value.
auto request = webcc::HttpRequest::Make(webcc::kHttpGet, url, host); auto request = webcc::HttpRequest::New(webcc::kHttpGet, url, host);
// 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;
webcc::HttpSslAsyncClientPtr client{ auto client = webcc::HttpSslAsyncClient::New(io_context, 2000, ssl_verify);
new webcc::HttpSslAsyncClient{ io_context, 2000, ssl_verify }
};
// Response callback. // Response callback.
auto callback = [](webcc::HttpResponsePtr response, webcc::Error error, auto callback = [](webcc::HttpResponsePtr response, webcc::Error error,

@ -5,15 +5,27 @@
namespace webcc { namespace webcc {
class HttpAsyncClient;
typedef std::shared_ptr<HttpAsyncClient> HttpAsyncClientPtr;
// HTTP asynchronous client. // HTTP asynchronous client.
class HttpAsyncClient : public HttpAsyncClientBase { class HttpAsyncClient : public HttpAsyncClientBase {
public: public:
explicit HttpAsyncClient(boost::asio::io_context& io_context,
std::size_t buffer_size = 0);
~HttpAsyncClient() = default; ~HttpAsyncClient() = default;
// Forbid to create HttpAsyncClient in stack since it's derived from
// std::shared_from_this.
static HttpAsyncClientPtr New(boost::asio::io_context& io_context,
std::size_t buffer_size = 0) {
return HttpAsyncClientPtr{
new HttpAsyncClient(io_context, buffer_size)
};
}
private: private:
explicit HttpAsyncClient(boost::asio::io_context& io_context,
std::size_t buffer_size = 0);
void Resolve() final { void Resolve() final {
DoResolve(kHttpPort); DoResolve(kHttpPort);
} }
@ -34,8 +46,6 @@ class HttpAsyncClient : public HttpAsyncClientBase {
tcp::socket socket_; tcp::socket socket_;
}; };
typedef std::shared_ptr<HttpAsyncClient> HttpAsyncClientPtr;
} // namespace webcc } // namespace webcc
#endif // WEBCC_HTTP_ASYNC_CLIENT_H_ #endif // WEBCC_HTTP_ASYNC_CLIENT_H_

@ -33,11 +33,11 @@ void HttpRequest::Prepare() {
} }
// static // static
HttpRequestPtr HttpRequest::Make(const std::string& method, HttpRequestPtr HttpRequest::New(const std::string& method,
const std::string& url, const std::string& url,
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
bool prepare) { bool prepare) {
HttpRequestPtr request{ HttpRequestPtr request{
new HttpRequest{ method, url, host, port } new HttpRequest{ method, url, host, port }
}; };

@ -43,11 +43,11 @@ class HttpRequest : public HttpMessage {
// Compose start line, set Host header, etc. // Compose start line, set Host header, etc.
void Prepare() override; void Prepare() override;
static HttpRequestPtr Make(const std::string& method, static HttpRequestPtr New(const std::string& method,
const std::string& url, const std::string& url,
const std::string& host, const std::string& host,
const std::string& port = "", const std::string& port = "",
bool prepare = true); bool prepare = true);
private: private:
friend class HttpRequestParser; friend class HttpRequestParser;

@ -7,24 +7,37 @@
namespace webcc { namespace webcc {
class HttpSslAsyncClient;
typedef std::shared_ptr<HttpSslAsyncClient> HttpSslAsyncClientPtr;
// HTTP SSL (a.k.a., HTTPS) asynchronous client. // HTTP SSL (a.k.a., HTTPS) asynchronous client.
class HttpSslAsyncClient : public HttpAsyncClientBase { class HttpSslAsyncClient : public HttpAsyncClientBase {
public: public:
// SSL verification (|ssl_verify|) 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.
explicit HttpSslAsyncClient(boost::asio::io_context& io_context,
std::size_t buffer_size = 0,
bool ssl_verify = true);
~HttpSslAsyncClient() = default; ~HttpSslAsyncClient() = default;
// Forbid to create HttpSslAsyncClient in stack since it's derived from
// std::shared_from_this.
static HttpSslAsyncClientPtr New(boost::asio::io_context& io_context,
std::size_t buffer_size = 0,
bool ssl_verify = true) {
return HttpSslAsyncClientPtr{
new HttpSslAsyncClient(io_context, buffer_size, ssl_verify)
};
}
// See https://stackoverflow.com/q/657155/6825348 // See https://stackoverflow.com/q/657155/6825348
std::shared_ptr<HttpSslAsyncClient> shared_from_this() { std::shared_ptr<HttpSslAsyncClient> shared_from_this() {
return shared_from_base<HttpSslAsyncClient>(); return shared_from_base<HttpSslAsyncClient>();
} }
private: private:
// SSL verification (|ssl_verify|) 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.
explicit HttpSslAsyncClient(boost::asio::io_context& io_context,
std::size_t buffer_size = 0,
bool ssl_verify = true);
void Resolve() final; void Resolve() final;
// Override to do handshake after connected. // Override to do handshake after connected.
@ -51,8 +64,6 @@ class HttpSslAsyncClient : public HttpAsyncClientBase {
bool ssl_verify_; bool ssl_verify_;
}; };
typedef std::shared_ptr<HttpSslAsyncClient> HttpSslAsyncClientPtr;
} // namespace webcc } // namespace webcc
#endif // WEBCC_HTTP_SSL_ASYNC_CLIENT_H_ #endif // WEBCC_HTTP_SSL_ASYNC_CLIENT_H_

@ -26,9 +26,7 @@ void RestAsyncClient::Request(const std::string& method,
http_request->Prepare(); http_request->Prepare();
HttpAsyncClientPtr http_async_client{ auto http_async_client = HttpAsyncClient::New(io_context_, buffer_size_);
new HttpAsyncClient(io_context_, buffer_size_)
};
if (timeout_seconds_ > 0) { if (timeout_seconds_ > 0) {
http_async_client->SetTimeout(timeout_seconds_); http_async_client->SetTimeout(timeout_seconds_);

@ -65,9 +65,7 @@ void SoapAsyncClient::Request(const std::string& operation,
http_request->SetHeader(kSoapAction, operation); http_request->SetHeader(kSoapAction, operation);
http_request->Prepare(); http_request->Prepare();
HttpAsyncClientPtr http_async_client{ auto http_async_client = HttpAsyncClient::New(io_context_, buffer_size_);
new HttpAsyncClient(io_context_, buffer_size_)
};
if (timeout_seconds_ > 0) { if (timeout_seconds_ > 0) {
http_async_client->SetTimeout(timeout_seconds_); http_async_client->SetTimeout(timeout_seconds_);

Loading…
Cancel
Save