diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cd372a3..bc934fe2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ find_package(PkgConfig REQUIRED) # Options set(PHOTON_CXX_STANDARD "14" CACHE STRING "C++ standard") option(PHOTON_BUILD_TESTING "enable build testing" OFF) +option(PHOTON_BUILD_WITH_ASAN "build with asan" OFF) option(PHOTON_ENABLE_URING "enable io_uring function" OFF) option(PHOTON_ENABLE_FUSE "enable fuse function" OFF) option(PHOTON_ENABLE_SASL "enable sasl" OFF) @@ -57,6 +58,13 @@ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) endif () add_compile_options(${global_compile_options}) +if (PHOTON_BUILD_WITH_ASAN) + if ((NOT CMAKE_BUILD_TYPE STREQUAL "Debug") OR (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")) + message(FATAL_ERROR "Wrong environment") + endif () + add_link_options(-fsanitize=address -static-libasan) +endif () + set(CMAKE_CXX_STANDARD ${PHOTON_CXX_STANDARD}) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -96,12 +104,6 @@ if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif () -# If ccache exists, use it to speed up compiling -find_program(CCACHE_FOUND ccache) -if(CCACHE_FOUND) - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) -endif(CCACHE_FOUND) - # CMake dirs list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/output) diff --git a/net/http/client.h b/net/http/client.h index 22fb0910..0011b1f4 100644 --- a/net/http/client.h +++ b/net/http/client.h @@ -40,6 +40,17 @@ class ICookieJar : public Object { class Client : public Object { public: + class Operation; + Operation* new_operation(Verb v, std::string_view url, uint16_t buf_size = UINT16_MAX) { + return Operation::create(this, v, url, buf_size); + } + Operation* new_operation(uint16_t buf_size = UINT16_MAX) { + return Operation::create(this, buf_size); + } + void destroy_operation(Operation* op) { + op->destroy(); + } + class Operation { public: Request req; // request @@ -68,8 +79,9 @@ class Client : public Object { this->~Operation(); free(this); } - void set_enable_proxy(bool enable) { enable_proxy = enable; } - + void set_enable_proxy(bool enable) { + enable_proxy = enable; + } int call() { if (!_client) return -1; return _client->call(this); @@ -91,24 +103,18 @@ class Client : public Object { : req(_buf, buf_size), enable_proxy(c->has_proxy()), _client(c) {} - Operation(uint16_t buf_size) : req(_buf, buf_size) {} + explicit Operation(uint16_t buf_size) : req(_buf, buf_size), _client(nullptr) {} + Operation() = delete; + ~Operation() = default; }; - Operation* new_operation(Verb v, std::string_view url, uint16_t buf_size = UINT16_MAX) { - return Operation::create(this, v, url, buf_size); - } - - Operation* new_operation(uint16_t buf_size = UINT16_MAX) { - return Operation::create(this, buf_size); - } - template class OperationOnStack : public Operation { char _buf[BufferSize]; public: OperationOnStack(Client* c, Verb v, std::string_view url): Operation(c, v, url, BufferSize) {} - OperationOnStack(Client* c): Operation(c, BufferSize) {}; + explicit OperationOnStack(Client* c): Operation(c, BufferSize) {}; OperationOnStack(): Operation(BufferSize) {} }; diff --git a/net/http/test/client_function_test.cpp b/net/http/test/client_function_test.cpp index d3fd6a57..af20f37a 100644 --- a/net/http/test/client_function_test.cpp +++ b/net/http/test/client_function_test.cpp @@ -98,7 +98,7 @@ TEST(http_client, get) { auto client = new_http_client(); DEFER(delete client); auto op2 = client->new_operation(Verb::GET, target); - DEFER(op2->destroy()); + DEFER(client->destroy_operation(op2)); op2->req.headers.content_length(0); int ret = client->call(op2); GTEST_ASSERT_EQ(0, ret); @@ -112,7 +112,7 @@ TEST(http_client, get) { EXPECT_EQ(0, strcmp(resp_body_buf, socket_buf)); auto op3 = client->new_operation(Verb::GET, target); - DEFER(op3->destroy()); + DEFER(client->destroy_operation(op3)); op3->req.headers.content_length(0); op3->req.headers.range(10, 19); client->call(op3); @@ -123,7 +123,7 @@ TEST(http_client, get) { LOG_DEBUG(resp_body_buf_range); auto op4 = client->new_operation(Verb::GET, target); - DEFER(op4->destroy()); + DEFER(client->destroy_operation(op4)); op4->req.headers.content_length(0); op4->call(); EXPECT_EQ(sizeof(socket_buf), op4->resp.resource_size()); @@ -140,7 +140,7 @@ TEST(http_client, get) { static const char target_tb[] = "http://www.taobao.com?x"; auto op5 = client->new_operation(Verb::GET, target_tb); - DEFER(op5->destroy()); + DEFER(client->destroy_operation(op5)); op5->req.headers.content_length(0); op5->call(); EXPECT_EQ(op5->resp.status_code(), 200); @@ -193,7 +193,7 @@ TEST(http_client, post) { // body stream test auto op1 = client->new_operation(Verb::POST, target); - DEFER(op1->destroy()); + DEFER(client->destroy_operation(op1)); struct stat st; EXPECT_EQ(0, file->fstat(&st)); op1->req.headers.content_length(st.st_size); @@ -207,7 +207,7 @@ TEST(http_client, post) { // body writer test auto op2 = client->new_operation(Verb::POST, target); - DEFER(op2->destroy()); + DEFER(client->destroy_operation(op2)); op2->req.headers.content_length(st.st_size); auto writer = [&](Request *req)-> ssize_t { file->lseek(0, SEEK_SET); @@ -348,7 +348,7 @@ TEST(http_client, chunked) { DEFER(delete client); auto url = to_url(server, "/"); auto op = client->new_operation(Verb::GET, url); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); std::string buf; op->call(); @@ -362,7 +362,7 @@ TEST(http_client, chunked) { server->set_handler({nullptr, &chunked_handler_complict}); auto opc = client->new_operation(Verb::GET, url); - DEFER(opc->destroy()); + DEFER(client->destroy_operation(opc)); opc->call(); EXPECT_EQ(200, opc->status_code); buf.resize(20000); @@ -382,7 +382,7 @@ TEST(http_client, chunked) { server->set_handler({nullptr, &chunked_handler_pt}); for (auto tmp = 0; tmp < 20; tmp++) { auto op_test = client->new_operation(Verb::GET, url); - DEFER(op_test->destroy()); + DEFER(client->destroy_operation(op_test)); op_test->call(); EXPECT_EQ(200, op_test->status_code); buf.resize(std_data_size); @@ -459,7 +459,7 @@ TEST(http_client, debug) { auto client = new_http_client(); DEFER(delete client); auto op_test = client->new_operation(Verb::GET, to_url(server, "/")); - DEFER(op_test->destroy()); + DEFER(client->destroy_operation(op_test)); op_test->call(); EXPECT_EQ(200, op_test->status_code); std::string buf; @@ -492,7 +492,7 @@ TEST(http_client, server_no_resp) { auto client = new_http_client(); DEFER(delete client); auto op = client->new_operation(Verb::GET, to_url(server, "/wtf")); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); op->req.headers.content_length(0); client->call(op); EXPECT_EQ(-1, op->status_code); @@ -521,7 +521,7 @@ TEST(http_client, partial_body) { auto client = new_http_client(); DEFER(delete client); auto op = client->new_operation(Verb::GET, target_get); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); op->req.headers.content_length(0); client->call(op); EXPECT_EQ(sizeof(socket_buf), op->resp.resource_size()); @@ -540,7 +540,7 @@ TEST(DISABLED_http_client, ipv6) { // make sure runing in a ipv6-ready environm DEFER(delete client); // here is an ipv6-only website auto op = client->new_operation(Verb::GET, "http://test6.ustc.edu.cn"); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); op->call(); EXPECT_EQ(200, op->resp.status_code()); } diff --git a/net/http/test/client_tls_test.cpp b/net/http/test/client_tls_test.cpp index 3d2929c4..f76c3884 100644 --- a/net/http/test/client_tls_test.cpp +++ b/net/http/test/client_tls_test.cpp @@ -72,7 +72,7 @@ TEST(client_tls, basic) { auto client = net::http::new_http_client(nullptr, ctx); DEFER(delete client); auto op = client->new_operation(net::http::Verb::GET, to_surl(tcpserver, "/test")); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); auto exp_len = 20; op->req.headers.range(0, exp_len - 1); op->call(); @@ -91,7 +91,7 @@ TEST(http_client, DISABLED_SNI) { auto client = photon::net::http::new_http_client(nullptr, tls); DEFER(delete client); auto op = client->new_operation(photon::net::http::Verb::GET, "https://debug.fly.dev"); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); op->retry = 0; int res = op->call(); ASSERT_EQ(0, res); diff --git a/net/http/test/server_function_test.cpp b/net/http/test/server_function_test.cpp index d9397b3c..de2ca498 100644 --- a/net/http/test/server_function_test.cpp +++ b/net/http/test/server_function_test.cpp @@ -63,7 +63,7 @@ TEST(http_server, headers) { auto client = new_http_client(); DEFER(delete client); auto op = client->new_operation(Verb::GET, to_url(tcpserver, "/test")); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); auto exp_len = 20; op->req.headers.range(0, exp_len - 1); op->call(); @@ -104,7 +104,7 @@ TEST(http_server, post) { auto client = new_http_client(); DEFER(delete client); auto op = client->new_operation(Verb::POST, to_url(tcpserver, "/test")); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); op->req.headers.content_length(10); std::string body = "1234567890"; auto writer = [&](Request *req)-> ssize_t { @@ -125,7 +125,7 @@ std::string fs_handler_std_str = "01234567890123456789"; void test_case(Client* client, estring_view url, off_t st, size_t len, size_t exp_content_length, bool invalid = false) { LOG_INFO("test case start"); auto op = client->new_operation(Verb::GET, url); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); op->req.headers.range(st, st + len - 1); auto ret = op->call(); LOG_INFO("call finished"); @@ -151,7 +151,7 @@ void test_case(Client* client, estring_view url, off_t st, size_t len, size_t ex void test_head_case(Client* client, estring_view url, off_t st, size_t len, size_t exp_content_length) { LOG_INFO("test HEAD case start"); auto op = client->new_operation(Verb::HEAD, url); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); op->req.headers.range(st, st + len - 1); op->req.headers.content_length(fs_handler_std_str.size()); auto ret = op->call(); @@ -299,7 +299,7 @@ TEST(http_server, proxy_handler_get) { tcpserver->start_loop(); //---------------------------------------------------- auto op = client->new_operation(Verb::GET, to_url(tcpserver, "/filename")); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); ret = op->call(); EXPECT_EQ(0, ret); std::string data_buf; @@ -341,7 +341,7 @@ TEST(http_server, proxy_handler_post) { tcpserver->start_loop(); //---------------------------------------------------- auto op = client->new_operation(Verb::POST, to_url(tcpserver, "/filename")); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); std::string body = "1234567890"; op->req.headers.content_length(10); auto writer = [&](Request *req)-> ssize_t { @@ -402,7 +402,7 @@ TEST(http_server, proxy_handler_post_forward) { DEFER(delete client1); client1->set_proxy(to_url(tcpserver, "/")); auto op = client1->new_operation(Verb::POST, to_url(source_server, "/filename")); - DEFER(op->destroy()); + DEFER(client1->destroy_operation(op)); std::string body = "1234567890"; op->req.headers.content_length(10); auto writer = [&](Request *req)-> ssize_t { @@ -441,7 +441,7 @@ TEST(http_server, proxy_handler_failure) { //---------------------------------------------------- auto url = to_url(tcpserver, "/filename"); auto op = client->new_operation(Verb::GET, url); - DEFER(op->destroy()); + DEFER(client->destroy_operation(op)); auto ret = op->call(); EXPECT_EQ(0, ret); EXPECT_EQ(502, op->resp.status_code()); @@ -492,7 +492,7 @@ TEST(http_server, mux_handler) { //---------------------------------------------------- //--------------test static service-------------------- auto op_static = client->new_operation(Verb::GET, to_url(tcpserver, "/static_service/fs_handler_test")); - DEFER(op_static->destroy()); + DEFER(client->destroy_operation(op_static)); ret = op_static->call(); EXPECT_EQ(0, ret); EXPECT_EQ(200, op_static->resp.status_code()); @@ -503,7 +503,7 @@ TEST(http_server, mux_handler) { EXPECT_EQ(true, data_buf == fs_handler_std_str); //--------------test proxy service--------------------- auto op_proxy = client->new_operation(Verb::GET, to_url(tcpserver, "/proxy/filename_not_important")); - DEFER(op_proxy->destroy()); + DEFER(client->destroy_operation(op_proxy)); ret = op_proxy->call(); EXPECT_EQ(0, ret); EXPECT_EQ(200, op_proxy->resp.status_code()); @@ -514,7 +514,7 @@ TEST(http_server, mux_handler) { EXPECT_EQ(true, data_buf == std_data); //-------------test mux default handler--------------- auto op_default = client->new_operation(Verb::GET, to_url(tcpserver, "/not_recorded/should_be_404")); - DEFER(op_default->destroy()); + DEFER(client->destroy_operation(op_default)); ret = op_default->call(); EXPECT_EQ(0, ret); EXPECT_EQ(404, op_default->resp.status_code());