diff --git a/CMakeLists.txt b/CMakeLists.txt index 2051ace7..b0a9617c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,15 @@ else (UNIX) SET(DEPENDENT_LIBRARIES event glog) endif (UNIX) +# Set to true if https support is needed. +# Note that this needs openssl +# SET(HTTPS True) +if (HTTPS) + list(APPEND DEPENDENT_LIBRARIES ssl crypto event_openssl) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEVPP_HTTP_CLIENT_SUPPORTS_SSL") +endif (HTTPS) + + if (CMAKE_BENCHMARK_TESTING) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DH_BENCHMARK_TESTING=1") endif (CMAKE_BENCHMARK_TESTING) diff --git a/evpp/CMakeLists.txt b/evpp/CMakeLists.txt index b2e470de..6c84f3e4 100644 --- a/evpp/CMakeLists.txt +++ b/evpp/CMakeLists.txt @@ -16,6 +16,12 @@ include_directories(${PROJECT_SOURCE_DIR}) add_library(evpp_static STATIC ${evpp_SRCS}) target_link_libraries(evpp_static ${DEPENDENT_LIBRARIES}) +if (HTTPS) +add_library(evpp_https_static STATIC ${evpp_SRCS}) +target_compile_definitions(evpp_https_static PRIVATE -DEVPP_HTTP_CLIENT_SUPPORTS_SSL) +target_link_libraries(evpp_https_static ${DEPENDENT_LIBRARIES}) +endif (HTTPS) + add_library(evpp_lite_static STATIC ${evpp_lite_SRCS}) target_link_libraries(evpp_lite_static ${DEPENDENT_LIBRARIES}) diff --git a/evpp/httpc/conn.cc b/evpp/httpc/conn.cc index 433cd428..401991f7 100644 --- a/evpp/httpc/conn.cc +++ b/evpp/httpc/conn.cc @@ -4,6 +4,7 @@ #if defined(EVPP_HTTP_CLIENT_SUPPORTS_SSL) #include "evpp/httpc/ssl.h" #include +#include #endif #include "evpp/libevent.h" diff --git a/evpp/httpc/request.cc b/evpp/httpc/request.cc index f9419233..ad25a54d 100644 --- a/evpp/httpc/request.cc +++ b/evpp/httpc/request.cc @@ -1,10 +1,13 @@ - #include "evpp/libevent.h" #include "evpp/httpc/conn_pool.h" #include "evpp/httpc/response.h" #include "evpp/httpc/request.h" #include "evpp/httpc/url_parser.h" +#if defined(EVPP_HTTP_CLIENT_SUPPORTS_SSL) +#include +#endif + namespace evpp { namespace httpc { const std::string Request::empty_ = ""; @@ -195,9 +198,7 @@ void Request::HandleResponse(struct evhttp_request* r) { } #if defined(EVPP_HTTP_CLIENT_SUPPORTS_SSL) - bool had_ssl_error = false; if (!r) { - had_ssl_error = true; int errcode = EVUTIL_SOCKET_ERROR(); unsigned long oslerr; bool printed_some_error = false; diff --git a/evpp/httpc/request.h b/evpp/httpc/request.h index e54fc426..315f2a1a 100644 --- a/evpp/httpc/request.h +++ b/evpp/httpc/request.h @@ -45,7 +45,7 @@ class EVPP_EXPORT Request { const std::string& host() const { return host_; } - const int port() const { + int port() const { return port_; } void set_retry_number(int v) { @@ -75,7 +75,7 @@ class EVPP_EXPORT Request { // The retried times int retried_ = 0; - + // The max retry times. Set to 0 if you don't want to retry when failed. // The total execution times is retry_number_+1 int retry_number_ = 2; diff --git a/evpp/httpc/ssl.cc b/evpp/httpc/ssl.cc index d315a78b..aba76983 100644 --- a/evpp/httpc/ssl.cc +++ b/evpp/httpc/ssl.cc @@ -4,6 +4,7 @@ #include "evpp/logging.h" #include +#include namespace evpp { namespace httpc { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e6d74c5f..15fd1d7b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,10 @@ file(GLOB evpp_unittest_SRCS *.cc ${PROJECT_SOURCE_DIR}/3rdparty/gtest/src/gtest-all.cc ${PROJECT_SOURCE_DIR}/3rdparty/gtest/src/gtest_main.cc) +list(REMOVE_ITEM evpp_unittest_SRCS ${PROJECT_SOURCE_DIR}/test/https_client_test.cc) +file(GLOB evpp_https_unittest_SRCS https_client_test.cc + ${PROJECT_SOURCE_DIR}/3rdparty/gtest/src/gtest-all.cc + ${PROJECT_SOURCE_DIR}/3rdparty/gtest/src/gtest_main.cc) include_directories(${PROJECT_SOURCE_DIR}/3rdparty ${PROJECT_SOURCE_DIR}/3rdparty/gtest) if (MSVC) @@ -10,6 +14,11 @@ endif (MSVC) add_executable(evpp_unittest ${evpp_unittest_SRCS}) target_link_libraries(evpp_unittest evpp_static ${DEPENDENT_LIBRARIES}) +if (HTTPS) +add_executable(evpp_https_unittest ${evpp_https_unittest_SRCS}) +target_link_libraries(evpp_https_unittest evpp_https_static ${DEPENDENT_LIBRARIES}) +endif (HTTPS) + if (UNIX) add_executable(evpp_unittest_boost_lockfree ${evpp_unittest_SRCS}) target_link_libraries(evpp_unittest_boost_lockfree evpp_boost ${DEPENDENT_LIBRARIES}) diff --git a/test/evhttp_client_test.cc b/test/evhttp_client_test.cc index 2f310f60..a87cecc6 100644 --- a/test/evhttp_client_test.cc +++ b/test/evhttp_client_test.cc @@ -162,4 +162,4 @@ TEST_UNIT(testHTTPRequest5) { H_TEST_ASSERT(hc::retried == 3); t.Stop(true); LOG_INFO << "EventLoopThread stopped."; -} \ No newline at end of file +} diff --git a/test/https_client_test.cc b/test/https_client_test.cc new file mode 100644 index 00000000..da6ccad8 --- /dev/null +++ b/test/https_client_test.cc @@ -0,0 +1,68 @@ +#include +#include +#include + +#include "test_common.h" + +#include +#include +#include +#include +#include + +namespace { +void InitSSLOnce() { + static std::once_flag flag; + std::call_once(flag, [](){ evpp::httpc::InitSSL(); }); +} + +std::string HttpFetch(const std::string& url) { + InitSSLOnce(); + evpp::EventLoopThread t; + t.Start(true); + evpp::httpc::GetRequest* req = + new evpp::httpc::GetRequest(t.loop(), url, evpp::Duration(1.0)); + volatile bool responsed = false; + std::string ret; + req->Execute([req, &ret, &responsed]( + const std::shared_ptr& response) mutable { + std::stringstream oss; + oss << "http_code=" + << response->http_code() + << std::endl + << "body [" + << std::endl + << response->body().ToString() + << "]" + << std::endl; + responsed = true; + delete req; + ret = oss.str(); + }); + while (!responsed) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + t.Stop(true); + return ret; +} +} + +TEST_UNIT(testHTTPResponse) { + std::string response = HttpFetch("http://httpbin.org/headers?show_env=1"); + H_TEST_ASSERT(!response.empty()); + H_TEST_ASSERT(response.find("http_code=200") != std::string::npos); + H_TEST_ASSERT(response.find("\"Host\": \"httpbin.org\",") != std::string::npos); + H_TEST_ASSERT(response.find("\"X-Forwarded-Port\": \"80\",") != std::string::npos); + H_TEST_ASSERT(response.find("\"X-Forwarded-Proto\": \"http\",") != std::string::npos); + H_TEST_ASSERT(response.find("\"Connection\": \"close\",") != std::string::npos); +} + +TEST_UNIT(testHTTPSResponse) { + std::string response = HttpFetch("https://httpbin.org/headers?show_env=1"); + H_TEST_ASSERT(!response.empty()); + H_TEST_ASSERT(response.find("http_code=200") != std::string::npos); + H_TEST_ASSERT(response.find("\"Host\": \"httpbin.org\",") != std::string::npos); + H_TEST_ASSERT(response.find("\"X-Forwarded-Port\": \"443\",") != std::string::npos); + H_TEST_ASSERT(response.find("\"X-Forwarded-Proto\": \"https\",") != std::string::npos); + H_TEST_ASSERT(response.find("\"Connection\": \"close\",") != std::string::npos); +}