Handle both HTTP & HTTPS in HttpClientSession; remove macro WEBCC_ENABLE_SSL.
This commit is contained in:
+21
-15
@@ -10,7 +10,6 @@ project(webcc)
|
|||||||
|
|
||||||
option(WEBCC_ENABLE_REST "Enable REST support?" ON)
|
option(WEBCC_ENABLE_REST "Enable REST support?" ON)
|
||||||
option(WEBCC_ENABLE_SOAP "Enable SOAP support (need pugixml)?" ON)
|
option(WEBCC_ENABLE_SOAP "Enable SOAP support (need pugixml)?" ON)
|
||||||
option(WEBCC_ENABLE_SSL "Enable SSL/HTTPS support (need OpenSSL)?" OFF)
|
|
||||||
option(WEBCC_ENABLE_UNITTEST "Build unit test?" ON)
|
option(WEBCC_ENABLE_UNITTEST "Build unit test?" ON)
|
||||||
option(WEBCC_ENABLE_EXAMPLES "Build examples?" ON)
|
option(WEBCC_ENABLE_EXAMPLES "Build examples?" ON)
|
||||||
|
|
||||||
@@ -85,14 +84,12 @@ if(Boost_FOUND)
|
|||||||
message(STATUS ${Boost_LIBRARIES})
|
message(STATUS ${Boost_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBCC_ENABLE_SSL)
|
set(OPENSSL_USE_STATIC_LIBS ON)
|
||||||
set(OPENSSL_USE_STATIC_LIBS ON)
|
set(OPENSSL_MSVC_STATIC_RT ON)
|
||||||
set(OPENSSL_MSVC_STATIC_RT ON)
|
find_package(OpenSSL)
|
||||||
find_package(OpenSSL)
|
if(OPENSSL_FOUND)
|
||||||
if(OPENSSL_FOUND)
|
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
message(STATUS "OpenSSL libs: " ${OPENSSL_LIBRARIES})
|
||||||
message(STATUS "OpenSSL libs: " ${OPENSSL_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
@@ -121,6 +118,17 @@ endif()
|
|||||||
add_subdirectory(webcc)
|
add_subdirectory(webcc)
|
||||||
|
|
||||||
if(WEBCC_ENABLE_EXAMPLES)
|
if(WEBCC_ENABLE_EXAMPLES)
|
||||||
|
# Common libraries to link for examples.
|
||||||
|
set(EXAMPLE_COMMON_LIBS webcc ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES}
|
||||||
|
"${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
if(WIN32)
|
||||||
|
set(EXAMPLE_COMMON_LIBS ${EXAMPLE_COMMON_LIBS} crypt32)
|
||||||
|
endif()
|
||||||
|
if(UNIX)
|
||||||
|
# Add `-ldl` for Linux to avoid "undefined reference to `dlopen'".
|
||||||
|
set(EXAMPLE_COMMON_LIBS ${EXAMPLE_COMMON_LIBS} ${CMAKE_DL_LIBS})
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(example/http_client)
|
add_subdirectory(example/http_client)
|
||||||
# add_subdirectory(example/http_async_client)
|
# add_subdirectory(example/http_async_client)
|
||||||
|
|
||||||
@@ -143,13 +151,11 @@ if(WEBCC_ENABLE_EXAMPLES)
|
|||||||
add_subdirectory(example/soap_book_client)
|
add_subdirectory(example/soap_book_client)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBCC_ENABLE_SSL)
|
add_subdirectory(example/http_ssl_client)
|
||||||
add_subdirectory(example/http_ssl_client)
|
# add_subdirectory(example/http_ssl_async_client)
|
||||||
# add_subdirectory(example/http_ssl_async_client)
|
|
||||||
|
|
||||||
if(WEBCC_ENABLE_REST)
|
if(WEBCC_ENABLE_REST)
|
||||||
# add_subdirectory(example/github_rest_client)
|
# add_subdirectory(example/github_rest_client)
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,2 @@
|
|||||||
set(LIBS webcc jsoncpp ${Boost_LIBRARIES} "${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
|
|
||||||
set(LIBS ${LIBS} ${OPENSSL_LIBRARIES})
|
|
||||||
if(WIN32)
|
|
||||||
set(LIBS ${LIBS} crypt32)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(UNIX)
|
|
||||||
# Add `-ldl` for Linux to avoid "undefined reference to `dlopen'".
|
|
||||||
set(LIBS ${LIBS} ${CMAKE_DL_LIBS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(github_rest_client main.cc)
|
add_executable(github_rest_client main.cc)
|
||||||
|
target_link_libraries(github_rest_client ${EXAMPLE_COMMON_LIBS} jsoncpp)
|
||||||
target_link_libraries(github_rest_client ${LIBS})
|
|
||||||
|
|||||||
@@ -1,4 +1,2 @@
|
|||||||
add_executable(http_client main.cc)
|
add_executable(http_client main.cc)
|
||||||
|
target_link_libraries(http_client ${EXAMPLE_COMMON_LIBS})
|
||||||
target_link_libraries(http_client webcc ${Boost_LIBRARIES})
|
|
||||||
target_link_libraries(http_client "${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
|
|||||||
+29
-18
@@ -1,6 +1,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "webcc/http_client_session.h" // TEST
|
#include "webcc/http_client_session.h"
|
||||||
#include "webcc/logger.h"
|
#include "webcc/logger.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
@@ -12,38 +12,49 @@ int main() {
|
|||||||
|
|
||||||
HttpClientSession session;
|
HttpClientSession session;
|
||||||
|
|
||||||
#if 0
|
// ---------------------------------------------------------------------------
|
||||||
r = session.Request(HttpRequestArgs("GET")
|
|
||||||
.url("http://httpbin.org/get") // Moved
|
r = session.Request(HttpRequestArgs{ "GET" }.
|
||||||
.parameters({ "key1", "value1", "key2", "value2" }) // Moved
|
url("http://httpbin.org/get"). // moved
|
||||||
.headers({ "Accept", "application/json" }) // Moved
|
parameters({ "key1", "value1", "key2", "value2" }). // moved
|
||||||
.buffer_size(1000));
|
headers({ "Accept", "application/json" }). // moved
|
||||||
|
buffer_size(1000));
|
||||||
|
|
||||||
std::cout << r->content() << std::endl;
|
std::cout << r->content() << std::endl;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// If you want to create the args object firstly, there'll be an extra call
|
// If you want to create the args object firstly, there'll be an extra call
|
||||||
// to its move constructor.
|
// to its move constructor.
|
||||||
// - constructor: HttpRequestArgs("GET")
|
// - constructor: HttpRequestArgs{ "GET" }
|
||||||
// - move constructor: auto args = ...
|
// - move constructor: auto args = ...
|
||||||
auto args = HttpRequestArgs("GET")
|
|
||||||
.url("http://httpbin.org/get")
|
auto args = HttpRequestArgs{"GET"}.
|
||||||
.parameters({ "key1", "value1", "key2", "value2" })
|
url("http://httpbin.org/get").
|
||||||
.headers({ "Accept", "application/json" })
|
parameters({ "key1", "value1", "key2", "value2" }).
|
||||||
.buffer_size(1000);
|
headers({ "Accept", "application/json" }).
|
||||||
|
buffer_size(1000);
|
||||||
|
|
||||||
r = session.Request(std::move(args));
|
r = session.Request(std::move(args));
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Use pre-defined wrappers.
|
||||||
|
|
||||||
r = session.Get("http://httpbin.org/get",
|
r = session.Get("http://httpbin.org/get",
|
||||||
{ "key1", "value1", "key2", "value2" },
|
{ "key1", "value1", "key2", "value2" },
|
||||||
{ "Accept", "application/json" },
|
{ "Accept", "application/json" },
|
||||||
HttpRequestArgs().buffer_size(1000));
|
HttpRequestArgs{}.buffer_size(1000));
|
||||||
#endif
|
|
||||||
|
|
||||||
r = session.Post("http://httpbin.org/post", "{ 'key': 'value' }", true,
|
// ---------------------------------------------------------------------------
|
||||||
|
// HTTPS is auto-detected from the URL schema.
|
||||||
|
|
||||||
|
r = session.Post("https://httpbin.org/post", "{ 'key': 'value' }", true,
|
||||||
{ "Accept", "application/json" },
|
{ "Accept", "application/json" },
|
||||||
HttpRequestArgs().buffer_size(1000));
|
HttpRequestArgs{}.ssl_verify(false).buffer_size(1000));
|
||||||
|
|
||||||
std::cout << r->content() << std::endl;
|
if (r) {
|
||||||
|
std::cout << r->content() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,2 @@
|
|||||||
add_executable(http_ssl_client main.cc)
|
add_executable(http_ssl_client main.cc)
|
||||||
|
target_link_libraries(http_ssl_client ${EXAMPLE_COMMON_LIBS})
|
||||||
set(SSL_LIBS ${OPENSSL_LIBRARIES})
|
|
||||||
if(WIN32)
|
|
||||||
set(SSL_LIBS ${SSL_LIBS} crypt32)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_link_libraries(http_ssl_client webcc ${Boost_LIBRARIES})
|
|
||||||
target_link_libraries(http_ssl_client "${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
target_link_libraries(http_ssl_client ${SSL_LIBS})
|
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "webcc/url.h"
|
||||||
|
|
||||||
|
TEST(Url, Basic) {
|
||||||
|
webcc::Url url("http://example.com/path", false);
|
||||||
|
|
||||||
|
EXPECT_EQ("http", url.scheme());
|
||||||
|
EXPECT_EQ("example.com", url.host());
|
||||||
|
EXPECT_EQ("", url.port());
|
||||||
|
EXPECT_EQ("path", url.path());
|
||||||
|
EXPECT_EQ("", url.query());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Url, NoPath) {
|
||||||
|
webcc::Url url("http://example.com", false);
|
||||||
|
|
||||||
|
EXPECT_EQ("http", url.scheme());
|
||||||
|
EXPECT_EQ("example.com", url.host());
|
||||||
|
EXPECT_EQ("", url.port());
|
||||||
|
EXPECT_EQ("", url.path());
|
||||||
|
EXPECT_EQ("", url.query());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Url, NoPath2) {
|
||||||
|
webcc::Url url("http://example.com/", false);
|
||||||
|
|
||||||
|
EXPECT_EQ("http", url.scheme());
|
||||||
|
EXPECT_EQ("example.com", url.host());
|
||||||
|
EXPECT_EQ("", url.port());
|
||||||
|
EXPECT_EQ("", url.path());
|
||||||
|
EXPECT_EQ("", url.query());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Url, NoPath3) {
|
||||||
|
webcc::Url url("http://example.com?key=value", false);
|
||||||
|
|
||||||
|
EXPECT_EQ("http", url.scheme());
|
||||||
|
EXPECT_EQ("example.com", url.host());
|
||||||
|
EXPECT_EQ("", url.port());
|
||||||
|
EXPECT_EQ("", url.path());
|
||||||
|
EXPECT_EQ("key=value", url.query());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Url, NoPath4) {
|
||||||
|
webcc::Url url("http://example.com/?key=value", false);
|
||||||
|
|
||||||
|
EXPECT_EQ("http", url.scheme());
|
||||||
|
EXPECT_EQ("example.com", url.host());
|
||||||
|
EXPECT_EQ("", url.port());
|
||||||
|
EXPECT_EQ("", url.path());
|
||||||
|
EXPECT_EQ("key=value", url.query());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Url, NoScheme) {
|
||||||
|
webcc::Url url("/path/to", false);
|
||||||
|
|
||||||
|
EXPECT_EQ("", url.scheme());
|
||||||
|
EXPECT_EQ("", url.host());
|
||||||
|
EXPECT_EQ("", url.port());
|
||||||
|
EXPECT_EQ("path/to", url.path());
|
||||||
|
EXPECT_EQ("", url.query());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Url, NoScheme2) {
|
||||||
|
webcc::Url url("/path/to?key=value", false);
|
||||||
|
|
||||||
|
EXPECT_EQ("", url.scheme());
|
||||||
|
EXPECT_EQ("", url.host());
|
||||||
|
EXPECT_EQ("", url.port());
|
||||||
|
EXPECT_EQ("path/to", url.path());
|
||||||
|
EXPECT_EQ("key=value", url.query());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Url, Full) {
|
||||||
|
webcc::Url url("https://localhost:3000/path/to?key=value", false);
|
||||||
|
|
||||||
|
EXPECT_EQ("https", url.scheme());
|
||||||
|
EXPECT_EQ("localhost", url.host());
|
||||||
|
EXPECT_EQ("3000", url.port());
|
||||||
|
EXPECT_EQ("path/to", url.path());
|
||||||
|
EXPECT_EQ("key=value", url.query());
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ set(HEADERS
|
|||||||
http_response.h
|
http_response.h
|
||||||
http_response_parser.h
|
http_response_parser.h
|
||||||
http_server.h
|
http_server.h
|
||||||
|
http_ssl_client.h
|
||||||
# http_ssl_async_client.h
|
# http_ssl_async_client.h
|
||||||
queue.h
|
queue.h
|
||||||
url.h
|
url.h
|
||||||
@@ -53,6 +54,7 @@ set(SOURCES
|
|||||||
http_response.cc
|
http_response.cc
|
||||||
http_response_parser.cc
|
http_response_parser.cc
|
||||||
http_server.cc
|
http_server.cc
|
||||||
|
http_ssl_client.cc
|
||||||
# http_ssl_async_client.cc
|
# http_ssl_async_client.cc
|
||||||
logger.cc
|
logger.cc
|
||||||
url.cc
|
url.cc
|
||||||
@@ -61,7 +63,7 @@ set(SOURCES
|
|||||||
|
|
||||||
if(WEBCC_ENABLE_REST)
|
if(WEBCC_ENABLE_REST)
|
||||||
set(REST_HEADERS
|
set(REST_HEADERS
|
||||||
# rest_async_client.h
|
# rest_async_client.h
|
||||||
# rest_client.h
|
# rest_client.h
|
||||||
rest_request_handler.h
|
rest_request_handler.h
|
||||||
rest_server.h
|
rest_server.h
|
||||||
@@ -80,11 +82,6 @@ if(WEBCC_ENABLE_REST)
|
|||||||
set(SOURCES ${SOURCES} ${REST_SOURCES})
|
set(SOURCES ${SOURCES} ${REST_SOURCES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBCC_ENABLE_SSL)
|
|
||||||
set(HEADERS ${HEADERS} http_ssl_client.h)
|
|
||||||
set(SOURCES ${SOURCES} http_ssl_client.cc)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WEBCC_ENABLE_SOAP)
|
if(WEBCC_ENABLE_SOAP)
|
||||||
set(SOAP_HEADERS
|
set(SOAP_HEADERS
|
||||||
# soap_async_client.h
|
# soap_async_client.h
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "webcc/http_client_session.h"
|
#include "webcc/http_client_session.h"
|
||||||
|
|
||||||
#include "webcc/http_client.h"
|
#include "webcc/http_client.h"
|
||||||
#include "webcc/http_request.h"
|
#include "webcc/http_ssl_client.h"
|
||||||
#include "webcc/url.h"
|
#include "webcc/url.h"
|
||||||
|
|
||||||
namespace webcc {
|
namespace webcc {
|
||||||
@@ -14,7 +14,7 @@ HttpResponsePtr HttpClientSession::Request(HttpRequestArgs&& args) {
|
|||||||
assert(args.parameters_.size() % 2 == 0);
|
assert(args.parameters_.size() % 2 == 0);
|
||||||
assert(args.headers_.size() % 2 == 0);
|
assert(args.headers_.size() % 2 == 0);
|
||||||
|
|
||||||
HttpRequest request(args.method_, args.url_, args.parameters_);
|
HttpRequest request{ args.method_, args.url_, args.parameters_ };
|
||||||
|
|
||||||
if (!args.data_.empty()) {
|
if (!args.data_.empty()) {
|
||||||
request.SetContent(std::move(args.data_), true);
|
request.SetContent(std::move(args.data_), true);
|
||||||
@@ -39,12 +39,26 @@ HttpResponsePtr HttpClientSession::Request(HttpRequestArgs&& args) {
|
|||||||
|
|
||||||
request.Prepare();
|
request.Prepare();
|
||||||
|
|
||||||
HttpClient client;
|
// TODO:
|
||||||
if (!client.Request(request, args.buffer_size_)) {
|
|
||||||
|
std::shared_ptr<HttpClientBase> impl;
|
||||||
|
|
||||||
|
if (request.url().scheme() == "http") {
|
||||||
|
impl.reset(new HttpClient);
|
||||||
|
} else if (request.url().scheme() == "https") {
|
||||||
|
impl.reset(new HttpSslClient{args.ssl_verify_});
|
||||||
|
} else {
|
||||||
return HttpResponsePtr{};
|
return HttpResponsePtr{};
|
||||||
}
|
}
|
||||||
|
|
||||||
return client.response();
|
if (impl) {
|
||||||
|
if (!impl->Request(request, args.buffer_size_)) {
|
||||||
|
return HttpResponsePtr{};
|
||||||
|
}
|
||||||
|
return impl->response();
|
||||||
|
}
|
||||||
|
|
||||||
|
return HttpResponsePtr{};
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponsePtr HttpClientSession::Get(const std::string& url,
|
HttpResponsePtr HttpClientSession::Get(const std::string& url,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class HttpClientSession;
|
|||||||
class HttpRequestArgs {
|
class HttpRequestArgs {
|
||||||
public:
|
public:
|
||||||
explicit HttpRequestArgs(const std::string& method = "")
|
explicit HttpRequestArgs(const std::string& method = "")
|
||||||
: method_(method), json_(false), buffer_size_(0) {
|
: method_(method), json_(false), ssl_verify_(true), buffer_size_(0) {
|
||||||
LOG_VERB("HttpRequestArgs()");
|
LOG_VERB("HttpRequestArgs()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@ public:
|
|||||||
data_(std::move(rhs.data_)),
|
data_(std::move(rhs.data_)),
|
||||||
json_(rhs.json_),
|
json_(rhs.json_),
|
||||||
headers_(std::move(rhs.headers_)),
|
headers_(std::move(rhs.headers_)),
|
||||||
|
ssl_verify_(rhs.ssl_verify_),
|
||||||
buffer_size_(rhs.buffer_size_) {
|
buffer_size_(rhs.buffer_size_) {
|
||||||
LOG_VERB("HttpRequestArgs(&&)");
|
LOG_VERB("HttpRequestArgs(&&)");
|
||||||
}
|
}
|
||||||
@@ -50,6 +51,7 @@ public:
|
|||||||
data_ = std::move(rhs.data_);
|
data_ = std::move(rhs.data_);
|
||||||
json_ = rhs.json_;
|
json_ = rhs.json_;
|
||||||
headers_ = std::move(rhs.headers_);
|
headers_ = std::move(rhs.headers_);
|
||||||
|
ssl_verify_ = rhs.ssl_verify_;
|
||||||
buffer_size_ = buffer_size_;
|
buffer_size_ = buffer_size_;
|
||||||
}
|
}
|
||||||
LOG_VERB("HttpRequestArgs& operator=(&&)");
|
LOG_VERB("HttpRequestArgs& operator=(&&)");
|
||||||
@@ -108,6 +110,11 @@ public:
|
|||||||
return std::move(*this);
|
return std::move(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HttpRequestArgs&& ssl_verify(bool ssl_verify = true) {
|
||||||
|
ssl_verify_ = ssl_verify;
|
||||||
|
return std::move(*this);
|
||||||
|
}
|
||||||
|
|
||||||
HttpRequestArgs&& buffer_size(std::size_t buffer_size) {
|
HttpRequestArgs&& buffer_size(std::size_t buffer_size) {
|
||||||
buffer_size_ = buffer_size;
|
buffer_size_ = buffer_size;
|
||||||
return std::move(*this);
|
return std::move(*this);
|
||||||
@@ -130,6 +137,10 @@ private:
|
|||||||
|
|
||||||
std::vector<std::string> headers_;
|
std::vector<std::string> headers_;
|
||||||
|
|
||||||
|
// Verify the certificate of the peer (remote server) or not.
|
||||||
|
// HTTPS only.
|
||||||
|
bool ssl_verify_;
|
||||||
|
|
||||||
// Size of the buffer to read response.
|
// Size of the buffer to read response.
|
||||||
// Leave it to 0 for using default value.
|
// Leave it to 0 for using default value.
|
||||||
std::size_t buffer_size_;
|
std::size_t buffer_size_;
|
||||||
|
|||||||
Reference in New Issue
Block a user