From 53af1a9cf0be41f6c10edb52e6900eb993873e9f Mon Sep 17 00:00:00 2001 From: jbaldwin Date: Fri, 20 Nov 2020 14:54:54 -0700 Subject: [PATCH 1/6] rename files --- CMakeLists.txt | 30 +++++++------- README.md | 2 +- examples/async_simple.cpp | 2 +- examples/benchmark.cpp | 2 +- examples/readme.cpp | 2 +- examples/synch_simple.cpp | 2 +- inc/lift/Lift.hpp | 15 ------- inc/lift/{Const.hpp => const.hpp} | 0 inc/lift/{Escape.hpp => escape.hpp} | 0 inc/lift/{EventLoop.hpp => event_loop.hpp} | 8 ++-- inc/lift/{Executor.hpp => executor.hpp} | 4 +- inc/lift/{Header.hpp => header.hpp} | 0 inc/lift/{Http.hpp => http.hpp} | 0 inc/lift/{Init.hpp => init.hpp} | 0 inc/lift/lift.hpp | 15 +++++++ inc/lift/{LiftStatus.hpp => lift_status.hpp} | 0 inc/lift/{MimeField.hpp => mime_field.hpp} | 0 .../{QueryBuilder.hpp => query_builder.hpp} | 0 inc/lift/{Request.hpp => request.hpp} | 12 +++--- .../{ResolveHost.hpp => resolve_host.hpp} | 0 inc/lift/{Response.hpp => response.hpp} | 6 +-- inc/lift/{Share.hpp => share.hpp} | 0 src/{Escape.cpp => escape.cpp} | 2 +- src/{EventLoop.cpp => event_loop.cpp} | 4 +- src/{Executor.cpp => executor.cpp} | 6 +-- src/{Header.cpp => header.cpp} | 2 +- src/{Http.cpp => http.cpp} | 2 +- src/{Init.cpp => init.cpp} | 2 +- src/{LiftStatus.cpp => lift_status.cpp} | 2 +- src/{MimeField.cpp => mime_field.cpp} | 2 +- src/{QueryBuilder.cpp => query_builder.cpp} | 4 +- src/{Request.cpp => request.cpp} | 6 +-- src/{ResolveHost.cpp => resolve_host.cpp} | 2 +- src/{Response.cpp => response.cpp} | 4 +- src/{Share.cpp => share.cpp} | 2 +- test/CMakeLists.txt | 29 +++++++------- test/main.cpp | 39 +------------------ test/setup.hpp | 18 +++++++++ ...RequestTest.hpp => test_async_request.cpp} | 8 ++-- test/{EscapeTest.hpp => test_escape.cpp} | 6 +-- ...{EventLoopTest.hpp => test_event_loop.cpp} | 6 +-- test/{HeaderTest.hpp => test_header.cpp} | 4 +- test/{HttpTest.hpp => test_http.cpp} | 8 ++-- ...{MimeFieldTest.hpp => test_mime_field.cpp} | 8 ++-- test/{ProxyTest.hpp => test_proxy.cpp} | 8 ++-- ...BuilderTest.hpp => test_query_builder.cpp} | 8 ++-- ...olveHostTest.hpp => test_resolve_host.cpp} | 8 ++-- test/{ShareTest.hpp => test_share.cpp} | 8 ++-- ...cRequestTest.hpp => test_sync_request.cpp} | 7 ++-- test/{TimesupTest.hpp => test_timesup.cpp} | 6 +-- ...hpp => test_transfer_progress_request.cpp} | 8 ++-- ...estTest.hpp => test_user_data_request.cpp} | 8 ++-- 52 files changed, 143 insertions(+), 184 deletions(-) delete mode 100644 inc/lift/Lift.hpp rename inc/lift/{Const.hpp => const.hpp} (100%) rename inc/lift/{Escape.hpp => escape.hpp} (100%) rename inc/lift/{EventLoop.hpp => event_loop.hpp} (99%) rename inc/lift/{Executor.hpp => executor.hpp} (98%) rename inc/lift/{Header.hpp => header.hpp} (100%) rename inc/lift/{Http.hpp => http.hpp} (100%) rename inc/lift/{Init.hpp => init.hpp} (100%) create mode 100644 inc/lift/lift.hpp rename inc/lift/{LiftStatus.hpp => lift_status.hpp} (100%) rename inc/lift/{MimeField.hpp => mime_field.hpp} (100%) rename inc/lift/{QueryBuilder.hpp => query_builder.hpp} (100%) rename inc/lift/{Request.hpp => request.hpp} (99%) rename inc/lift/{ResolveHost.hpp => resolve_host.hpp} (100%) rename inc/lift/{Response.hpp => response.hpp} (98%) rename inc/lift/{Share.hpp => share.hpp} (100%) rename src/{Escape.cpp => escape.cpp} (97%) rename src/{EventLoop.cpp => event_loop.cpp} (99%) rename src/{Executor.cpp => executor.cpp} (99%) rename src/{Header.cpp => header.cpp} (96%) rename src/{Http.cpp => http.cpp} (99%) rename src/{Init.cpp => init.cpp} (82%) rename src/{LiftStatus.cpp => lift_status.cpp} (98%) rename src/{MimeField.cpp => mime_field.cpp} (94%) rename src/{QueryBuilder.cpp => query_builder.cpp} (97%) rename src/{Request.cpp => request.cpp} (97%) rename src/{ResolveHost.cpp => resolve_host.cpp} (95%) rename src/{Response.cpp => response.cpp} (90%) rename src/{Share.cpp => share.cpp} (98%) create mode 100644 test/setup.hpp rename test/{AsyncRequestTest.hpp => test_async_request.cpp} (98%) rename test/{EscapeTest.hpp => test_escape.cpp} (95%) rename test/{EventLoopTest.hpp => test_event_loop.cpp} (98%) rename test/{HeaderTest.hpp => test_header.cpp} (98%) rename test/{HttpTest.hpp => test_http.cpp} (99%) rename test/{MimeFieldTest.hpp => test_mime_field.cpp} (96%) rename test/{ProxyTest.hpp => test_proxy.cpp} (98%) rename test/{QueryBuilderTest.hpp => test_query_builder.cpp} (93%) rename test/{ResolveHostTest.hpp => test_resolve_host.cpp} (96%) rename test/{ShareTest.hpp => test_share.cpp} (98%) rename test/{SyncRequestTest.hpp => test_sync_request.cpp} (98%) rename test/{TimesupTest.hpp => test_timesup.cpp} (97%) rename test/{TransferProgressRequest.hpp => test_transfer_progress_request.cpp} (97%) rename test/{UserDataRequestTest.hpp => test_user_data_request.cpp} (97%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6afc8c0..ec46899 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,21 +29,21 @@ message("${PROJECT_NAME} LIFT_CODE_COVERAGE = ${LIFT_CODE_COVERAGE}") message("${PROJECT_NAME} LIFT_USER_LINK_LIBRARIES = ${LIFT_USER_LINK_LIBRARIES}") set(LIBLIFT_SOURCE_FILES - inc/lift/Const.hpp - inc/lift/Escape.hpp src/Escape.cpp - inc/lift/EventLoop.hpp src/EventLoop.cpp - inc/lift/Executor.hpp src/Executor.cpp - inc/lift/Header.hpp src/Header.cpp - inc/lift/Http.hpp src/Http.cpp - inc/lift/Init.hpp src/Init.cpp - inc/lift/Lift.hpp - inc/lift/LiftStatus.hpp src/LiftStatus.cpp - inc/lift/MimeField.hpp src/MimeField.cpp - inc/lift/QueryBuilder.hpp src/QueryBuilder.cpp - inc/lift/Request.hpp src/Request.cpp - inc/lift/ResolveHost.hpp src/ResolveHost.cpp - inc/lift/Response.hpp src/Response.cpp - inc/lift/Share.hpp src/Share.cpp + inc/lift/const.hpp + inc/lift/escape.hpp src/escape.cpp + inc/lift/event_loop.hpp src/event_loop.cpp + inc/lift/executor.hpp src/executor.cpp + inc/lift/header.hpp src/header.cpp + inc/lift/http.hpp src/http.cpp + inc/lift/init.hpp src/init.cpp + inc/lift/lift_status.hpp src/lift_status.cpp + inc/lift/lift.hpp + inc/lift/mime_field.hpp src/mime_field.cpp + inc/lift/query_builder.hpp src/query_builder.cpp + inc/lift/request.hpp src/request.cpp + inc/lift/resolve_host.hpp src/resolve_host.cpp + inc/lift/response.hpp src/response.cpp + inc/lift/share.hpp src/share.cpp ) add_library(${PROJECT_NAME} STATIC ${LIBLIFT_SOURCE_FILES}) diff --git a/README.md b/README.md index 94b97bf..de4fcd0 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ to get your started on using liblifthttp with both the synchronous and asynchron #### Synchronous and Asynchronous Requests ```C++ #include - #include + #include int main() { diff --git a/examples/async_simple.cpp b/examples/async_simple.cpp index bd977dc..4ea0301 100644 --- a/examples/async_simple.cpp +++ b/examples/async_simple.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/examples/benchmark.cpp b/examples/benchmark.cpp index 6ce30c8..8f41b44 100644 --- a/examples/benchmark.cpp +++ b/examples/benchmark.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/examples/readme.cpp b/examples/readme.cpp index 78e8a46..27e0b4a 100644 --- a/examples/readme.cpp +++ b/examples/readme.cpp @@ -1,5 +1,5 @@ #include -#include +#include int main() { diff --git a/examples/synch_simple.cpp b/examples/synch_simple.cpp index fbca88f..c8f1437 100644 --- a/examples/synch_simple.cpp +++ b/examples/synch_simple.cpp @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/inc/lift/Lift.hpp b/inc/lift/Lift.hpp deleted file mode 100644 index 3a4704b..0000000 --- a/inc/lift/Lift.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "lift/Const.hpp" -#include "lift/Escape.hpp" -#include "lift/EventLoop.hpp" -#include "lift/Executor.hpp" -#include "lift/Header.hpp" -#include "lift/Init.hpp" -#include "lift/LiftStatus.hpp" -#include "lift/MimeField.hpp" -#include "lift/QueryBuilder.hpp" -#include "lift/Request.hpp" -#include "lift/ResolveHost.hpp" -#include "lift/Response.hpp" -#include "lift/Share.hpp" diff --git a/inc/lift/Const.hpp b/inc/lift/const.hpp similarity index 100% rename from inc/lift/Const.hpp rename to inc/lift/const.hpp diff --git a/inc/lift/Escape.hpp b/inc/lift/escape.hpp similarity index 100% rename from inc/lift/Escape.hpp rename to inc/lift/escape.hpp diff --git a/inc/lift/EventLoop.hpp b/inc/lift/event_loop.hpp similarity index 99% rename from inc/lift/EventLoop.hpp rename to inc/lift/event_loop.hpp index b06783b..89c12e3 100644 --- a/inc/lift/EventLoop.hpp +++ b/inc/lift/event_loop.hpp @@ -1,9 +1,9 @@ #pragma once -#include "lift/Executor.hpp" -#include "lift/Request.hpp" -#include "lift/ResolveHost.hpp" -#include "lift/Share.hpp" +#include "lift/executor.hpp" +#include "lift/request.hpp" +#include "lift/resolve_host.hpp" +#include "lift/share.hpp" #include #include diff --git a/inc/lift/Executor.hpp b/inc/lift/executor.hpp similarity index 98% rename from inc/lift/Executor.hpp rename to inc/lift/executor.hpp index 788845a..3e1b858 100644 --- a/inc/lift/Executor.hpp +++ b/inc/lift/executor.hpp @@ -1,7 +1,7 @@ #pragma once -#include "lift/Request.hpp" -#include "lift/Response.hpp" +#include "lift/request.hpp" +#include "lift/response.hpp" #include diff --git a/inc/lift/Header.hpp b/inc/lift/header.hpp similarity index 100% rename from inc/lift/Header.hpp rename to inc/lift/header.hpp diff --git a/inc/lift/Http.hpp b/inc/lift/http.hpp similarity index 100% rename from inc/lift/Http.hpp rename to inc/lift/http.hpp diff --git a/inc/lift/Init.hpp b/inc/lift/init.hpp similarity index 100% rename from inc/lift/Init.hpp rename to inc/lift/init.hpp diff --git a/inc/lift/lift.hpp b/inc/lift/lift.hpp new file mode 100644 index 0000000..b2c099a --- /dev/null +++ b/inc/lift/lift.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "lift/const.hpp" +#include "lift/escape.hpp" +#include "lift/event_loop.hpp" +#include "lift/executor.hpp" +#include "lift/header.hpp" +#include "lift/init.hpp" +#include "lift/lift_status.hpp" +#include "lift/mime_field.hpp" +#include "lift/query_builder.hpp" +#include "lift/request.hpp" +#include "lift/resolve_host.hpp" +#include "lift/response.hpp" +#include "lift/share.hpp" diff --git a/inc/lift/LiftStatus.hpp b/inc/lift/lift_status.hpp similarity index 100% rename from inc/lift/LiftStatus.hpp rename to inc/lift/lift_status.hpp diff --git a/inc/lift/MimeField.hpp b/inc/lift/mime_field.hpp similarity index 100% rename from inc/lift/MimeField.hpp rename to inc/lift/mime_field.hpp diff --git a/inc/lift/QueryBuilder.hpp b/inc/lift/query_builder.hpp similarity index 100% rename from inc/lift/QueryBuilder.hpp rename to inc/lift/query_builder.hpp diff --git a/inc/lift/Request.hpp b/inc/lift/request.hpp similarity index 99% rename from inc/lift/Request.hpp rename to inc/lift/request.hpp index 3743e34..1dcde30 100644 --- a/inc/lift/Request.hpp +++ b/inc/lift/request.hpp @@ -1,11 +1,11 @@ #pragma once -#include "lift/Header.hpp" -#include "lift/Http.hpp" -#include "lift/MimeField.hpp" -#include "lift/ResolveHost.hpp" -#include "lift/Response.hpp" -#include "lift/Share.hpp" +#include "lift/header.hpp" +#include "lift/http.hpp" +#include "lift/mime_field.hpp" +#include "lift/resolve_host.hpp" +#include "lift/response.hpp" +#include "lift/share.hpp" #include #include diff --git a/inc/lift/ResolveHost.hpp b/inc/lift/resolve_host.hpp similarity index 100% rename from inc/lift/ResolveHost.hpp rename to inc/lift/resolve_host.hpp diff --git a/inc/lift/Response.hpp b/inc/lift/response.hpp similarity index 98% rename from inc/lift/Response.hpp rename to inc/lift/response.hpp index 50803db..99e66d8 100644 --- a/inc/lift/Response.hpp +++ b/inc/lift/response.hpp @@ -1,8 +1,8 @@ #pragma once -#include "lift/Header.hpp" -#include "lift/Http.hpp" -#include "lift/LiftStatus.hpp" +#include "lift/header.hpp" +#include "lift/http.hpp" +#include "lift/lift_status.hpp" #include #include diff --git a/inc/lift/Share.hpp b/inc/lift/share.hpp similarity index 100% rename from inc/lift/Share.hpp rename to inc/lift/share.hpp diff --git a/src/Escape.cpp b/src/escape.cpp similarity index 97% rename from src/Escape.cpp rename to src/escape.cpp index 960599a..d4957e7 100644 --- a/src/Escape.cpp +++ b/src/escape.cpp @@ -1,4 +1,4 @@ -#include "lift/Escape.hpp" +#include "lift/escape.hpp" #include diff --git a/src/EventLoop.cpp b/src/event_loop.cpp similarity index 99% rename from src/EventLoop.cpp rename to src/event_loop.cpp index 4d4bbb8..015d934 100644 --- a/src/EventLoop.cpp +++ b/src/event_loop.cpp @@ -1,5 +1,5 @@ -#include "lift/EventLoop.hpp" -#include "lift/Init.hpp" +#include "lift/event_loop.hpp" +#include "lift/init.hpp" #include #include diff --git a/src/Executor.cpp b/src/executor.cpp similarity index 99% rename from src/Executor.cpp rename to src/executor.cpp index 16bb933..2e5d2e0 100644 --- a/src/Executor.cpp +++ b/src/executor.cpp @@ -1,6 +1,6 @@ -#include "lift/Executor.hpp" -#include "lift/EventLoop.hpp" -#include "lift/Init.hpp" +#include "lift/executor.hpp" +#include "lift/event_loop.hpp" +#include "lift/init.hpp" namespace lift { diff --git a/src/Header.cpp b/src/header.cpp similarity index 96% rename from src/Header.cpp rename to src/header.cpp index a767dcf..e5a62d9 100644 --- a/src/Header.cpp +++ b/src/header.cpp @@ -1,4 +1,4 @@ -#include "lift/Header.hpp" +#include "lift/header.hpp" #include diff --git a/src/Http.cpp b/src/http.cpp similarity index 99% rename from src/Http.cpp rename to src/http.cpp index 065e92b..240c3fd 100644 --- a/src/Http.cpp +++ b/src/http.cpp @@ -1,4 +1,4 @@ -#include "lift/Http.hpp" +#include "lift/http.hpp" namespace lift::http { diff --git a/src/Init.cpp b/src/init.cpp similarity index 82% rename from src/Init.cpp rename to src/init.cpp index 92ddc1b..f2f62e0 100644 --- a/src/Init.cpp +++ b/src/init.cpp @@ -1,4 +1,4 @@ -#include "lift/Init.hpp" +#include "lift/init.hpp" namespace lift { diff --git a/src/LiftStatus.cpp b/src/lift_status.cpp similarity index 98% rename from src/LiftStatus.cpp rename to src/lift_status.cpp index 6584280..f905066 100644 --- a/src/LiftStatus.cpp +++ b/src/lift_status.cpp @@ -1,4 +1,4 @@ -#include "lift/LiftStatus.hpp" +#include "lift/lift_status.hpp" namespace lift { diff --git a/src/MimeField.cpp b/src/mime_field.cpp similarity index 94% rename from src/MimeField.cpp rename to src/mime_field.cpp index dca567b..c148b62 100644 --- a/src/MimeField.cpp +++ b/src/mime_field.cpp @@ -1,4 +1,4 @@ -#include "lift/MimeField.hpp" +#include "lift/mime_field.hpp" namespace lift { diff --git a/src/QueryBuilder.cpp b/src/query_builder.cpp similarity index 97% rename from src/QueryBuilder.cpp rename to src/query_builder.cpp index 85d3df7..f450da6 100644 --- a/src/QueryBuilder.cpp +++ b/src/query_builder.cpp @@ -1,5 +1,5 @@ -#include "lift/QueryBuilder.hpp" -#include "lift/Escape.hpp" +#include "lift/query_builder.hpp" +#include "lift/escape.hpp" namespace lift { diff --git a/src/Request.cpp b/src/request.cpp similarity index 97% rename from src/Request.cpp rename to src/request.cpp index 5197d6d..36a169a 100644 --- a/src/Request.cpp +++ b/src/request.cpp @@ -1,6 +1,6 @@ -#include "lift/Request.hpp" -#include "lift/Const.hpp" -#include "lift/Executor.hpp" +#include "lift/request.hpp" +#include "lift/const.hpp" +#include "lift/executor.hpp" namespace lift { diff --git a/src/ResolveHost.cpp b/src/resolve_host.cpp similarity index 95% rename from src/ResolveHost.cpp rename to src/resolve_host.cpp index c1467bd..2558cc4 100644 --- a/src/ResolveHost.cpp +++ b/src/resolve_host.cpp @@ -1,4 +1,4 @@ -#include "lift/ResolveHost.hpp" +#include "lift/resolve_host.hpp" namespace lift { diff --git a/src/Response.cpp b/src/response.cpp similarity index 90% rename from src/Response.cpp rename to src/response.cpp index 9d51fba..1aa3c53 100644 --- a/src/Response.cpp +++ b/src/response.cpp @@ -1,5 +1,5 @@ -#include "lift/Response.hpp" -#include "lift/Const.hpp" +#include "lift/response.hpp" +#include "lift/const.hpp" namespace lift { diff --git a/src/Share.cpp b/src/share.cpp similarity index 98% rename from src/Share.cpp rename to src/share.cpp index ddd4338..fb67881 100644 --- a/src/Share.cpp +++ b/src/share.cpp @@ -1,4 +1,4 @@ -#include "lift/Share.hpp" +#include "lift/share.hpp" namespace lift { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 926de79..763bc6e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,20 +4,21 @@ project(liblifthttp_tests) option(LIFT_LOCALHOST_TESTS "Define ON if running tests locally." OFF) set(LIBLIFT_TEST_SOURCE_FILES - AsyncRequestTest.hpp - EscapeTest.hpp - EventLoopTest.hpp - HeaderTest.hpp - HttpTest.hpp - MimeFieldTest.hpp - ProxyTest.hpp - QueryBuilderTest.hpp - ResolveHostTest.hpp - ShareTest.hpp - SyncRequestTest.hpp - TimesupTest.hpp - TransferProgressRequest.hpp - UserDataRequestTest.hpp + setup.hpp + test_async_request.cpp + test_escape.cpp + test_event_loop.cpp + test_header.cpp + test_http.cpp + test_mime_field.cpp + test_proxy.cpp + test_query_builder.cpp + test_resolve_host.cpp + test_share.cpp + test_sync_request.cpp + test_timesup.cpp + test_transfer_progress_request.cpp + test_user_data_request.cpp ) add_executable(${PROJECT_NAME} main.cpp ${LIBLIFT_TEST_SOURCE_FILES}) diff --git a/test/main.cpp b/test/main.cpp index 668e008..037fbc7 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,23 +1,7 @@ #define CATCH_CONFIG_MAIN +#include "catch.hpp" -#include -#include - -#ifdef LIFT_LOCALHOST_TESTS -static const std::string SERVICE_IP_ADDRESS = "127.0.0.1"; -static const std::string NGINX_HOSTNAME = "localhost"; -static const std::string HAPROXY_HOSTNAME = "localhost"; -#else -// Note that this IP Address is asigned by github actions and is subject to change. -static const std::string SERVICE_IP_ADDRESS = "172.18.0.3"; -static const std::string NGINX_HOSTNAME = "nginx"; -static const std::string HAPROXY_HOSTNAME = "haproxy"; -#endif - -static const uint16_t NGINX_PORT = 80; -static const std::string NGINX_PORT_STR = "80"; -static const uint32_t HAPROXY_PORT = 3128; -static const std::string HAPROXY_PORT_STR = "3128"; +#include "setup.hpp" struct TestSetupInfo { @@ -32,22 +16,3 @@ struct TestSetupInfo << "\n"; } } test_setup_info_instance; - -#include "catch.hpp" - -#include - -#include "AsyncRequestTest.hpp" -#include "EscapeTest.hpp" -#include "EventLoopTest.hpp" -#include "HeaderTest.hpp" -#include "HttpTest.hpp" -#include "MimeFieldTest.hpp" -#include "ProxyTest.hpp" -#include "QueryBuilderTest.hpp" -#include "ResolveHostTest.hpp" -#include "ShareTest.hpp" -#include "SyncRequestTest.hpp" -#include "TimesupTest.hpp" -#include "TransferProgressRequest.hpp" -#include "UserDataRequestTest.hpp" diff --git a/test/setup.hpp b/test/setup.hpp new file mode 100644 index 0000000..21bab89 --- /dev/null +++ b/test/setup.hpp @@ -0,0 +1,18 @@ +#include +#include + +#ifdef LIFT_LOCALHOST_TESTS +static inline const std::string SERVICE_IP_ADDRESS = "127.0.0.1"; +static inline const std::string NGINX_HOSTNAME = "localhost"; +static inline const std::string HAPROXY_HOSTNAME = "localhost"; +#else +// Note that this IP Address is asigned by github actions and is subject to change. +static inline const std::string SERVICE_IP_ADDRESS = "172.18.0.3"; +static inline const std::string NGINX_HOSTNAME = "nginx"; +static inline const std::string HAPROXY_HOSTNAME = "haproxy"; +#endif + +static inline const uint16_t NGINX_PORT = 80; +static inline const std::string NGINX_PORT_STR = "80"; +static inline const uint32_t HAPROXY_PORT = 3128; +static inline const std::string HAPROXY_PORT_STR = "3128"; diff --git a/test/AsyncRequestTest.hpp b/test/test_async_request.cpp similarity index 98% rename from test/AsyncRequestTest.hpp rename to test/test_async_request.cpp index 3c44f00..43f6b78 100644 --- a/test/AsyncRequestTest.hpp +++ b/test/test_async_request.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include #include #include @@ -98,4 +96,4 @@ TEST_CASE("Async POST request") request->Header("Expect", ""); ev.StartRequest(std::move(request)); -} \ No newline at end of file +} diff --git a/test/EscapeTest.hpp b/test/test_escape.cpp similarity index 95% rename from test/EscapeTest.hpp rename to test/test_escape.cpp index 2bfb376..e6acfd3 100644 --- a/test/EscapeTest.hpp +++ b/test/test_escape.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include TEST_CASE("Escape", "[escape]") { diff --git a/test/EventLoopTest.hpp b/test/test_event_loop.cpp similarity index 98% rename from test/EventLoopTest.hpp rename to test/test_event_loop.cpp index de2e96e..f685bdc 100644 --- a/test/EventLoopTest.hpp +++ b/test/test_event_loop.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include TEST_CASE("EventLoop Start event loop, then stop and add a request.") { diff --git a/test/HeaderTest.hpp b/test/test_header.cpp similarity index 98% rename from test/HeaderTest.hpp rename to test/test_header.cpp index 61dc204..a2d5e9b 100644 --- a/test/HeaderTest.hpp +++ b/test/test_header.cpp @@ -1,6 +1,6 @@ #include "catch.hpp" - -#include +#include "setup.hpp" +#include TEST_CASE("Header basic") { diff --git a/test/HttpTest.hpp b/test/test_http.cpp similarity index 99% rename from test/HttpTest.hpp rename to test/test_http.cpp index 11919e1..b4a3b1a 100644 --- a/test/HttpTest.hpp +++ b/test/test_http.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include TEST_CASE("HTTP Method to_string") { @@ -248,4 +246,4 @@ TEST_CASE("HTTP ConnectionType to_string") REQUIRE(to_string(ConnectionType::KEEP_ALIVE) == CONNECTION_TYPE_KEEP_ALIVE); REQUIRE(to_string(ConnectionType::UPGRADE) == CONNECTION_TYPE_UPGRADE); REQUIRE(to_string(static_cast(3839)) == CONNECTION_TYPE_UNKNOWN); -} \ No newline at end of file +} diff --git a/test/MimeFieldTest.hpp b/test/test_mime_field.cpp similarity index 96% rename from test/MimeFieldTest.hpp rename to test/test_mime_field.cpp index 6ed11dd..eaac425 100644 --- a/test/MimeFieldTest.hpp +++ b/test/test_mime_field.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include TEST_CASE("MimeField field_value") { @@ -42,4 +40,4 @@ TEST_CASE("MimeField added to Request") REQUIRE(mime_fields[1].Name() == "name2"); REQUIRE(std::holds_alternative(mime_fields[1].Value())); REQUIRE(std::get(mime_fields[1].Value()) == "/var/log/lift.log"); -} \ No newline at end of file +} diff --git a/test/ProxyTest.hpp b/test/test_proxy.cpp similarity index 98% rename from test/ProxyTest.hpp rename to test/test_proxy.cpp index 6e31af7..7c1b482 100644 --- a/test/ProxyTest.hpp +++ b/test/test_proxy.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include #include @@ -98,4 +96,4 @@ TEST_CASE("Proxy Any Auth") REQUIRE(header.Value() == "text/html"); } } -} \ No newline at end of file +} diff --git a/test/QueryBuilderTest.hpp b/test/test_query_builder.cpp similarity index 93% rename from test/QueryBuilderTest.hpp rename to test/test_query_builder.cpp index afa9e92..5b3d4ed 100644 --- a/test/QueryBuilderTest.hpp +++ b/test/test_query_builder.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include TEST_CASE("Query Builder simple") { @@ -23,4 +21,4 @@ TEST_CASE("Query Builder simple") url = query_builder.Build(); REQUIRE(url == "http://www.reddit.com/r/funny"); -} \ No newline at end of file +} diff --git a/test/ResolveHostTest.hpp b/test/test_resolve_host.cpp similarity index 96% rename from test/ResolveHostTest.hpp rename to test/test_resolve_host.cpp index e95e991..3f94bee 100644 --- a/test/ResolveHostTest.hpp +++ b/test/test_resolve_host.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include TEST_CASE("ResolveHost synchronous perform") { @@ -41,4 +39,4 @@ TEST_CASE("EventLoop ResolveHost") lift::Request::make_unique("herpderp.com:" + NGINX_PORT_STR, std::chrono::seconds{60}, on_complete)); REQUIRE(ev.StartRequests(std::move(requests))); -} \ No newline at end of file +} diff --git a/test/ShareTest.hpp b/test/test_share.cpp similarity index 98% rename from test/ShareTest.hpp rename to test/test_share.cpp index 27d3d32..4134f0f 100644 --- a/test/ShareTest.hpp +++ b/test/test_share.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include TEST_CASE("Share Requests ALL") { @@ -125,4 +123,4 @@ TEST_CASE("Share EventLoop overlapping requests") } REQUIRE(count == N_EVENT_LOOPS * N_REQUESTS); -} \ No newline at end of file +} diff --git a/test/SyncRequestTest.hpp b/test/test_sync_request.cpp similarity index 98% rename from test/SyncRequestTest.hpp rename to test/test_sync_request.cpp index 6a5572b..008ab5d 100644 --- a/test/SyncRequestTest.hpp +++ b/test/test_sync_request.cpp @@ -1,9 +1,8 @@ -#pragma once - #include "catch.hpp" +#include "setup.hpp" +#include #include -#include TEST_CASE("Synchronous 200") { @@ -111,4 +110,4 @@ TEST_CASE("Happy Eyeballs Test") TEST_CASE("SSL functions") { // TODO, some of these require files. -} \ No newline at end of file +} diff --git a/test/TimesupTest.hpp b/test/test_timesup.cpp similarity index 97% rename from test/TimesupTest.hpp rename to test/test_timesup.cpp index 870b9be..4528b0e 100644 --- a/test/TimesupTest.hpp +++ b/test/test_timesup.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include #include #include diff --git a/test/TransferProgressRequest.hpp b/test/test_transfer_progress_request.cpp similarity index 97% rename from test/TransferProgressRequest.hpp rename to test/test_transfer_progress_request.cpp index 956a5f7..32389b6 100644 --- a/test/TransferProgressRequest.hpp +++ b/test/test_transfer_progress_request.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include #include @@ -53,4 +51,4 @@ TEST_CASE("Download bytes test synchronous") // Its possible the test downloads the entire file before finishing, take the appropriate action. REQUIRE(response.LiftStatus() == ((should_failed) ? lift::LiftStatus::ERROR : lift::LiftStatus::SUCCESS)); REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); -} \ No newline at end of file +} diff --git a/test/UserDataRequestTest.hpp b/test/test_user_data_request.cpp similarity index 97% rename from test/UserDataRequestTest.hpp rename to test/test_user_data_request.cpp index 0d10116..2c95e94 100644 --- a/test/UserDataRequestTest.hpp +++ b/test/test_user_data_request.cpp @@ -1,8 +1,6 @@ -#pragma once - #include "catch.hpp" - -#include +#include "setup.hpp" +#include static auto user_data_on_complete( lift::RequestPtr request_ptr, lift::Response response, uint64_t user_data_value1, double user_data_value2) -> void @@ -50,4 +48,4 @@ TEST_CASE("User data") { std::this_thread::sleep_for(std::chrono::milliseconds{10}); } -} \ No newline at end of file +} From 9f37c09d908de481bdfd7dc743f2cc9b47c9e362 Mon Sep 17 00:00:00 2001 From: jbaldwin Date: Sun, 22 Nov 2020 12:01:31 -0700 Subject: [PATCH 2/6] through http.hpp --- README.md | 26 +- examples/async_simple.cpp | 6 +- examples/benchmark.cpp | 10 +- examples/readme.cpp | 26 +- examples/synch_simple.cpp | 2 +- inc/lift/const.hpp | 4 +- inc/lift/event_loop.hpp | 210 +++---- inc/lift/executor.hpp | 40 +- inc/lift/header.hpp | 27 +- inc/lift/http.hpp | 551 +++++++++-------- inc/lift/request.hpp | 26 +- inc/lift/resolve_host.hpp | 4 +- inc/lift/response.hpp | 22 +- inc/lift/share.hpp | 4 +- src/event_loop.cpp | 303 +++++----- src/executor.cpp | 66 +- src/header.cpp | 4 +- src/http.cpp | 773 ++++++++++-------------- src/request.cpp | 6 +- src/response.cpp | 10 +- test/test_async_request.cpp | 36 +- test/test_event_loop.cpp | 34 +- test/test_header.cpp | 82 +-- test/test_http.cpp | 436 +++++++------ test/test_proxy.cpp | 42 +- test/test_resolve_host.cpp | 10 +- test/test_share.cpp | 40 +- test/test_sync_request.cpp | 36 +- test/test_timesup.cpp | 18 +- test/test_transfer_progress_request.cpp | 4 +- test/test_user_data_request.cpp | 8 +- 31 files changed, 1351 insertions(+), 1515 deletions(-) diff --git a/README.md b/README.md index de4fcd0..a0e1ea0 100644 --- a/README.md +++ b/README.md @@ -37,42 +37,32 @@ to get your started on using liblifthttp with both the synchronous and asynchron lift::Request request{"http://www.example.com"}; // This is the blocking synchronous HTTP call. auto response = request.Perform(); - std::cout << "LiftStatus: " << lift::to_string(response.LiftStatus()) << "\n"; - std::cout << "HTTP Status Code: " << lift::http::to_string(response.StatusCode()) << "\n"; - for (const auto& header : response.Headers()) - { - std::cout << header.Name() << ": " << header.Value() << "\n"; - } - std::cout << response.Data(); + std::cout << "Lift status: " << lift::to_string(response.LiftStatus()) << "\n"; + std::cout << response << "\n"; // Will print the raw http response. // Creating the event loop starts it immediately, it spawns a background thread for executing requests. - lift::EventLoop loop{}; + lift::event_loop loop{}; // Create the request just like we did in the sync version, but now provide a lambda for on completion. // NOTE: that the Lambda is executed ON the Lift event loop background thread. If you want to handle // on completion processing on this main thread you need to std::move() it back via a queue or inter-thread // communication. This is imporant if any resources are shared between the threads. // NOTE: The request is created on the heap so ownership can be passed easily via an std::unique_ptr - // to the lift::EventLoop! lift::Request::make_unique() is a handy function to easily do so. + // to the lift::event_loop! lift::Request::make_unique() is a handy function to easily do so. auto request_ptr = lift::Request::make_unique( "http://www.example.com", std::chrono::seconds{10}, // Give the request 10 seconds to complete or timeout. [](lift::RequestPtr req_ptr, lift::Response response) { - std::cout << "LiftStatus: " << lift::to_string(response.LiftStatus()) << "\n"; - std::cout << "HTTP Status Code: " << lift::http::to_string(response.StatusCode()) << "\n"; - for (const auto& header : response.Headers()) - { - std::cout << header.Name() << ": " << header.Value() << "\n"; - } - std::cout << response.Data(); + std::cout << "Lift status: " << lift::to_string(response.LiftStatus()) << "\n"; + std::cout << response << "\n"; }); // Now inject the request into the event to be executed. Moving into the event loop is required, // this passes ownership of the request to the event loop background worker thread. - loop.StartRequest(std::move(request_ptr)); + loop.start_request(std::move(request_ptr)); // Block on this main thread until the lift event loop background thread has completed the request, or timed out. - while (loop.ActiveRequestCount() > 0) + while (!loop.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds{10}); } diff --git a/examples/async_simple.cpp b/examples/async_simple.cpp index 4ea0301..2be3788 100644 --- a/examples/async_simple.cpp +++ b/examples/async_simple.cpp @@ -24,7 +24,7 @@ int main() std::vector urls = {"http://www.example.com", "http://www.google.com", "http://www.reddit.com"}; - lift::EventLoop event_loop{}; + lift::event_loop el{}; /** * Create asynchronous requests for each url and inject them into @@ -36,13 +36,13 @@ int main() { std::cout << "Requesting " << url << std::endl; auto request_ptr = lift::Request::make_unique(url, timeout, on_complete); - event_loop.StartRequest(std::move(request_ptr)); + el.start_request(std::move(request_ptr)); timeout += 250ms; std::this_thread::sleep_for(50ms); } // Now wait for all the requests to finish before cleaning up. - while (event_loop.ActiveRequestCount() > 0) + while (!el.empty()) { std::this_thread::sleep_for(100ms); } diff --git a/examples/benchmark.cpp b/examples/benchmark.cpp index 8f41b44..9aee6f7 100644 --- a/examples/benchmark.cpp +++ b/examples/benchmark.cpp @@ -99,10 +99,10 @@ int main(int argc, char* argv[]) std::atomic error{0}; { - std::vector> loops; + std::vector> loops; for (uint64_t i = 0; i < threads; ++i) { - auto event_loop_ptr = std::make_unique(); + auto event_loop_ptr = std::make_unique(); for (uint64_t j = 0; j < connections; ++j) { @@ -120,12 +120,12 @@ int main(int argc, char* argv[]) } // And request again until we are shutting down. - event_loop.StartRequest(std::move(req_ptr)); + event_loop.start_request(std::move(req_ptr)); }); request_ptr->FollowRedirects(false); request_ptr->Header("Connection", "Keep-Alive"); - event_loop_ptr->StartRequest(std::move(request_ptr)); + event_loop_ptr->start_request(std::move(request_ptr)); } loops.emplace_back(std::move(event_loop_ptr)); @@ -135,7 +135,7 @@ int main(int argc, char* argv[]) for (auto& thread : loops) { - thread->Stop(); + thread->stop(); } } diff --git a/examples/readme.cpp b/examples/readme.cpp index 27e0b4a..004ad7f 100644 --- a/examples/readme.cpp +++ b/examples/readme.cpp @@ -7,42 +7,32 @@ int main() lift::Request request{"http://www.example.com"}; // This is the blocking synchronous HTTP call. auto response = request.Perform(); - std::cout << "LiftStatus: " << lift::to_string(response.LiftStatus()) << "\n"; - std::cout << "HTTP Status Code: " << lift::http::to_string(response.StatusCode()) << "\n"; - for (const auto& header : response.Headers()) - { - std::cout << header.Name() << ": " << header.Value() << "\n"; - } - std::cout << response.Data(); + std::cout << "Lift status: " << lift::to_string(response.LiftStatus()) << "\n"; + std::cout << response << "\n"; // Will print the raw http response. // Creating the event loop starts it immediately, it spawns a background thread for executing requests. - lift::EventLoop loop{}; + lift::event_loop loop{}; // Create the request just like we did in the sync version, but now provide a lambda for on completion. // NOTE: that the Lambda is executed ON the Lift event loop background thread. If you want to handle // on completion processing on this main thread you need to std::move() it back via a queue or inter-thread // communication. This is imporant if any resources are shared between the threads. // NOTE: The request is created on the heap so ownership can be passed easily via an std::unique_ptr - // to the lift::EventLoop! lift::Request::make_unique() is a handy function to easily do so. + // to the lift::event_loop! lift::Request::make_unique() is a handy function to easily do so. auto request_ptr = lift::Request::make_unique( "http://www.example.com", std::chrono::seconds{10}, // Give the request 10 seconds to complete or timeout. [](lift::RequestPtr req_ptr, lift::Response response) { - std::cout << "LiftStatus: " << lift::to_string(response.LiftStatus()) << "\n"; - std::cout << "HTTP Status Code: " << lift::http::to_string(response.StatusCode()) << "\n"; - for (const auto& header : response.Headers()) - { - std::cout << header.Name() << ": " << header.Value() << "\n"; - } - std::cout << response.Data(); + std::cout << "Lift status: " << lift::to_string(response.LiftStatus()) << "\n"; + std::cout << response << "\n"; }); // Now inject the request into the event to be executed. Moving into the event loop is required, // this passes ownership of the request to the event loop background worker thread. - loop.StartRequest(std::move(request_ptr)); + loop.start_request(std::move(request_ptr)); // Block on this main thread until the lift event loop background thread has completed the request, or timed out. - while (loop.ActiveRequestCount() > 0) + while (!loop.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds{10}); } diff --git a/examples/synch_simple.cpp b/examples/synch_simple.cpp index c8f1437..0c21ec4 100644 --- a/examples/synch_simple.cpp +++ b/examples/synch_simple.cpp @@ -19,7 +19,7 @@ int main() for (const auto& header : response.Headers()) { - std::cout << header.Name() << ": " << header.Value() << "\n"; + std::cout << header.name() << ": " << header.value() << "\n"; } } diff --git a/inc/lift/const.hpp b/inc/lift/const.hpp index 835b3e7..f4c4673 100644 --- a/inc/lift/const.hpp +++ b/inc/lift/const.hpp @@ -4,7 +4,7 @@ namespace lift { -static constexpr uint64_t HEADER_DEFAULT_MEMORY_BYTES = 4096; -static constexpr uint64_t HEADER_DEFAULT_COUNT = 16; +static constexpr uint64_t header_default_memory_bytes = 4096; +static constexpr uint64_t header_default_count = 16; } // namespace lift diff --git a/inc/lift/event_loop.hpp b/inc/lift/event_loop.hpp index 89c12e3..477b68c 100644 --- a/inc/lift/event_loop.hpp +++ b/inc/lift/event_loop.hpp @@ -19,67 +19,92 @@ namespace lift { -class CurlContext; -using CurlContextPtr = std::unique_ptr; +class curl_context; +using curl_context_ptr = std::unique_ptr; -class EventLoop +class event_loop { - friend CurlContext; - friend Executor; + friend curl_context; + friend executor; public: - // libuv uses simple uint64_t values for millisecond steady clocks. - using TimePoint = uint64_t; + /// libuv uses simple uint64_t values for millisecond steady clocks. + using time_point = uint64_t; + + /// Functor type for on background thread creation/deletion. + using on_thread_callback_type = std::function; + + struct options + { + /// The number of connections to prepare (reserve) for execution. + std::optional reserve_connections{std::nullopt}; + /// The maximum number of connections this event loop should + /// hold open at any given time. If exceeded the oldest connection + /// not in use will be removed. + std::optional max_connections{std::nullopt}; + /// The amount of time new connections are allowed to setup the connection. + /// This value will be applied to every request that is executed through + /// this event loop, but if the individual request has a connect timeout + /// set on it then that value will be used instead. Note that on individual + /// requests this value should be less than the total timeout value, but on + /// the event loop this should be larger than the total timeout, its a special + /// feature to allow for long tail connects but very short requests once + /// the keep-alive connection is established. + std::optional connect_timeout{std::nullopt}; + /// A set of host:port combinations to bypass DNS resolving. + std::optional> resolve_hosts{std::nullopt}; + /// Should separate event loops share connection information? + SharePtr share_ptr{nullptr}; + /// If this functor is provided it is called on the background + /// thread starting and thread stopping. This can be used to set the + /// thread's priority/niceness or possibly changes its thread name. + on_thread_callback_type on_thread_callback{nullptr}; + }; /** * Creates a new lift event loop to execute many asynchronous HTTP requests simultaneously. - * @param reserve_connections The number of connections to prepare (reserve) for execution. - * @param max_connections The maximum number of connections this event loop should - * hold open at any given time. If exceeded the oldest connection - * not in use will be removed. - * @param connect_timeout The amount of time new connections are allowed to setup the connection. - * This value will be applied to every request that is executed through - * this event loop, but if the individual request has a connect timeout - * set on it then that value will be used instead. Note that on individual - * requests this value should be less than the total timeout value, but on - * the event loop this should be larger than the total timeout, its a special - * feature to allow for long tail connects but very short requests once - * the keep-alive connection is established. - * @param resolve_hosts A set of host:port combinations to bypass DNS resolving. - * @param share_ptr Should separate event loops share connection information? + * @param options See event_loop::options for various options. */ - explicit EventLoop( - std::optional reserve_connections = std::nullopt, - std::optional max_connections = std::nullopt, - std::optional connect_timeout = std::nullopt, - std::vector resolve_hosts = {}, - SharePtr share_ptr = nullptr); - - ~EventLoop(); - - EventLoop(const EventLoop& copy) = delete; - EventLoop(EventLoop&& move) = delete; - auto operator=(const EventLoop& copy_assign) noexcept -> EventLoop& = delete; - auto operator=(EventLoop&& move_assign) noexcept -> EventLoop& = delete; + explicit event_loop( + options opts = options{ + std::nullopt, // reserve connections + std::nullopt, // max connections + std::nullopt, // connect timeout + std::nullopt, // resolve hosts + nullptr, // share ptr + nullptr // on thread callback + }); + + ~event_loop(); + + event_loop(const event_loop&) = delete; + event_loop(event_loop&&) = delete; + auto operator=(const event_loop&) noexcept -> event_loop& = delete; + auto operator=(event_loop&&) noexcept -> event_loop& = delete; /** * @return True if the event loop is currently running. */ - [[nodiscard]] auto IsRunning() -> bool; + [[nodiscard]] auto is_running() -> bool { return m_is_running.load(std::memory_order_acquire); } /** * Stops the event loop from accepting new requests. It will continue to process - * existing requests until they are completed. Note that the ~EventLoop() will + * existing requests until they are completed. Note that the ~event_loop() will * 'block' until all requests flush as the background even loop process thread * won't exit until they are all completed/timed-out/error'ed/etc. */ - auto Stop() -> void; + auto stop() -> void { m_is_stopping.exchange(true, std::memory_order_release); } /** * @return Gets the number of active HTTP requests currently running. This includes * the number of pending requests that haven't been started yet (if any). */ - [[nodiscard]] auto ActiveRequestCount() const -> uint64_t; + [[nodiscard]] auto size() const -> uint64_t { return m_active_request_count.load(std::memory_order_relaxed); } + + /** + * @return True if there are no requests pending or executing. + */ + [[nodiscard]] auto empty() const -> bool { return size() == 0; } /** * Adds a request to process. The ownership of the request is trasferred into @@ -92,42 +117,25 @@ class EventLoop * will have its OnComplete() handler called * when its completed/error'ed/etc. */ - auto StartRequest(RequestPtr request_ptr) -> bool; + auto start_request(RequestPtr request_ptr) -> bool; /** * Adds a batch of requests to process. The requests in the container will be moved - * out of the container and into the EventLoop, ownership of the requests is transferred + * out of the container and into the event_loop, ownership of the requests is transferred * into th event loop during execution. * * This function is thread safe. * - * @tparam Container A container of class RequestPtr. + * @tparam container_type A container of class lift::request_ptr. * @param requests The batch of requests to process. */ - template - auto StartRequests(Container requests) -> bool; - - /** - * Gets the background event loop's native thread id. This will only be available after the - * background thread has started, e.g. `IsRunning()` returns `true`. - * @return std::thread::native_handle_type for the background event loop thread. - */ - [[nodiscard]] auto NativeThreadHandle() const -> const std::optional>& - { - return m_native_handle; - } - - /** - * Gets the background event loop's native operating system thread id. This will only be available - * after the background thread has started, e.g. `IsRunning()` returns `true`. - * @return gettid() - */ - [[nodiscard]] auto OperatingSystemThreadId() const -> const std::optional>& { return m_tid; } + template + auto start_requests(container_type requests) -> bool; private: - /// Set to true if the EventLoop is currently running. + /// Set to true if the event_loop is currently running. std::atomic m_is_running{false}; - /// Set to true if the EventLoop is currently shutting down. + /// Set to true if the event_loop is currently shutting down. std::atomic m_is_stopping{false}; /// The active number of requests running. std::atomic m_active_request_count{0}; @@ -153,119 +161,119 @@ class EventLoop * uv loop iteration. Any memory accesses to this object should first acquire the * m_pending_requests_lock to guarantee thread safety. * - * Before the EventLoop begins working on the pending requests, it swaps + * Before the event_loop begins working on the pending requests, it swaps * the pending requests vector into the grabbed requests vector -- this is done * because the pending requests lock could deadlock with internal curl locks! */ std::vector m_pending_requests{}; - /// Only accessible from within the EventLoop thread. + /// Only accessible from within the event_loop thread. std::vector m_grabbed_requests{}; /// The background thread spawned to drive the event loop. std::thread m_background_thread{}; - /// The background thread operating system thread id. - std::optional> m_tid{}; - /// The background thread native handle type id (pthread_t). - std::optional> m_native_handle{}; - /// List of CurlContext objects to re-use for requests, cannot be initialized here due to CurlContext being private. - std::deque m_curl_context_ready; + /// List of curl_context objects to re-use for requests, cannot be initialized here due to curl_context being + /// private. + std::deque m_curl_context_ready; - /// Pool of Executors for running requests. - std::deque> m_executors{}; + /// Pool of executors for running requests. + std::deque> m_executors{}; /// The set of resolve hosts to apply to all requests in this event loop. std::vector m_resolve_hosts{}; /// When connection time is enabled on an event loop the curl timeout is the longer /// timeout value and these timeouts are the shorter value. - std::multimap m_timeouts{}; + std::multimap m_timeouts{}; /// If the event loop is provided a Share object then connection information like /// DNS/SSL/Data pipelining can be shared across event loops. SharePtr m_share_ptr{nullptr}; + /// Functor to call on background thread start/stop. + on_thread_callback_type m_on_thread_callback{nullptr}; + /// The background thread runs from this function. auto run() -> void; /** * Checks current pending curl actions like timeouts. */ - auto checkActions() -> void; + auto check_actions() -> void; /** * Checks current pending curl actions for a specific socket/action (event_bitmask) * @param socket The socket to check current actions on. * @param event_bitmask The type of action (IN|OUT|INOUT|ERR). */ - auto checkActions(curl_socket_t socket, int event_bitmask) -> void; + auto check_actions(curl_socket_t socket, int event_bitmask) -> void; /** * Completes a request to pass ownership back to the user land. * Manages internal state accordingly, always call this function rather * than the Request->OnComplete() function directly. - * @param executor The request handle to complete. + * @param exe The request handle to complete. * @param status The status of the request when completing. */ - auto completeRequestNormal(Executor& executor, LiftStatus status) -> void; + auto complete_request_normal(executor& exe, LiftStatus status) -> void; /** * Completes a request that has timed out but still has connection time remaining. - * @param executor The request to timeout. + * @param exe The request to timeout. */ - auto completeRequestTimeout(Executor& executor) -> void; + auto complete_request_timeout(executor& exe) -> void; /** * Adds the request with the appropriate timeout. * If only a timeout exists, the timeout is set directly on CURLM. * If timeout + connection time exists AND connectoin time > timeout - * timeout is set on the EventLoop + * timeout is set on the event_loop * connection time is set on Curl * If timeout > connection time - * timeout is set on the EventLoop + * timeout is set on the event_loop * If no timeout exists nothing is set (infinite -- and could hang). */ - auto addTimeout(Executor& executor) -> void; + auto add_timeout(executor& exe) -> void; /** - * Removes the timeout from the EventLoop timer information. + * Removes the timeout from the event_loop timer information. * Connection time can still fire from curl but the request's * on complete handler won't be called. */ - auto removeTimeout(Executor& executor) -> std::multimap::iterator; + auto remove_timeout(executor& exe) -> std::multimap::iterator; /** * Updates the event loop timeout information. */ - auto updateTimeouts() -> void; + auto update_timeouts() -> void; - auto acquireExecutor() -> std::unique_ptr; - auto returnExecutor(std::unique_ptr executor_ptr) -> void; + auto acquire_executor() -> std::unique_ptr; + auto return_executor(std::unique_ptr executor_ptr) -> void; /** * This function is called by libcurl to start a timeout with duration timeout_ms. * - * This function is a friend so it can access the EventLoop's m_timeout_timer object and - * call checkActions(). + * This function is a friend so it can access the event_loop's m_timeout_timer object and + * call check_actions(). * * @param cmh The curl multi handle to apply the new timeout for. * @param timeout_ms The timeout duration in milliseconds. - * @param user_data This is a pointer to this EventLoop object. + * @param user_data This is a pointer to this event_loop object. */ friend auto curl_start_timeout(CURLM* cmh, long timeout_ms, void* user_data) -> void; /** * This function is called by libcurl to handle socket actions and update each sockets - * state within the EventLoop. + * state within the event_loop. * - * This function is a friend so it can access various EventLoop members to drive libcurl + * This function is a friend so it can access various event_loop members to drive libcurl * and libuv. * * @param curl The curl handle to handle its socket actions. * @param socket The raw socket being handled. * @param action The action to apply to the socket (e.g. POLL IN|OUT) - * @param user_data This is a pointer to this EventLoop object. - * @param socketp A pointer to the CurlContext if this is an existing request. This will + * @param user_data This is a pointer to this event_loop object. + * @param socketp A pointer to the curl_context if this is an existing request. This will * be a nullptr if this is a new request and will then be created. * @return Always returns zero. */ @@ -277,8 +285,8 @@ class EventLoop * This is used to make sure the m_timeout_timer and m_async handles are stopped and * the event loop can be closed. * - * This function is a friend so it can access the EventLoop flags to assist shutdown. - * Each handle.data pointer is set to this EventLoop object. + * This function is a friend so it can access the event_loop flags to assist shutdown. + * Each handle.data pointer is set to this event_loop object. * * @param handle The handle that is being closed. */ @@ -287,7 +295,7 @@ class EventLoop /** * This function is called by libuv when the m_timeout_timer expires. * - * This function is a friend so it can call checkActions() and have libcurl timeout + * This function is a friend so it can call check_actions() and have libcurl timeout * jobs that have expired. * * @param handle The timer object trigger, this will always be m_timeout_timer. @@ -295,7 +303,7 @@ class EventLoop friend auto on_uv_timeout_callback(uv_timer_t* handle) -> void; /** - * This function is called by libuv to call checkActions(socket, action) for a specific + * This function is called by libuv to call check_actions(socket, action) for a specific * socket and action (POLL IN|OUT). * @param req Libuv's context around the 'pollable' item, in this case the curl handle. * @param status The status of the poll item, a non-zero value implies an error. A zero value @@ -309,7 +317,7 @@ class EventLoop * This function is called by libuv when the m_async is triggered with a new request. * * This function is a friend so it can pull pending requests and inject them into - * the EventLoop. + * the event_loop. * * @param handle The async object trigger, this will always be m_async. */ @@ -318,8 +326,8 @@ class EventLoop friend auto on_uv_timesup_callback(uv_timer_t* handle) -> void; }; -template -auto EventLoop::StartRequests(Container requests) -> bool +template +auto event_loop::start_requests(container_type requests) -> bool { if (m_is_stopping.load(std::memory_order_acquire)) { diff --git a/inc/lift/executor.hpp b/inc/lift/executor.hpp index 3e1b858..d418322 100644 --- a/inc/lift/executor.hpp +++ b/inc/lift/executor.hpp @@ -10,7 +10,7 @@ namespace lift { class Request; -class EventLoop; +class event_loop; /** * This class's design is to encapsulate executing either a synchronous @@ -26,19 +26,19 @@ class EventLoop; * This class should never be used directly by the user of liblifthttp, * hence it has no public methods other than its destructor. */ -class Executor +class executor { - /// Allowed to create Executors and Timesup! - friend EventLoop; - /// Allowed to create Executors. + /// Allowed to create executor and Timesup! + friend event_loop; + /// Allowed to create executors. friend Request; public: - Executor(const Executor&) = delete; - Executor(Executor&&) = delete; - auto operator=(const Executor&) -> Executor& = delete; - auto operator=(Executor &&) -> Executor& = delete; - ~Executor(); + executor(const executor&) = delete; + executor(executor&&) = delete; + auto operator=(const executor&) -> executor& = delete; + auto operator=(executor &&) -> executor& = delete; + ~executor(); private: /// The curl handle to execute against. @@ -56,11 +56,11 @@ class Executor Request* m_request_sync{nullptr}; /// If async request the event loop executing this request. - EventLoop* m_event_loop{nullptr}; + event_loop* m_event_loop{nullptr}; /// If async request the pointer to the request. RequestPtr m_request_async{nullptr}; /// If the async request has a timeout set then this is the position to delete when completed. - std::optional::iterator> m_timeout_iterator{}; + std::optional::iterator> m_timeout_iterator{}; // Has the on complete callback been called already? bool m_on_complete_callback_called{false}; @@ -70,9 +70,9 @@ class Executor /// The HTTP response data. Response m_response{}; - static auto make_unique(EventLoop* event_loop) -> std::unique_ptr + static auto make_unique(event_loop* event_loop) -> std::unique_ptr { - return std::unique_ptr(new Executor{event_loop}); + return std::unique_ptr(new executor{event_loop}); } /** @@ -80,19 +80,19 @@ class Executor * @param request The synchronous request pointer. * @param share Curl share handle to use for this request. */ - Executor(Request* request, Share* share); + executor(Request* request, Share* share); /** * This constructor is used for executing an asynchronous requests. * @param event_loop The event loop that will execute this request. */ - Executor(EventLoop* event_loop); + executor(event_loop* event_loop); /** * @param request_ptr The asynchronous request to execute. * @param share Curl share handle to use for this request. */ - auto startAsync(RequestPtr request_ptr, Share* share) -> void; + auto start_async(RequestPtr request_ptr, Share* share) -> void; /** * Synchronously performs the request and returns the Response. @@ -110,13 +110,13 @@ class Executor * Copies all available HTTP response fields into the lift::Response from * the curl handle. */ - auto copyCurlToResponse() -> void; + auto copy_curl_to_response() -> void; /** * Sets the response object with appropriate times up values. * @param total_time The total time the request executed for. */ - auto setTimesupResponse(std::chrono::milliseconds total_time) -> void; + auto set_timesup_response(std::chrono::milliseconds total_time) -> void; auto reset() -> void; @@ -146,6 +146,6 @@ class Executor friend auto on_uv_timesup_callback(uv_timer_t* handle) -> void; }; -using ExecutorPtr = std::unique_ptr; +using executor_ptr = std::unique_ptr; } // namespace lift diff --git a/inc/lift/header.hpp b/inc/lift/header.hpp index 67317e0..537b631 100644 --- a/inc/lift/header.hpp +++ b/inc/lift/header.hpp @@ -5,11 +5,11 @@ namespace lift { -class Executor; +class executor; -class Header +class header { - friend Executor; + friend executor; public: /** @@ -17,23 +17,23 @@ class Header * @param name The name of the header. * @param value The value of the header. */ - explicit Header(std::string_view name, std::string_view value); + header(std::string_view name, std::string_view value); /** * Creates an owned header. * @param header_full The full ": " header field. */ - explicit Header(std::string header_full); + explicit header(std::string header_full); /** * @return The entire header, e.g. "Connection: Keep-Alive" */ - [[nodiscard]] auto HeaderFull() const -> const std::string& { return m_header; } + [[nodiscard]] auto data() const -> const std::string& { return m_header; } /** * @return The header's name. */ - [[nodiscard]] auto Name() const -> std::string_view + [[nodiscard]] auto name() const -> std::string_view { std::string_view name = m_header; name = name.substr(0, m_colon_pos); @@ -43,7 +43,7 @@ class Header /** * @return The header's value or empty if it doesn't have a value. */ - [[nodiscard]] auto Value() const -> std::string_view + [[nodiscard]] auto value() const -> std::string_view { std::string_view value = m_header; // Remove the name from the value. We know we made this string with ": " so skip two chars. @@ -51,13 +51,16 @@ class Header return value; } + friend auto operator<<(std::ostream& os, const header& h) -> std::ostream& + { + os << h.m_header; + return os; + } + private: /// The full header data. std::string m_header{}; - std::size_t m_colon_pos{0}; - - // Executor requires a char* to pass into the curlslist. - [[nodiscard]] auto headerFull() -> std::string& { return m_header; } + uint16_t m_colon_pos{0}; }; } // namespace lift diff --git a/inc/lift/http.hpp b/inc/lift/http.hpp index b3e0d2b..b7a8594 100644 --- a/inc/lift/http.hpp +++ b/inc/lift/http.hpp @@ -6,331 +6,330 @@ namespace lift::http { -extern const std::string METHOD_UNKNOWN; // = "UNKNOWN"s; -extern const std::string METHOD_GET; // = "GET"s; -extern const std::string METHOD_HEAD; // = "HEAD"s; -extern const std::string METHOD_POST; // = "POST"s; -extern const std::string METHOD_PUT; // = "PUT"s; -extern const std::string METHOD_DELETE; // = "DELETE"s; -extern const std::string METHOD_CONNECT; // = "CONNECT"s; -extern const std::string METHOD_OPTIONS; // = "OPTIONS"s; -extern const std::string METHOD_PATCH; // = "PATCH"s; - -enum class Method : uint8_t +inline const std::string method_unknown{"unknown"}; +inline const std::string method_get{"GET"}; +inline const std::string method_head{"HEAD"}; +inline const std::string method_post{"POST"}; +inline const std::string method_put{"PUT"}; +inline const std::string method_delete{"DELETE"}; +inline const std::string method_connect{"CONNECT"}; +inline const std::string method_options{"OPTIONS"}; +inline const std::string method_patch{"PATCH"}; + +enum class method : uint8_t { - UNKNOWN, - GET, - HEAD, - POST, - PUT, - DELETE, - CONNECT, - OPTIONS, - PATCH + unknown, + get, + head, + post, + put, + delete_t, + connect, + options, + patch }; -auto to_string(Method method) -> const std::string&; +auto to_string(method m) -> const std::string&; // Some liberty is taken on the version strings where they don't match the specification. -extern const std::string VERSION_UNKNOWN; // = "HTTP/unknown"s; -extern const std::string VERSION_USE_BEST; // = "HTTP/Best"s; -extern const std::string VERSION_V1_0; // = "HTTP/1.0"s; -extern const std::string VERSION_V1_1; // = "HTTP/1.1"s; -extern const std::string VERSION_V2_0; // = "HTTP/2.0"s; -extern const std::string VERSION_V2_0_TLS; //= "HTTP/2.0-TLS"s; -extern const std::string VERSION_V2_0_ONLY; // = "HTTP/2.0-only"s; +inline const std::string version_unknown{"HTTP/unknown"}; +inline const std::string version_use_best{"HTTP/Best"}; +inline const std::string version_v1_0{"HTTP/1.0"}; +inline const std::string version_v1_1{"HTTP/1.1"}; +inline const std::string version_v2_0{"HTTP/2.0"}; +inline const std::string version_v2_0_tls{"HTTP/2.0-TLS"}; +inline const std::string version_v2_0_only{"HTTP/2.0-only"}; -enum class Version : uint8_t +enum class version : uint8_t { - UNKNOWN = 255, + unknown = 255, /// Use the best version available. - USE_BEST = CURL_HTTP_VERSION_NONE, + use_best = CURL_HTTP_VERSION_NONE, /// Use HTTP 1.0. - V1_0 = CURL_HTTP_VERSION_1_0, + v1_0 = CURL_HTTP_VERSION_1_0, /// Use HTTP 1.1. - V1_1 = CURL_HTTP_VERSION_1_1, + v1_1 = CURL_HTTP_VERSION_1_1, /// Attempt HTTP 2 requests but fallback to 1.1 on failure. - V2_0 = CURL_HTTP_VERSION_2_0, + v2_0 = CURL_HTTP_VERSION_2_0, /// Attempt HTTP 2 over TLS (HTTPS) but fallback to 1.1 on failure. - V2_0_TLS = CURL_HTTP_VERSION_2TLS, + v2_0_tls = CURL_HTTP_VERSION_2TLS, /// Use HTTP 2.0 non-TLS with no fallback to 1.1. - V2_0_ONLY = CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE + v2_0_only = CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE }; -auto to_string(Version version) -> const std::string&; - -extern const std::string STATUS_CODE_HTTP_UNKNOWN; // = "UNKNOWN"s; -extern const std::string STATUS_CODE_HTTP_100_CONTINUE; // = "100 Continue"s; -extern const std::string STATUS_CODE_HTTP_101_SWITCHING_PROTOCOLS; // = "101 Switching Protocols"s; -extern const std::string STATUS_CODE_HTTP_102_PROCESSING; // = "102 Processing"s; -extern const std::string STATUS_CODE_HTTP_103_EARLY_HINTS; // = "103 Early Hints"s; - -extern const std::string STATUS_CODE_HTTP_200_OK; // = "200 OK"s; -extern const std::string STATUS_CODE_HTTP_201_CREATED; // = "201 Created"s; -extern const std::string STATUS_CODE_HTTP_202_ACCEPTED; // = "202 Accepted"s; -extern const std::string STATUS_CODE_HTTP_203_NON_AUTHORITATIVE_INFORMATION; // = "203 Non-Authoritative Information"s; -extern const std::string STATUS_CODE_HTTP_204_NO_CONTENT; // = "204 No Content"s; -extern const std::string STATUS_CODE_HTTP_205_RESET_CONTENT; // = "205 Reset Content"s; -extern const std::string STATUS_CODE_HTTP_206_PARTIAL_CONTENT; // = "206 Partial Content"s; -extern const std::string STATUS_CODE_HTTP_207_MULTI_STATUS; // = "207 Multi-Status"s; -extern const std::string STATUS_CODE_HTTP_208_ALREADY_REPORTED; // = "208 Already Reported"s; -extern const std::string STATUS_CODE_HTTP_226_IM_USED; // = "226 IM Used"s; - -extern const std::string STATUS_CODE_HTTP_300_MULTIPLE_CHOICES; // = "300 Multiple Choices"s; -extern const std::string STATUS_CODE_HTTP_301_MOVED_PERMANENTLY; // = "301 Moved Permanently"s; -extern const std::string STATUS_CODE_HTTP_302_FOUND; // = "302 Found"s; -extern const std::string STATUS_CODE_HTTP_303_SEE_OTHER; // = "303 See Other"s; -extern const std::string STATUS_CODE_HTTP_304_NOT_MODIFIED; // = "304 Not Modified"s; -extern const std::string STATUS_CODE_HTTP_305_USE_PROXY; // = "305 Use Proxy"s; -extern const std::string STATUS_CODE_HTTP_306_SWITCH_PROXY; // = "306 Switch Proxy"s; -extern const std::string STATUS_CODE_HTTP_307_TEMPORARY_REDIRECT; // = "307 Temporary Redirect"s; -extern const std::string STATUS_CODE_HTTP_308_PERMANENT_REDIRECT; // = "308 Permanent Redirect"s; - -extern const std::string STATUS_CODE_HTTP_400_BAD_REQUEST; // = "400 Bad Request"s; -extern const std::string STATUS_CODE_HTTP_401_UNAUTHORIZED; // = "401 Unauthorized"s; -extern const std::string STATUS_CODE_HTTP_402_PAYMENT_REQUIRED; // = "402 Payment Required"s; -extern const std::string STATUS_CODE_HTTP_403_FORBIDDEN; // = "403 Forbidden"s; -extern const std::string STATUS_CODE_HTTP_404_NOT_FOUND; // = "404 Not Found"s; -extern const std::string STATUS_CODE_HTTP_405_METHOD_NOT_ALLOWED; // = "405 Method Not Allowed"s; -extern const std::string STATUS_CODE_HTTP_406_NOT_ACCEPTABLE; // = "406 Not Acceptable"s; -extern const std::string STATUS_CODE_HTTP_407_PROXY_AUTHENTICATION_REQUIRED; // = "407 Proxy Authentication Required"s; -extern const std::string STATUS_CODE_HTTP_408_REQUEST_TIMEOUT; // = "408 Request Timeout"s; -extern const std::string STATUS_CODE_HTTP_409_CONFLICT; // = "409 Conflict"s; -extern const std::string STATUS_CODE_HTTP_410_GONE; // = "410 Gone"s; -extern const std::string STATUS_CODE_HTTP_411_LENGTH_REQUIRED; // = "411 Length Required"s; -extern const std::string STATUS_CODE_HTTP_412_PRECONDITION_FAILED; // = "412 Precondition Failed"s; -extern const std::string STATUS_CODE_HTTP_413_PAYLOAD_TOO_LARGE; // = "413 Payload Too Large"s; -extern const std::string STATUS_CODE_HTTP_414_URI_TOO_LONG; // = "414 URI Too Long"s; -extern const std::string STATUS_CODE_HTTP_415_UNSUPPORTED_MEDIA_TYPE; // = "415 Unsupported Media Type"s; -extern const std::string STATUS_CODE_HTTP_416_RANGE_NOT_SATISFIABLE; // = "416 Range Not Satisfiable"s; -extern const std::string STATUS_CODE_HTTP_417_EXPECTATION_FAILED; // = "417 Expectation Failed"s; -extern const std::string STATUS_CODE_HTTP_418_IM_A_TEAPOT; // = "418 I'm a teapot"s; -extern const std::string STATUS_CODE_HTTP_421_MISDIRECTED_REQUEST; // = "421 Misdirected Request"s; -extern const std::string STATUS_CODE_HTTP_422_UNPROCESSABLE_ENTITY; // = "422 Unprocessable Entity"s; -extern const std::string STATUS_CODE_HTTP_423_LOCKED; // = "423 Locked"s; -extern const std::string STATUS_CODE_HTTP_424_FAILED_DEPENDENCY; // = "424 Failed Dependency"s; -extern const std::string STATUS_CODE_HTTP_425_TOO_EARLY; // = "425 Too Early"s; -extern const std::string STATUS_CODE_HTTP_426_UPGRADE_REQUIRED; // = "426 Upgrade Required"s; -extern const std::string STATUS_CODE_HTTP_428_PRECONDITION_REQUIRED; // = "428 Precondition Required"s; -extern const std::string STATUS_CODE_HTTP_429_TOO_MANY_REQUESTS; // = "429 Too Many Requests"s; -extern const std::string - STATUS_CODE_HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE; // = "431 Request Header Fields Too Large"s; -extern const std::string STATUS_CODE_HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS; // = "451 Unavailable For Legal Reasons"s; - -extern const std::string STATUS_CODE_HTTP_500_INTERNAL_SERVER_ERROR; // = "500 Internal Server Error"s; -extern const std::string STATUS_CODE_HTTP_501_NOT_IMPLEMENTED; // = "501 Not Implemented"s; -extern const std::string STATUS_CODE_HTTP_502_BAD_GATEWAY; // = "502 Bad Gateway"s; -extern const std::string STATUS_CODE_HTTP_503_SERVICE_UNAVAILABLE; // = "503 Service Unavailable"s; -extern const std::string STATUS_CODE_HTTP_504_GATEWAY_TIMEOUT; // = "504 Gateway Timeout"s; -extern const std::string STATUS_CODE_HTTP_505_HTTP_VERSION_NOT_SUPPORTED; // = "505 HTTP Version Not Supported"s; -extern const std::string STATUS_CODE_HTTP_506_VARIANT_ALSO_NEGOTIATES; // = "506 Variant Also Negotiates"s; -extern const std::string STATUS_CODE_HTTP_507_INSUFFICIENT_STORAGE; // = "507 Insufficient Storage"s; -extern const std::string STATUS_CODE_HTTP_508_LOOP_DETECTED; // = "508 Loop Detected"s; -extern const std::string STATUS_CODE_HTTP_510_NOT_EXTENDED; // = "510 Not Extended"s; -extern const std::string - STATUS_CODE_HTTP_511_NETWORK_AUTHENTICATION_REQUIRED; // = "511 Network Authentication Required"s; +auto to_string(version v) -> const std::string&; + +inline const std::string status_code_http_unknown{"unknown"}; + +inline const std::string status_code_http_100_continue{"100 Continue"}; +inline const std::string status_code_http_101_switching_protocols{"101 Switching Protocols"}; +inline const std::string status_code_http_102_processing{"102 Processing"}; +inline const std::string status_code_http_103_early_hints{"103 Early Hints"}; + +inline const std::string status_code_http_200_ok{"200 OK"}; +inline const std::string status_code_http_201_created{"201 Created"}; +inline const std::string status_code_http_202_accepted{"202 Accepted"}; +inline const std::string status_code_http_203_non_authoritative_information{"203 Non-Authoritative Information"}; +inline const std::string status_code_http_204_no_content{"204 No Content"}; +inline const std::string status_code_http_205_reset_content{"205 Reset Content"}; +inline const std::string status_code_http_206_partial_content{"206 Partial Content"}; +inline const std::string status_code_http_207_multi_status{"207 Multi-Status"}; +inline const std::string status_code_http_208_already_reported{"208 Already Reported"}; +inline const std::string status_code_http_226_im_used{"226 IM Used"}; + +inline const std::string status_code_http_300_multiple_choices{"300 Multiple Choices"}; +inline const std::string status_code_http_301_moved_permanently{"301 Moved Permanently"}; +inline const std::string status_code_http_302_found{"302 Found"}; +inline const std::string status_code_http_303_see_other{"303 See Other"}; +inline const std::string status_code_http_304_not_modified{"304 Not Modified"}; +inline const std::string status_code_http_305_use_proxy{"305 Use Proxy"}; +inline const std::string status_code_http_306_switch_proxy{"306 Switch Proxy"}; +inline const std::string status_code_http_307_temporary_redirect{"307 Temporary Redirect"}; +inline const std::string status_code_http_308_permanent_redirect{"308 Permanent Redirect"}; + +inline const std::string status_code_http_400_bad_request{"400 Bad Request"}; +inline const std::string status_code_http_401_unauthorized{"401 Unauthorized"}; +inline const std::string status_code_http_402_payment_required{"402 Payment Required"}; +inline const std::string status_code_http_403_forbidden{"403 Forbidden"}; +inline const std::string status_code_http_404_not_found{"404 Not Found"}; +inline const std::string status_code_http_405_method_not_allowed{"405 Method Not Allowed"}; +inline const std::string status_code_http_406_not_acceptable{"406 Not Acceptable"}; +inline const std::string status_code_http_407_proxy_authentication_required{"407 Proxy Authentication Required"}; +inline const std::string status_code_http_408_request_timeout{"408 Request Timeout"}; +inline const std::string status_code_http_409_conflict{"409 Conflict"}; +inline const std::string status_code_http_410_gone{"410 Gone"}; +inline const std::string status_code_http_411_length_required{"411 Length Required"}; +inline const std::string status_code_http_412_precondition_failed{"412 Precondition Failed"}; +inline const std::string status_code_http_413_payload_too_large{"413 Payload Too Large"}; +inline const std::string status_code_http_414_uri_too_long{"414 URI Too Long"}; +inline const std::string status_code_http_415_unsupported_media_type{"415 Unsupported Media Type"}; +inline const std::string status_code_http_416_range_not_satisfiable{"416 Range Not Satisfiable"}; +inline const std::string status_code_http_417_expectation_failed{"417 Expectation Failed"}; +inline const std::string status_code_http_418_im_a_teapot{"418 I'm a teapot"}; +inline const std::string status_code_http_421_misdirected_request{"421 Misdirected Request"}; +inline const std::string status_code_http_422_unprocessable_entity{"422 Unprocessable Entity"}; +inline const std::string status_code_http_423_locked{"423 Locked"}; +inline const std::string status_code_http_424_failed_dependency{"424 Failed Dependency"}; +inline const std::string status_code_http_425_too_early{"425 Too Early"}; +inline const std::string status_code_http_426_upgrade_required{"426 Upgrade Required"}; +inline const std::string status_code_http_428_precondition_required{"428 Precondition Required"}; +inline const std::string status_code_http_429_too_many_requests{"429 Too Many Requests"}; +inline const std::string status_code_http_431_request_header_fields_too_large{"431 Request Header Fields Too Large"}; +inline const std::string status_code_http_451_unavailable_for_legal_reasons{"451 Unavailable For Legal Reasons"}; + +inline const std::string status_code_http_500_internal_server_error{"500 Internal Server Error"}; +inline const std::string status_code_http_501_not_implemented{"501 Not Implemented"}; +inline const std::string status_code_http_502_bad_gateway{"502 Bad Gateway"}; +inline const std::string status_code_http_503_service_unavailable{"503 Service Unavailable"}; +inline const std::string status_code_http_504_gateway_timeout{"504 Gateway Timeout"}; +inline const std::string status_code_http_505_http_version_not_supported{"505 HTTP Version Not Supported"}; +inline const std::string status_code_http_506_variant_also_negotiates{"506 Variant Also Negotiates"}; +inline const std::string status_code_http_507_insufficient_storage{"507 Insufficient Storage"}; +inline const std::string status_code_http_508_loop_detected{"508 Loop Detected"}; +inline const std::string status_code_http_510_not_extended{"510 Not Extended"}; +inline const std::string status_code_http_511_network_authentication_required{"511 Network Authentication Required"}; /** * https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */ -enum class StatusCode : uint16_t +enum class status_code : uint16_t { - HTTP_UNKNOWN = 0, - - HTTP_100_CONTINUE = 100, - HTTP_101_SWITCHING_PROTOCOLS = 101, - HTTP_102_PROCESSING = 102, - HTTP_103_EARLY_HINTS = 103, - - HTTP_200_OK = 200, - HTTP_201_CREATED = 201, - HTTP_202_ACCEPTED = 202, - HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203, - HTTP_204_NO_CONTENT = 204, - HTTP_205_RESET_CONTENT = 205, - HTTP_206_PARTIAL_CONTENT = 206, - HTTP_207_MULTI_STATUS = 207, - HTTP_208_ALREADY_REPORTED = 208, - HTTP_226_IM_USED = 226, - - HTTP_300_MULTIPLE_CHOICES = 300, - HTTP_301_MOVED_PERMANENTLY = 301, - HTTP_302_FOUND = 302, - HTTP_303_SEE_OTHER = 303, - HTTP_304_NOT_MODIFIED = 304, - HTTP_305_USE_PROXY = 305, + http_unknown = 0, + + http_100_continue = 100, + http_101_switching_protocols = 101, + http_102_processing = 102, + http_103_early_hints = 103, + + http_200_ok = 200, + http_201_created = 201, + http_202_accepted = 202, + http_203_non_authoritative_information = 203, + http_204_no_content = 204, + http_205_reset_content = 205, + http_206_partial_content = 206, + http_207_multi_status = 207, + http_208_already_reported = 208, + http_226_im_used = 226, + + http_300_multiple_choices = 300, + http_301_moved_permanently = 301, + http_302_found = 302, + http_303_see_other = 303, + http_304_not_modified = 304, + http_305_use_proxy = 305, /* * HTTP status code 306 is unused and reserved per RFC 7231 (https://tools.ietf.org/html/rfc7231#section-6.4.6), * but originally meant 'switch proxy', so leaving for backwards compatibility. */ - HTTP_306_SWITCH_PROXY = 306, - HTTP_307_TEMPORARY_REDIRECT = 307, - HTTP_308_PERMANENT_REDIRECT = 308, - - HTTP_400_BAD_REQUEST = 400, - HTTP_401_UNAUTHORIZED = 401, - HTTP_402_PAYMENT_REQUIRED = 402, - HTTP_403_FORBIDDEN = 403, - HTTP_404_NOT_FOUND = 404, - HTTP_405_METHOD_NOT_ALLOWED = 405, - HTTP_406_NOT_ACCEPTABLE = 406, - HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407, - HTTP_408_REQUEST_TIMEOUT = 408, - HTTP_409_CONFLICT = 409, - HTTP_410_GONE = 410, - HTTP_411_LENGTH_REQUIRED = 411, - HTTP_412_PRECONDITION_FAILED = 412, - HTTP_413_PAYLOAD_TOO_LARGE = 413, - HTTP_414_URI_TOO_LONG = 414, - HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415, - HTTP_416_RANGE_NOT_SATISFIABLE = 416, - HTTP_417_EXPECTATION_FAILED = 417, - HTTP_418_IM_A_TEAPOT = 418, - HTTP_421_MISDIRECTED_REQUEST = 421, - HTTP_422_UNPROCESSABLE_ENTITY = 422, - HTTP_423_LOCKED = 423, - HTTP_424_FAILED_DEPENDENCY = 424, - HTTP_425_TOO_EARLY = 425, // https://tools.ietf.org/html/rfc8470#section-5.2 - HTTP_426_UPGRADE_REQUIRED = 426, - HTTP_428_PRECONDITION_REQUIRED = 428, // https://tools.ietf.org/html/rfc6585 - HTTP_429_TOO_MANY_REQUESTS = 429, - HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431, - HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451, - - HTTP_500_INTERNAL_SERVER_ERROR = 500, - HTTP_501_NOT_IMPLEMENTED = 501, - HTTP_502_BAD_GATEWAY = 502, - HTTP_503_SERVICE_UNAVAILABLE = 503, - HTTP_504_GATEWAY_TIMEOUT = 504, - HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505, - HTTP_506_VARIANT_ALSO_NEGOTIATES = 506, - HTTP_507_INSUFFICIENT_STORAGE = 507, - HTTP_508_LOOP_DETECTED = 508, - HTTP_510_NOT_EXTENDED = 510, - HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511 + http_306_switch_proxy = 306, + http_307_temporary_redirect = 307, + http_308_permanent_redirect = 308, + + http_400_bad_request = 400, + http_401_unauthorized = 401, + http_402_payment_required = 402, + http_403_forbidden = 403, + http_404_not_found = 404, + http_405_method_not_allowed = 405, + http_406_not_acceptable = 406, + http_407_proxy_authentication_required = 407, + http_408_request_timeout = 408, + http_409_conflict = 409, + http_410_gone = 410, + http_411_length_required = 411, + http_412_precondition_failed = 412, + http_413_payload_too_large = 413, + http_414_uri_too_long = 414, + http_415_unsupported_media_type = 415, + http_416_range_not_satisfiable = 416, + http_417_expectation_failed = 417, + http_418_im_a_teapot = 418, + http_421_misdirected_request = 421, + http_422_unprocessable_entity = 422, + http_423_locked = 423, + http_424_failed_dependency = 424, + http_425_too_early = 425, // https://tools.ietf.org/html/rfc8470#section-5.2 + http_426_upgrade_required = 426, + http_428_precondition_required = 428, // https://tools.ietf.org/html/rfc6585 + http_429_too_many_requests = 429, + http_431_request_header_fields_too_large = 431, + http_451_unavailable_for_legal_reasons = 451, + + http_500_internal_server_error = 500, + http_501_not_implemented = 501, + http_502_bad_gateway = 502, + http_503_service_unavailable = 503, + http_504_gateway_timeout = 504, + http_505_http_version_not_supported = 505, + http_506_variant_also_negotiates = 506, + http_507_insufficient_storage = 507, + http_508_loop_detected = 508, + http_510_not_extended = 510, + http_511_network_authentication_required = 511 }; /** * @param code The status code to retrieve its string representation. * @return string */ -auto to_string(StatusCode code) -> const std::string&; +auto to_string(status_code code) -> const std::string&; /** * @param code The HTTP status code as an int. * @return StatusCode */ -auto to_enum(int32_t code) -> StatusCode; - -extern const std::string CONTENT_TYPE_UNKNOWN; // = "UNKNOWN"s; - -extern const std::string CONTENT_TYPE_NO_CONTENT; // = ""s; - -extern const std::string CONTENT_TYPE_TEXT_CSS; // = "text/css"s; -extern const std::string CONTENT_TYPE_TEXT_CSV; // = "text/csv"s; -extern const std::string CONTENT_TYPE_TEXT_HTML; // = "text/html"s; -extern const std::string CONTENT_TYPE_TEXT_PLAIN; // = "text/plain"s; -extern const std::string CONTENT_TYPE_TEXT_XML; // = "text/xml"s; - -extern const std::string CONTENT_TYPE_IMAGE_GIF; // = "image/gif"s; -extern const std::string CONTENT_TYPE_IMAGE_JPEG; // = "image/jpeg"s; -extern const std::string CONTENT_TYPE_IMAGE_PNG; // = "image/png"s; -extern const std::string CONTENT_TYPE_IMAGE_TIFF; // = "image/tiff"s; -extern const std::string CONTENT_TYPE_IMAGE_X_ICON; // = "image/x-icon"s; -extern const std::string CONTENT_TYPE_IMAGE_SVG_XML; // = "image/svg+xml"s; - -extern const std::string CONTENT_TYPE_VIDEO_MPEG; // = "video/mpeg"s; -extern const std::string CONTENT_TYPE_VIDEO_MP4; // = "video/mp4"s; -extern const std::string CONTENT_TYPE_VIDEO_X_FLV; // = "video/x-flv"s; -extern const std::string CONTENT_TYPE_VIDEO_WEBM; // = "video/webm"s; - -extern const std::string CONTENT_TYPE_MULTIPART_MIXED; // = "multipart/mixed"s; -extern const std::string CONTENT_TYPE_MULTIPART_ALTERNATIVE; // = "multipart/alternative"s; -extern const std::string CONTENT_TYPE_MULTIPART_RELATED; // = "multipart/related"s; -extern const std::string CONTENT_TYPE_MULTIPART_FORM_DATA; // = "multipart/form-data"s; - -extern const std::string CONTENT_TYPE_AUDIO_MPEG; // = "audio/mpeg"s; -extern const std::string CONTENT_TYPE_AUDIO_X_MS_WMA; // = "audio/x-ms-wma"s; -extern const std::string CONTENT_TYPE_AUDIO_X_WAV; // = "audio/x-wav"s; - -extern const std::string CONTENT_TYPE_APPLICATION_JAVASCRIPT; // = "application/javascript"s; -extern const std::string CONTENT_TYPE_APPLICATION_OCTET_STREAM; // = "application/octet-stream"s; -extern const std::string CONTENT_TYPE_APPLICATION_OGG; // = "application/ogg"s; -extern const std::string CONTENT_TYPE_APPLICATION_PDF; // = "application/pdf"s; -extern const std::string CONTENT_TYPE_APPLICATION_XHTML_XML; // = "application/xhtml+xml"s; -extern const std::string CONTENT_TYPE_APPLICATION_X_SHOCKWAVE_FLASH; // = "application/x-shockwave-flash"s; -extern const std::string CONTENT_TYPE_APPLICATION_JSON; // = "application/json"s; -extern const std::string CONTENT_TYPE_APPLICATION_LD_JSON; // = "application/ld+json"s; -extern const std::string CONTENT_TYPE_APPLICATION_XML; // = "application/xml"s; -extern const std::string CONTENT_TYPE_APPLICATION_ZIP; // = "application/zip"s; -extern const std::string CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED; // = "application/x-www-form-urlencoded"s; +auto to_enum(uint16_t code) -> status_code; + +inline const std::string content_type_unknown{"unknown"}; + +inline const std::string content_type_no_content{""}; + +inline const std::string content_type_text_css{"text/css"}; +inline const std::string content_type_text_csv{"text/csv"}; +inline const std::string content_type_text_html{"text/html"}; +inline const std::string content_type_text_plain{"text/plain"}; +inline const std::string content_type_text_xml{"text/xml"}; + +inline const std::string content_type_image_gif{"image/gif"}; +inline const std::string content_type_image_jpeg{"image/jpeg"}; +inline const std::string content_type_image_png{"image/png"}; +inline const std::string content_type_image_tiff{"image/tiff"}; +inline const std::string content_type_image_x_icon{"image/x-icon"}; +inline const std::string content_type_image_svg_xml{"image/svg+xml"}; + +inline const std::string content_type_video_mpeg{"video/mpeg"}; +inline const std::string content_type_video_mp4{"video/mp4"}; +inline const std::string content_type_video_x_flv{"video/x-flv"}; +inline const std::string content_type_video_webm{"video/webm"}; + +inline const std::string content_type_multipart_mixed{"multipart/mixed"}; +inline const std::string content_type_multipart_alternative{"multipart/alternative"}; +inline const std::string content_type_multipart_related{"multipart/related"}; +inline const std::string content_type_multipart_form_data{"multipart/form-data"}; + +inline const std::string content_type_audio_mpeg{"audio/mpeg"}; +inline const std::string content_type_audio_x_ms_wma{"audio/x-ms-wma"}; +inline const std::string content_type_audio_x_wav{"audio/x-wav"}; + +inline const std::string content_type_application_javascript{"application/javascript"}; +inline const std::string content_type_application_octet_stream{"application/octet-stream"}; +inline const std::string content_type_application_ogg{"application/ogg"}; +inline const std::string content_type_application_pdf{"application/pdf"}; +inline const std::string content_type_application_xhtml_xml{"application/xhtml+xml"}; +inline const std::string content_type_application_x_shockwave_flash{"application/x-shockwave-flash"}; +inline const std::string content_type_application_json{"application/json"}; +inline const std::string content_type_application_ld_json{"application/ld+json"}; +inline const std::string content_type_application_xml{"application/xml"}; +inline const std::string content_type_application_zip{"application/zip"}; +inline const std::string content_type_application_x_www_form_urlencoded{"application/x-www-form-urlencoded"}; /** * HTTP 'Content-Type" types. Can be extended to support * as many values as needed. The design here is to reduce * string copies/manipulation. */ -enum class ContentType : uint16_t +enum class content_type : uint16_t { - UNKNOWN, - - NO_CONTENT, - - TEXT_CSS, - TEXT_CSV, - TEXT_HTML, - TEXT_PLAIN, - TEXT_XML, - - IMAGE_GIF, - IMAGE_JPEG, - IMAGE_PNG, - IMAGE_TIFF, - IMAGE_X_ICON, - IMAGE_SVG_XML, - - VIDEO_MPEG, - VIDEO_MP4, - VIDEO_X_FLV, - VIDEO_WEBM, - - MULTIPART_MIXED, - MULTIPART_ALTERNATIVE, - MULTIPART_RELATED, - MULTIPART_FORM_DATA, - - AUDIO_MPEG, - AUDIO_X_MS_WMA, - AUDIO_X_WAV, - - APPLICATION_JAVASCRIPT, - APPLICATION_OCTET_STREAM, - APPLICATION_OGG, - APPLICATION_PDF, - APPLICATION_XHTML_XML, - APPLICATION_X_SHOCKWAVE_FLASH, - APPLICATION_JSON, - APPLICATION_LD_JSON, - APPLICATION_XML, - APPLICATION_ZIP, - APPLICATION_X_WWW_FORM_URLENCODED + unknown, + + no_content, + + text_css, + text_csv, + text_html, + text_plain, + text_xml, + + image_gif, + image_jpeg, + image_png, + image_tiff, + image_x_icon, + image_svg_xml, + + video_mpeg, + video_mp4, + video_x_flv, + video_webm, + + multipart_mixed, + multipart_alternative, + multipart_related, + multipart_form_data, + + audio_mpeg, + audio_x_ms_wma, + audio_x_wav, + + application_javascript, + application_octet_stream, + application_ogg, + application_pdf, + application_xhtml_xml, + application_x_shockwave_flash, + application_json, + application_ld_json, + application_xml, + application_zip, + application_x_www_form_urlencoded }; -auto to_string(ContentType content_type) -> const std::string&; +auto to_string(content_type ct) -> const std::string&; -extern const std::string CONNECTION_TYPE_UNKNOWN; // = "UNKNOWN"s; -extern const std::string CONNECTION_TYPE_CLOSE; // = "close"s; -extern const std::string CONNECTION_TYPE_KEEP_ALIVE; // = "keep-alive"s; -extern const std::string CONNECTION_TYPE_UPGRADE; // = "upgrade"s; +inline const std::string connection_type_unknown{"unknown"}; +inline const std::string connection_type_close{"close"}; +inline const std::string connection_type_keep_alive{"keep-alive"}; +inline const std::string connection_type_upgrade{"upgrade"}; -enum class ConnectionType : uint8_t +enum class connection_type : uint8_t { - CLOSE, - KEEP_ALIVE, - UPGRADE + close, + keep_alive, + upgrade }; -auto to_string(ConnectionType connection_type) -> const std::string&; +auto to_string(connection_type ct) -> const std::string&; } // namespace lift::http diff --git a/inc/lift/request.hpp b/inc/lift/request.hpp index 1dcde30..757aff6 100644 --- a/inc/lift/request.hpp +++ b/inc/lift/request.hpp @@ -16,8 +16,8 @@ namespace lift { -class EventLoop; -class Executor; +class event_loop; +class executor; enum class SslCertificateType { @@ -62,8 +62,8 @@ auto to_string(SslCertificateType type) -> const std::string&; class Request { - friend EventLoop; - friend Executor; + friend event_loop; + friend executor; public: /** @@ -198,22 +198,22 @@ class Request /** * @return The HTTP method this request will use. */ - auto Method() const -> http::Method { return m_method; } + auto Method() const -> http::method { return m_method; } /** * @param method The HTTP method this request should use. */ - auto Method(http::Method method) -> void { m_method = method; } + auto Method(http::method method) -> void { m_method = method; } /** * @return The HTTP version this request will use. */ - auto Version() const -> http::Version { return m_version; } + auto Version() const -> http::version { return m_version; } /** * @param version The HTTP version this request should use. */ - auto Version(http::Version version) -> void { m_version = version; } + auto Version(http::version version) -> void { m_version = version; } /** * @return Is the HTTP request automatically following redirects? @@ -378,7 +378,7 @@ class Request * allows for the user to manually remove them. * @param name The name of the header, e.g. 'Accept' or 'Expect'. */ - auto RemoveHeader(std::string_view name) -> void { Header(name, std::string_view{}); } + auto RemoveHeader(std::string_view name) -> void { header(name, std::string_view{}); } /** * Adds a request header with its value. * @param name The name of the header, e.g. 'Connection'. @@ -390,7 +390,7 @@ class Request * @return The current list of headers added to this request. Note that if more headers are added * the Header classes Name() and Value() string_views might become invalidated. */ - auto Headers() const -> const std::vector& { return m_request_headers; } + auto Headers() const -> const std::vector& { return m_request_headers; } /** * Clears the current set of headers for this request. @@ -452,9 +452,9 @@ class Request /// The URL. std::string m_url{}; /// The HTTP request method. - http::Method m_method{http::Method::GET}; + http::method m_method{http::method::get}; /// The HTTP version to use for this request. - http::Version m_version{http::Version::USE_BEST}; + http::version m_version{http::version::use_best}; /// Should this request automatically follow redirects? bool m_follow_redirects{true}; /// How many redirects should be followed? -1 infinite, 0 none, . @@ -480,7 +480,7 @@ class Request /// A set of host:port to ip addresses that will be resolved before DNS. std::vector m_resolve_hosts{}; /// The request headers preformatted into the curl "Header: value\0" format. - std::vector m_request_headers{}; + std::vector m_request_headers{}; /// The POST request body data, mutually exclusive with MimeField requests. bool m_request_data_set{false}; std::string m_request_data{}; diff --git a/inc/lift/resolve_host.hpp b/inc/lift/resolve_host.hpp index 95d8093..6f202c9 100644 --- a/inc/lift/resolve_host.hpp +++ b/inc/lift/resolve_host.hpp @@ -4,12 +4,12 @@ namespace lift { -class Executor; +class executor; class ResolveHost { /// For getCurlFormattedResolveHost(). - friend Executor; + friend executor; public: /** diff --git a/inc/lift/response.hpp b/inc/lift/response.hpp index 99e66d8..b9dee75 100644 --- a/inc/lift/response.hpp +++ b/inc/lift/response.hpp @@ -14,13 +14,13 @@ namespace lift { -class EventLoop; -class Executor; +class event_loop; +class executor; class Response { - friend EventLoop; - friend Executor; + friend event_loop; + friend executor; public: Response(); @@ -44,17 +44,17 @@ class Response /** * @return The HTTP version of the response. */ - auto Version() const -> http::Version { return m_version; } + auto Version() const -> http::version { return m_version; } /** * @return The HTTP response status code. */ - [[nodiscard]] auto StatusCode() const -> http::StatusCode { return m_status_code; } + [[nodiscard]] auto StatusCode() const -> http::status_code { return m_status_code; } /** * @return The HTTP response headers. */ - [[nodiscard]] auto Headers() const -> const std::vector
& { return m_headers; } + [[nodiscard]] auto Headers() const -> const std::vector
& { return m_headers; } /** * @return The HTTP download payload. @@ -88,18 +88,18 @@ class Response /// Ordered by sizeof() since response gets std::moved()'ed back to the client. /// The response headers. - std::vector
m_headers{}; + std::vector
m_headers{}; /// The response data if any. std::vector m_data{}; /// The total time in milliseconds to execute the request, stored as uint32_t since that is enough /// time for 49~ days and saves 4 bytes from std::chrono::milliseconds. uint32_t m_total_time{0}; /// The HTTP response status code. - lift::http::StatusCode m_status_code{lift::http::StatusCode::HTTP_UNKNOWN}; + lift::http::status_code m_status_code{lift::http::status_code::http_unknown}; /// The status of this HTTP request. lift::LiftStatus m_lift_status{lift::LiftStatus::BUILDING}; /// The HTTP response version. - http::Version m_version{http::Version::V1_1}; + http::version m_version{http::version::v1_1}; /// The number of times attempted to connect to the remote server. uint8_t m_num_connects{0}; /// The number of redirects traversed while processing the request. @@ -119,7 +119,7 @@ class Response curl_off_t upload_total_bytes, curl_off_t upload_now_bytes) -> int; - /// libuv will call this function when the StartRequest() function is called. + /// libuv will call this function when the start_request() function is called. friend auto on_uv_requests_accept_async(uv_async_t* handle) -> void; /// For Timesup. diff --git a/inc/lift/share.hpp b/inc/lift/share.hpp index c54eb79..a55e8cb 100644 --- a/inc/lift/share.hpp +++ b/inc/lift/share.hpp @@ -8,7 +8,7 @@ namespace lift { -class Executor; +class executor; enum class ShareOptions : uint64_t { @@ -33,7 +33,7 @@ enum class ShareOptions : uint64_t class Share { - friend Executor; + friend executor; public: /** diff --git a/src/event_loop.cpp b/src/event_loop.cpp index 015d934..df82407 100644 --- a/src/event_loop.cpp +++ b/src/event_loop.cpp @@ -13,56 +13,56 @@ using namespace std::chrono_literals; namespace lift { -template -static auto uv_type_cast(I* i) -> O* +template +static auto uv_type_cast(input_type* i) -> output_type* { auto* void_ptr = static_cast(i); - return static_cast(void_ptr); + return static_cast(void_ptr); } -class CurlContext +class curl_context { public: - explicit CurlContext(EventLoop& event_loop) : m_event_loop(event_loop) { m_poll_handle.data = this; } + explicit curl_context(event_loop& event_loop) : m_event_loop(event_loop) { m_poll_handle.data = this; } - ~CurlContext() = default; + ~curl_context() = default; - CurlContext(const CurlContext&) = delete; - CurlContext(CurlContext&&) = delete; - auto operator=(const CurlContext&) noexcept -> CurlContext& = delete; - auto operator=(CurlContext&&) noexcept -> CurlContext& = delete; + curl_context(const curl_context&) = delete; + curl_context(curl_context&&) = delete; + auto operator=(const curl_context&) noexcept -> curl_context& = delete; + auto operator=(curl_context&&) noexcept -> curl_context& = delete; - auto Init(uv_loop_t* uv_loop, curl_socket_t sock_fd) -> void + auto init(uv_loop_t* uv_loop, curl_socket_t sock_fd) -> void { m_sock_fd = sock_fd; uv_poll_init(uv_loop, &m_poll_handle, m_sock_fd); } - auto Close() + auto close() { uv_poll_stop(&m_poll_handle); /** * uv requires us to jump through a few hoops before we can delete ourselves. */ - uv_close(uv_type_cast(&m_poll_handle), CurlContext::on_close); + uv_close(uv_type_cast(&m_poll_handle), curl_context::on_close); } - inline auto GetEventLoop() -> EventLoop& { return m_event_loop; } - inline auto GetUvPollHandle() -> uv_poll_t& { return m_poll_handle; } - inline auto GetCurlSockFd() -> curl_socket_t { return m_sock_fd; } + inline auto lift_event_loop() -> event_loop& { return m_event_loop; } + inline auto uv_poll_handle() -> uv_poll_t& { return m_poll_handle; } + inline auto curl_sock_fd() -> curl_socket_t { return m_sock_fd; } static auto on_close(uv_handle_t* handle) -> void { - auto* curl_context = static_cast(handle->data); + auto* cc = static_cast(handle->data); /** * uv has signaled that it is finished with the m_poll_handle, * we can now safely tell the event loop to re-use this curl context. */ - curl_context->m_event_loop.m_curl_context_ready.emplace_back(curl_context); + cc->lift_event_loop().m_curl_context_ready.emplace_back(cc); } private: - EventLoop& m_event_loop; + event_loop& m_event_loop; uv_poll_t m_poll_handle{}; curl_socket_t m_sock_fd{CURL_SOCKET_BAD}; }; @@ -81,22 +81,18 @@ auto on_uv_requests_accept_async(uv_async_t* handle) -> void; auto on_uv_timesup_callback(uv_timer_t* handle) -> void; -EventLoop::EventLoop( - std::optional reserve_connections, - std::optional max_connections, - std::optional connect_timeout, - std::vector resolve_hosts, - SharePtr share_ptr) - : m_connect_timeout(std::move(connect_timeout)), +event_loop::event_loop(options opts) + : m_connect_timeout(std::move(opts.connect_timeout)), m_curl_context_ready(), - m_resolve_hosts(std::move(resolve_hosts)), - m_share_ptr(std::move(share_ptr)) + m_resolve_hosts(std::move(opts.resolve_hosts.value_or(std::vector{}))), + m_share_ptr(std::move(opts.share_ptr)), + m_on_thread_callback(std::move(opts.on_thread_callback)) { global_init(); - for (std::size_t i = 0; i < reserve_connections.value_or(0); ++i) + for (std::size_t i = 0; i < opts.reserve_connections.value_or(0); ++i) { - m_executors.push_back(Executor::make_unique(this)); + m_executors.push_back(executor::make_unique(this)); } uv_loop_init(&m_uv_loop); @@ -115,29 +111,26 @@ EventLoop::EventLoop( curl_multi_setopt(m_cmh, CURLMOPT_TIMERFUNCTION, curl_start_timeout); curl_multi_setopt(m_cmh, CURLMOPT_TIMERDATA, this); - if (max_connections.has_value()) + if (opts.max_connections.has_value()) { - curl_multi_setopt(m_cmh, CURLMOPT_MAXCONNECTS, static_cast(max_connections.value())); + curl_multi_setopt(m_cmh, CURLMOPT_MAXCONNECTS, static_cast(opts.max_connections.value())); } m_background_thread = std::thread{[this] { run(); }}; /** - * Wait for the thread to spin-up and run the event loop, + * Spin wait for the thread to spin-up and run the event loop, * this means when the constructor returns the user can start adding requests * immediately without waiting. */ - while (!IsRunning()) - { - std::this_thread::sleep_for(1ms); - } + while (!is_running()) {} } -EventLoop::~EventLoop() +event_loop::~event_loop() { m_is_stopping.exchange(true, std::memory_order_release); - while (ActiveRequestCount() > 0) + while (!empty()) { std::this_thread::sleep_for(1ms); } @@ -163,22 +156,7 @@ EventLoop::~EventLoop() global_cleanup(); } -auto EventLoop::IsRunning() -> bool -{ - return m_is_running.load(std::memory_order_acquire); -} - -auto EventLoop::Stop() -> void -{ - m_is_stopping.exchange(true, std::memory_order_release); -} - -auto EventLoop::ActiveRequestCount() const -> uint64_t -{ - return m_active_request_count.load(std::memory_order_relaxed); -} - -auto EventLoop::StartRequest(RequestPtr request_ptr) -> bool +auto event_loop::start_request(RequestPtr request_ptr) -> bool { if (request_ptr == nullptr) { @@ -202,27 +180,29 @@ auto EventLoop::StartRequest(RequestPtr request_ptr) -> bool return true; } -auto EventLoop::run() -> void +auto event_loop::run() -> void { - m_tid = syscall(SYS_gettid); - /** - * Note that its possible to use m_background_thread.native_handle() however - * gdb and other debugging tools have an issue reporting the thread id correctly, so - * for now its better to call pthread_self(). - */ - m_native_handle = pthread_self(); + if (m_on_thread_callback != nullptr) + { + m_on_thread_callback(); + } m_is_running.exchange(true, std::memory_order_release); uv_run(&m_uv_loop, UV_RUN_DEFAULT); m_is_running.exchange(false, std::memory_order_release); + + if (m_on_thread_callback != nullptr) + { + m_on_thread_callback(); + } } -auto EventLoop::checkActions() -> void +auto event_loop::check_actions() -> void { - checkActions(CURL_SOCKET_TIMEOUT, 0); + check_actions(CURL_SOCKET_TIMEOUT, 0); } -auto EventLoop::checkActions(curl_socket_t socket, int event_bitmask) -> void +auto event_loop::check_actions(curl_socket_t socket, int event_bitmask) -> void { int running_handles = 0; CURLMcode curl_code = CURLM_OK; @@ -241,54 +221,54 @@ auto EventLoop::checkActions(curl_socket_t socket, int event_bitmask) -> void CURL* easy_handle = message->easy_handle; CURLcode easy_result = message->data.result; - Executor* executor = nullptr; - curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, &executor); - ExecutorPtr executor_ptr{executor}; + executor* exe = nullptr; + curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, &exe); + executor_ptr executor_ptr{exe}; curl_multi_remove_handle(m_cmh, easy_handle); - completeRequestNormal(*executor_ptr.get(), Executor::convert(easy_result)); + complete_request_normal(*executor_ptr.get(), executor::convert(easy_result)); - returnExecutor(std::move(executor_ptr)); + return_executor(std::move(executor_ptr)); } } } -auto EventLoop::completeRequestNormal(Executor& executor, LiftStatus status) -> void +auto event_loop::complete_request_normal(executor& exe, LiftStatus status) -> void { - if (executor.m_on_complete_callback_called == false) + if (exe.m_on_complete_callback_called == false) { - auto& on_complete_handler = executor.m_request_async->m_on_complete_handler; + auto& on_complete_handler = exe.m_request_async->m_on_complete_handler; if (on_complete_handler != nullptr) { - executor.m_on_complete_callback_called = true; - executor.m_response.m_lift_status = status; - executor.copyCurlToResponse(); - removeTimeout(executor); + exe.m_on_complete_callback_called = true; + exe.m_response.m_lift_status = status; + exe.copy_curl_to_response(); + remove_timeout(exe); - on_complete_handler(std::move(executor.m_request_async), std::move(executor.m_response)); + on_complete_handler(std::move(exe.m_request_async), std::move(exe.m_response)); } } m_active_request_count.fetch_sub(1, std::memory_order_relaxed); } -auto EventLoop::completeRequestTimeout(Executor& executor) -> void +auto event_loop::complete_request_timeout(executor& exe) -> void { - auto& on_complete_handler = executor.m_request_async->m_on_complete_handler; + auto& on_complete_handler = exe.m_request_async->m_on_complete_handler; // Call on complete if it exists and hasn't been called before. - if (executor.m_on_complete_callback_called == false && on_complete_handler != nullptr) + if (exe.m_on_complete_callback_called == false && on_complete_handler != nullptr) { - executor.m_on_complete_callback_called = true; - executor.m_response.m_lift_status = lift::LiftStatus::TIMEOUT; - executor.setTimesupResponse(executor.m_request->Timeout().value()); + exe.m_on_complete_callback_called = true; + exe.m_response.m_lift_status = lift::LiftStatus::TIMEOUT; + exe.set_timesup_response(exe.m_request->Timeout().value()); // Removing the timesup is done in the uv timesup callback so it can prune // every single item that has timesup'ed. Doing it here will cause 1 item // per loop iteration to be removed if there are multiple items with the same timesup value. - // removeTimeout(executor); + // remove_timeout(exe); // IMPORTANT! Copying here is required _OR_ shared ownership must be added as libcurl // maintains char* type pointers into the request data structure. There is no guarantee @@ -296,20 +276,20 @@ auto EventLoop::completeRequestTimeout(Executor& executor) -> void // own timeout. Shared ownership would most likely require locks as well since any curl // handle still in the curl multi handle could be mutated by curl at any moment, copying // seems far safer. - auto copy_ptr = std::make_unique(*executor.m_request_async); + auto copy_ptr = std::make_unique(*exe.m_request_async); - on_complete_handler(std::move(copy_ptr), std::move(executor.m_response)); + on_complete_handler(std::move(copy_ptr), std::move(exe.m_response)); } // Lift timeouts do not trigger an active request count drop. } -auto EventLoop::addTimeout(Executor& executor) -> void +auto event_loop::add_timeout(executor& exe) -> void { - auto* request = executor.m_request; + auto* request = exe.m_request; if (request->Timeout().has_value()) { - auto timeout = executor.m_request->Timeout().value(); + auto timeout = exe.m_request->Timeout().value(); std::optional connect_timeout{std::nullopt}; if (request->ConnectTimeout().has_value()) @@ -326,46 +306,53 @@ auto EventLoop::addTimeout(Executor& executor) -> void { if (connect_timeout.value() > timeout) { - auto now = uv_now(&m_uv_loop); - TimePoint time_point = now + static_cast(timeout.count()); - executor.m_timeout_iterator = m_timeouts.emplace(time_point, &executor); + auto now = uv_now(&m_uv_loop); + time_point tp = now + static_cast(timeout.count()); + exe.m_timeout_iterator = m_timeouts.emplace(tp, &exe); - updateTimeouts(); + update_timeouts(); curl_easy_setopt( - executor.m_curl_handle, CURLOPT_TIMEOUT_MS, static_cast(connect_timeout.value().count())); + exe.m_curl_handle, CURLOPT_TIMEOUT_MS, static_cast(connect_timeout.value().count())); } else { // If the user set a longer timeout on the individual request, just let curl handle it. - curl_easy_setopt(executor.m_curl_handle, CURLOPT_TIMEOUT_MS, static_cast(timeout.count())); + curl_easy_setopt(exe.m_curl_handle, CURLOPT_TIMEOUT_MS, static_cast(timeout.count())); } } else { - curl_easy_setopt(executor.m_curl_handle, CURLOPT_TIMEOUT_MS, static_cast(timeout.count())); + curl_easy_setopt(exe.m_curl_handle, CURLOPT_TIMEOUT_MS, static_cast(timeout.count())); } } } -auto EventLoop::removeTimeout(Executor& executor) -> std::multimap::iterator +auto event_loop::remove_timeout(executor& exe) -> std::multimap::iterator { - if (executor.m_timeout_iterator.has_value()) + if (exe.m_timeout_iterator.has_value()) { - auto iter = executor.m_timeout_iterator.value(); + auto iter = exe.m_timeout_iterator.value(); auto next = m_timeouts.erase(iter); - executor.m_timeout_iterator.reset(); + exe.m_timeout_iterator.reset(); // Anytime an item is removed the timesup timer might need to be adjusted. - updateTimeouts(); + update_timeouts(); return next; } - - return m_timeouts.end(); // is this behavior ok? + else + { + // This is probably a logic error if the passed in executor doesn't + // have a timeout, we'll update the timeouts to be sture we are triggering + // at the correct next timeout and return the end() so as not to go into + // an infinite loop if this is the first item. + update_timeouts(); + return m_timeouts.end(); + } } -auto EventLoop::updateTimeouts() -> void +auto event_loop::update_timeouts() -> void { // TODO only change if it needs to change, this will probably require // an iterator to the item just added or removed to properly skip @@ -395,9 +382,9 @@ auto EventLoop::updateTimeouts() -> void } } -auto EventLoop::acquireExecutor() -> std::unique_ptr +auto event_loop::acquire_executor() -> std::unique_ptr { - std::unique_ptr executor_ptr{nullptr}; + std::unique_ptr executor_ptr{nullptr}; if (!m_executors.empty()) { @@ -407,13 +394,13 @@ auto EventLoop::acquireExecutor() -> std::unique_ptr if (executor_ptr == nullptr) { - executor_ptr = Executor::make_unique(this); + executor_ptr = executor::make_unique(this); } return executor_ptr; } -auto EventLoop::returnExecutor(std::unique_ptr executor_ptr) -> void +auto event_loop::return_executor(std::unique_ptr executor_ptr) -> void { executor_ptr->reset(); m_executors.push_back(std::move(executor_ptr)); @@ -421,69 +408,69 @@ auto EventLoop::returnExecutor(std::unique_ptr executor_ptr) -> void auto curl_start_timeout(CURLM* /*cmh*/, long timeout_ms, void* user_data) -> void { - auto* event_loop = static_cast(user_data); + auto* el = static_cast(user_data); // Stop the current timer regardless. - uv_timer_stop(&event_loop->m_uv_timer_curl); + uv_timer_stop(&el->m_uv_timer_curl); if (timeout_ms > 0) { - uv_timer_start(&event_loop->m_uv_timer_curl, on_uv_timeout_callback, static_cast(timeout_ms), 0); + uv_timer_start(&el->m_uv_timer_curl, on_uv_timeout_callback, static_cast(timeout_ms), 0); } else if (timeout_ms == 0) { - event_loop->checkActions(); + el->check_actions(); } } auto curl_handle_socket_actions(CURL* /*curl*/, curl_socket_t socket, int action, void* user_data, void* socketp) -> int { - auto* event_loop = static_cast(user_data); + auto* el = static_cast(user_data); - CurlContext* curl_context = nullptr; + curl_context* cc = nullptr; if (action == CURL_POLL_IN || action == CURL_POLL_OUT || action == CURL_POLL_INOUT) { if (socketp != nullptr) { // existing request - curl_context = static_cast(socketp); + cc = static_cast(socketp); } else { // new request, and no curl context's available? make one - if (event_loop->m_curl_context_ready.empty()) + if (el->m_curl_context_ready.empty()) { - auto curl_context_ptr = std::make_unique(*event_loop); - curl_context = curl_context_ptr.release(); + auto curl_context_ptr = std::make_unique(*el); + cc = curl_context_ptr.release(); } else { - curl_context = event_loop->m_curl_context_ready.front().release(); - event_loop->m_curl_context_ready.pop_front(); + cc = el->m_curl_context_ready.front().release(); + el->m_curl_context_ready.pop_front(); } - curl_context->Init(&event_loop->m_uv_loop, socket); - curl_multi_assign(event_loop->m_cmh, socket, static_cast(curl_context)); + cc->init(&el->m_uv_loop, socket); + curl_multi_assign(el->m_cmh, socket, static_cast(cc)); } } switch (action) { case CURL_POLL_IN: - uv_poll_start(&curl_context->GetUvPollHandle(), UV_READABLE, on_uv_curl_perform_callback); + uv_poll_start(&cc->uv_poll_handle(), UV_READABLE, on_uv_curl_perform_callback); break; case CURL_POLL_OUT: - uv_poll_start(&curl_context->GetUvPollHandle(), UV_WRITABLE, on_uv_curl_perform_callback); + uv_poll_start(&cc->uv_poll_handle(), UV_WRITABLE, on_uv_curl_perform_callback); break; case CURL_POLL_INOUT: - uv_poll_start(&curl_context->GetUvPollHandle(), UV_READABLE | UV_WRITABLE, on_uv_curl_perform_callback); + uv_poll_start(&cc->uv_poll_handle(), UV_READABLE | UV_WRITABLE, on_uv_curl_perform_callback); break; case CURL_POLL_REMOVE: if (socketp != nullptr) { - curl_context = static_cast(socketp); - curl_context->Close(); // signal this handle is done - curl_multi_assign(event_loop->m_cmh, socket, nullptr); + cc = static_cast(socketp); + cc->close(); // signal this handle is done + curl_multi_assign(el->m_cmh, socket, nullptr); } break; default: @@ -493,25 +480,25 @@ auto curl_handle_socket_actions(CURL* /*curl*/, curl_socket_t socket, int action return 0; } -auto uv_close_callback(uv_handle_t* handle) -> void +auto uv_close_callback(uv_handle_t * /*handle*/) -> void { - auto* event_loop = static_cast(handle->data); - (void)event_loop; + // auto* el = static_cast(handle->data); + // (void)el; // Currently nothing needs to be done since all handles the event loop uses - // are allocated within the lift::EventLoop object and not separate on the heap. + // are allocated within the lift::event_loop object and not separate on the heap. } auto on_uv_timeout_callback(uv_timer_t* handle) -> void { - auto* event_loop = static_cast(handle->data); - event_loop->checkActions(); + auto* el = static_cast(handle->data); + el->check_actions(); } auto on_uv_curl_perform_callback(uv_poll_t* req, int status, int events) -> void { - auto* curl_context = static_cast(req->data); - auto& event_loop = curl_context->GetEventLoop(); + auto* cc = static_cast(req->data); + auto& el = cc->lift_event_loop(); int32_t action = 0; if (status < 0) @@ -530,38 +517,38 @@ auto on_uv_curl_perform_callback(uv_poll_t* req, int status, int events) -> void } } - event_loop.checkActions(curl_context->GetCurlSockFd(), action); + el.check_actions(cc->curl_sock_fd(), action); } auto on_uv_requests_accept_async(uv_async_t* handle) -> void { - auto* event_loop = static_cast(handle->data); + auto* el = static_cast(handle->data); /** * This lock must not have any "curl_*" functions called * while it is held, curl has its own internal locks and * it can cause a deadlock. This means we intentionally swap * vectors before working on them so we have exclusive access - * to the Request objects on the EventLoop thread. + * to the Request objects on the event_loop thread. */ { - std::lock_guard guard{event_loop->m_pending_requests_lock}; + std::lock_guard guard{el->m_pending_requests_lock}; // swap so we can release the lock as quickly as possible - event_loop->m_grabbed_requests.swap(event_loop->m_pending_requests); + el->m_grabbed_requests.swap(el->m_pending_requests); } - for (auto& request_ptr : event_loop->m_grabbed_requests) + for (auto& request_ptr : el->m_grabbed_requests) { - auto executor_ptr = event_loop->acquireExecutor(); - executor_ptr->startAsync(std::move(request_ptr), event_loop->m_share_ptr.get()); + auto executor_ptr = el->acquire_executor(); + executor_ptr->start_async(std::move(request_ptr), el->m_share_ptr.get()); executor_ptr->prepare(); // This must be done before adding to the CURLM* object, // if not its possible a very fast request could complete // before this gets into the multi-map! - event_loop->addTimeout(*executor_ptr); + el->add_timeout(*executor_ptr); - auto curl_code = curl_multi_add_handle(event_loop->m_cmh, executor_ptr->m_curl_handle); + auto curl_code = curl_multi_add_handle(el->m_cmh, executor_ptr->m_curl_handle); if (curl_code != CURLM_OK && curl_code != CURLM_CALL_MULTI_PERFORM) { @@ -569,7 +556,7 @@ auto on_uv_requests_accept_async(uv_async_t* handle) -> void * If curl_multi_add_handle fails then notify the user that the request failed to start * immediately. */ - event_loop->completeRequestNormal(*executor_ptr.get(), Executor::convert(CURLcode::CURLE_SEND_ERROR)); + el->complete_request_normal(*executor_ptr.get(), executor::convert(CURLcode::CURLE_SEND_ERROR)); } else { @@ -585,38 +572,38 @@ auto on_uv_requests_accept_async(uv_async_t* handle) -> void * Curl appears to have an internal queue and if it gets too long it might * drop requests. */ - event_loop->checkActions(); + el->check_actions(); } } - event_loop->m_grabbed_requests.clear(); + el->m_grabbed_requests.clear(); } auto on_uv_timesup_callback(uv_timer_t* handle) -> void { - auto* event_loop = static_cast(handle->data); - auto& timesup = event_loop->m_timeouts; + auto* el = static_cast(handle->data); + auto& timesup = el->m_timeouts; if (timesup.empty()) { return; } - auto now = uv_now(&event_loop->m_uv_loop); + auto now = uv_now(&el->m_uv_loop); // While the items in the timesup map are <= now "timesup" them to the client. auto iter = timesup.begin(); while (iter != timesup.end()) { - if (iter->first > now) + auto& [tp, exe] = *iter; + if (tp > now) { // Everything past this point has more time to wait. break; } - auto& executor = *iter->second; - event_loop->completeRequestTimeout(executor); - iter = event_loop->removeTimeout(executor); + el->complete_request_timeout(*exe); + iter = el->remove_timeout(*exe); } } diff --git a/src/executor.cpp b/src/executor.cpp index 2e5d2e0..52b663c 100644 --- a/src/executor.cpp +++ b/src/executor.cpp @@ -15,7 +15,7 @@ auto curl_xfer_info( curl_off_t upload_total_bytes, curl_off_t upload_now_bytes) -> int; -Executor::Executor(Request* request, Share* share) : m_request_sync(request), m_request(m_request_sync), m_response() +executor::executor(Request* request, Share* share) : m_request_sync(request), m_request(m_request_sync), m_response() { if (share != nullptr) { @@ -23,17 +23,17 @@ Executor::Executor(Request* request, Share* share) : m_request_sync(request), m_ } } -Executor::Executor(EventLoop* event_loop) : m_event_loop(event_loop) +executor::executor(event_loop* event_loop) : m_event_loop(event_loop) { } -Executor::~Executor() +executor::~executor() { reset(); curl_easy_cleanup(m_curl_handle); } -auto Executor::startAsync(RequestPtr request_ptr, Share* share) -> void +auto executor::start_async(RequestPtr request_ptr, Share* share) -> void { m_request_async = std::move(request_ptr); m_request = m_request_async.get(); @@ -43,7 +43,7 @@ auto Executor::startAsync(RequestPtr request_ptr, Share* share) -> void } } -auto Executor::perform() -> Response +auto executor::perform() -> Response { global_init(); @@ -51,14 +51,14 @@ auto Executor::perform() -> Response auto curl_error_code = curl_easy_perform(m_curl_handle); m_response.m_lift_status = convert(curl_error_code); - copyCurlToResponse(); + copy_curl_to_response(); global_cleanup(); return std::move(m_response); } -auto Executor::prepare() -> void +auto executor::prepare() -> void { curl_easy_setopt(m_curl_handle, CURLOPT_PRIVATE, this); curl_easy_setopt(m_curl_handle, CURLOPT_HEADERFUNCTION, curl_write_header); @@ -71,54 +71,54 @@ auto Executor::prepare() -> void switch (m_request->Method()) { - case http::Method::UNKNOWN: // default to GET on unknown/bad value. + case http::method::unknown: // default to GET on unknown/bad value. /* INTENTIONAL FALLTHROUGH */ - case http::Method::GET: + case http::method::get: curl_easy_setopt(m_curl_handle, CURLOPT_HTTPGET, 1L); break; - case http::Method::HEAD: + case http::method::head: curl_easy_setopt(m_curl_handle, CURLOPT_NOBODY, 1L); break; - case http::Method::POST: + case http::method::post: curl_easy_setopt(m_curl_handle, CURLOPT_POST, 1L); break; - case http::Method::PUT: + case http::method::put: curl_easy_setopt(m_curl_handle, CURLOPT_PUT, 1L); break; - case http::Method::DELETE: + case http::method::delete_t: curl_easy_setopt(m_curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE"); break; - case http::Method::CONNECT: + case http::method::connect: curl_easy_setopt(m_curl_handle, CURLOPT_CONNECT_ONLY, 1L); break; - case http::Method::OPTIONS: + case http::method::options: curl_easy_setopt(m_curl_handle, CURLOPT_CUSTOMREQUEST, "OPTIONS"); break; - case http::Method::PATCH: + case http::method::patch: curl_easy_setopt(m_curl_handle, CURLOPT_CUSTOMREQUEST, "PATCH"); break; } switch (m_request->Version()) { - case http::Version::UNKNOWN: // default to USE_BEST on unknown/bad value. + case http::version::unknown: // default to USE_BEST on unknown/bad value. /* INTENTIONAL FALLTHROUGH */ - case http::Version::USE_BEST: + case http::version::use_best: curl_easy_setopt(m_curl_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_NONE); break; - case http::Version::V1_0: + case http::version::v1_0: curl_easy_setopt(m_curl_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); break; - case http::Version::V1_1: + case http::version::v1_1: curl_easy_setopt(m_curl_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); break; - case http::Version::V2_0: + case http::version::v2_0: curl_easy_setopt(m_curl_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); break; - case http::Version::V2_0_TLS: + case http::version::v2_0_tls: curl_easy_setopt(m_curl_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS); break; - case http::Version::V2_0_ONLY: + case http::version::v2_0_only: curl_easy_setopt(m_curl_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE); break; } @@ -289,7 +289,7 @@ auto Executor::prepare() -> void for (auto& header : m_request->m_request_headers) { - m_curl_request_headers = curl_slist_append(m_curl_request_headers, header.headerFull().data()); + m_curl_request_headers = curl_slist_append(m_curl_request_headers, header.data().data()); } if (m_curl_request_headers != nullptr) @@ -381,7 +381,7 @@ auto Executor::prepare() -> void } } -auto Executor::copyCurlToResponse() -> void +auto executor::copy_curl_to_response() -> void { long http_response_code = 0; curl_easy_getinfo(m_curl_handle, CURLINFO_RESPONSE_CODE, &http_response_code); @@ -389,7 +389,7 @@ auto Executor::copyCurlToResponse() -> void long http_version = 0; curl_easy_getinfo(m_curl_handle, CURLINFO_HTTP_VERSION, &http_version); - m_response.m_version = static_cast(http_version); + m_response.m_version = static_cast(http_version); double total_time = 0; curl_easy_getinfo(m_curl_handle, CURLINFO_TOTAL_TIME, &total_time); @@ -410,15 +410,15 @@ auto Executor::copyCurlToResponse() -> void : static_cast(redirect_count); } -auto Executor::setTimesupResponse(std::chrono::milliseconds total_time) -> void +auto executor::set_timesup_response(std::chrono::milliseconds total_time) -> void { - m_response.m_status_code = lift::http::StatusCode::HTTP_504_GATEWAY_TIMEOUT; + m_response.m_status_code = lift::http::status_code::http_504_gateway_timeout; m_response.m_total_time = static_cast(total_time.count()); m_response.m_num_connects = 0; m_response.m_num_redirects = 0; } -auto Executor::reset() -> void +auto executor::reset() -> void { if (m_mime_handle != nullptr) { @@ -453,7 +453,7 @@ auto Executor::reset() -> void curl_easy_reset(m_curl_handle); } -auto Executor::convert(CURLcode curl_code) -> LiftStatus +auto executor::convert(CURLcode curl_code) -> LiftStatus { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch-enum" @@ -483,7 +483,7 @@ auto Executor::convert(CURLcode curl_code) -> LiftStatus auto curl_write_header(char* buffer, size_t size, size_t nitems, void* user_ptr) -> size_t { - auto* executor_ptr = static_cast(user_ptr); + auto* executor_ptr = static_cast(user_ptr); auto& response = executor_ptr->m_response; const size_t data_length = size * nitems; @@ -520,7 +520,7 @@ auto curl_write_header(char* buffer, size_t size, size_t nitems, void* user_ptr) auto curl_write_data(void* buffer, size_t size, size_t nitems, void* user_ptr) -> size_t { - auto* executor_ptr = static_cast(user_ptr); + auto* executor_ptr = static_cast(user_ptr); auto& response = executor_ptr->m_response; size_t data_length = size * nitems; @@ -539,7 +539,7 @@ auto curl_xfer_info( curl_off_t upload_total_bytes, curl_off_t upload_now_bytes) -> int { - const auto* executor_ptr = static_cast(clientp); + const auto* executor_ptr = static_cast(clientp); if (executor_ptr != nullptr && executor_ptr->m_request->m_on_transfer_progress_handler != nullptr) { diff --git a/src/header.cpp b/src/header.cpp index e5a62d9..d63420b 100644 --- a/src/header.cpp +++ b/src/header.cpp @@ -4,7 +4,7 @@ namespace lift { -Header::Header(std::string_view name, std::string_view value) +header::header(std::string_view name, std::string_view value) { m_header.reserve(name.length() + value.length() + 2); m_header.append(name.data(), name.length()); @@ -14,7 +14,7 @@ Header::Header(std::string_view name, std::string_view value) m_colon_pos = name.length(); } -Header::Header(std::string header_full) : m_header(std::move(header_full)) +header::header(std::string header_full) : m_header(std::move(header_full)) { m_colon_pos = m_header.find(":"); // class assumes the two bytes ": " always exist, enforce that. diff --git a/src/http.cpp b/src/http.cpp index 240c3fd..c28eeb7 100644 --- a/src/http.cpp +++ b/src/http.cpp @@ -2,564 +2,433 @@ namespace lift::http { -using namespace std::string_literals; - -const std::string METHOD_UNKNOWN = "UNKNOWN"s; -const std::string METHOD_GET = "GET"s; -const std::string METHOD_HEAD = "HEAD"s; -const std::string METHOD_POST = "POST"s; -const std::string METHOD_PUT = "PUT"s; -const std::string METHOD_DELETE = "DELETE"s; -const std::string METHOD_CONNECT = "CONNECT"s; -const std::string METHOD_OPTIONS = "OPTIONS"s; -const std::string METHOD_PATCH = "PATCH"s; - -auto to_string(Method method) -> const std::string& +auto to_string(method m) -> const std::string& { - switch (method) + switch (m) { - case Method::GET: - return METHOD_GET; - case Method::HEAD: - return METHOD_HEAD; - case Method::POST: - return METHOD_POST; - case Method::PUT: - return METHOD_PUT; - case Method::DELETE: - return METHOD_DELETE; - case Method::CONNECT: - return METHOD_CONNECT; - case Method::OPTIONS: - return METHOD_OPTIONS; - case Method::PATCH: - return METHOD_PATCH; + case method::get: + return method_get; + case method::head: + return method_head; + case method::post: + return method_post; + case method::put: + return method_put; + case method::delete_t: + return method_delete; + case method::connect: + return method_connect; + case method::options: + return method_options; + case method::patch: + return method_patch; default: - return METHOD_UNKNOWN; + return method_unknown; } } -const std::string VERSION_UNKNOWN = "HTTP/unknown"s; -const std::string VERSION_USE_BEST = "HTTP/Best"s; -const std::string VERSION_V1_0 = "HTTP/1.0"s; -const std::string VERSION_V1_1 = "HTTP/1.1"s; -const std::string VERSION_V2_0 = "HTTP/2.0"s; -const std::string VERSION_V2_0_TLS = "HTTP/2.0-TLS"s; -const std::string VERSION_V2_0_ONLY = "HTTP/2.0-only"s; - -auto to_string(Version version) -> const std::string& +auto to_string(version v) -> const std::string& { - switch (version) + switch (v) { - case Version::USE_BEST: - return VERSION_USE_BEST; - case Version::V1_0: - return VERSION_V1_0; - case Version::V1_1: - return VERSION_V1_1; - case Version::V2_0: - return VERSION_V2_0; - case Version::V2_0_TLS: - return VERSION_V2_0_TLS; - case Version::V2_0_ONLY: - return VERSION_V2_0_ONLY; + case version::use_best: + return version_use_best; + case version::v1_0: + return version_v1_0; + case version::v1_1: + return version_v1_1; + case version::v2_0: + return version_v2_0; + case version::v2_0_tls: + return version_v2_0_tls; + case version::v2_0_only: + return version_v2_0_only; default: - return VERSION_UNKNOWN; + return version_unknown; } } -const std::string STATUS_CODE_HTTP_UNKNOWN = "UNKNOWN"s; -const std::string STATUS_CODE_HTTP_100_CONTINUE = "100 Continue"s; -const std::string STATUS_CODE_HTTP_101_SWITCHING_PROTOCOLS = "101 Switching Protocols"s; -const std::string STATUS_CODE_HTTP_102_PROCESSING = "102 Processing"s; -const std::string STATUS_CODE_HTTP_103_EARLY_HINTS = "103 Early Hints"s; - -const std::string STATUS_CODE_HTTP_200_OK = "200 OK"s; -const std::string STATUS_CODE_HTTP_201_CREATED = "201 Created"s; -const std::string STATUS_CODE_HTTP_202_ACCEPTED = "202 Accepted"s; -const std::string STATUS_CODE_HTTP_203_NON_AUTHORITATIVE_INFORMATION = "203 Non-Authoritative Information"s; -const std::string STATUS_CODE_HTTP_204_NO_CONTENT = "204 No Content"s; -const std::string STATUS_CODE_HTTP_205_RESET_CONTENT = "205 Reset Content"s; -const std::string STATUS_CODE_HTTP_206_PARTIAL_CONTENT = "206 Partial Content"s; -const std::string STATUS_CODE_HTTP_207_MULTI_STATUS = "207 Multi-Status"s; -const std::string STATUS_CODE_HTTP_208_ALREADY_REPORTED = "208 Already Reported"s; -const std::string STATUS_CODE_HTTP_226_IM_USED = "226 IM Used"s; - -const std::string STATUS_CODE_HTTP_300_MULTIPLE_CHOICES = "300 Multiple Choices"s; -const std::string STATUS_CODE_HTTP_301_MOVED_PERMANENTLY = "301 Moved Permanently"s; -const std::string STATUS_CODE_HTTP_302_FOUND = "302 Found"s; -const std::string STATUS_CODE_HTTP_303_SEE_OTHER = "303 See Other"s; -const std::string STATUS_CODE_HTTP_304_NOT_MODIFIED = "304 Not Modified"s; -const std::string STATUS_CODE_HTTP_305_USE_PROXY = "305 Use Proxy"s; -const std::string STATUS_CODE_HTTP_306_SWITCH_PROXY = "306 Switch Proxy"s; -const std::string STATUS_CODE_HTTP_307_TEMPORARY_REDIRECT = "307 Temporary Redirect"s; -const std::string STATUS_CODE_HTTP_308_PERMANENT_REDIRECT = "308 Permanent Redirect"s; - -const std::string STATUS_CODE_HTTP_400_BAD_REQUEST = "400 Bad Request"s; -const std::string STATUS_CODE_HTTP_401_UNAUTHORIZED = "401 Unauthorized"s; -const std::string STATUS_CODE_HTTP_402_PAYMENT_REQUIRED = "402 Payment Required"s; -const std::string STATUS_CODE_HTTP_403_FORBIDDEN = "403 Forbidden"s; -const std::string STATUS_CODE_HTTP_404_NOT_FOUND = "404 Not Found"s; -const std::string STATUS_CODE_HTTP_405_METHOD_NOT_ALLOWED = "405 Method Not Allowed"s; -const std::string STATUS_CODE_HTTP_406_NOT_ACCEPTABLE = "406 Not Acceptable"s; -const std::string STATUS_CODE_HTTP_407_PROXY_AUTHENTICATION_REQUIRED = "407 Proxy Authentication Required"s; -const std::string STATUS_CODE_HTTP_408_REQUEST_TIMEOUT = "408 Request Timeout"s; -const std::string STATUS_CODE_HTTP_409_CONFLICT = "409 Conflict"s; -const std::string STATUS_CODE_HTTP_410_GONE = "410 Gone"s; -const std::string STATUS_CODE_HTTP_411_LENGTH_REQUIRED = "411 Length Required"s; -const std::string STATUS_CODE_HTTP_412_PRECONDITION_FAILED = "412 Precondition Failed"s; -const std::string STATUS_CODE_HTTP_413_PAYLOAD_TOO_LARGE = "413 Payload Too Large"s; -const std::string STATUS_CODE_HTTP_414_URI_TOO_LONG = "414 URI Too Long"s; -const std::string STATUS_CODE_HTTP_415_UNSUPPORTED_MEDIA_TYPE = "415 Unsupported Media Type"s; -const std::string STATUS_CODE_HTTP_416_RANGE_NOT_SATISFIABLE = "416 Range Not Satisfiable"s; -const std::string STATUS_CODE_HTTP_417_EXPECTATION_FAILED = "417 Expectation Failed"s; -const std::string STATUS_CODE_HTTP_418_IM_A_TEAPOT = "418 I'm a teapot"s; -const std::string STATUS_CODE_HTTP_421_MISDIRECTED_REQUEST = "421 Misdirected Request"s; -const std::string STATUS_CODE_HTTP_422_UNPROCESSABLE_ENTITY = "422 Unprocessable Entity"s; -const std::string STATUS_CODE_HTTP_423_LOCKED = "423 Locked"s; -const std::string STATUS_CODE_HTTP_424_FAILED_DEPENDENCY = "424 Failed Dependency"s; -const std::string STATUS_CODE_HTTP_425_TOO_EARLY = "425 Too Early"s; -const std::string STATUS_CODE_HTTP_426_UPGRADE_REQUIRED = "426 Upgrade Required"s; -const std::string STATUS_CODE_HTTP_428_PRECONDITION_REQUIRED = "428 Precondition Required"s; -const std::string STATUS_CODE_HTTP_429_TOO_MANY_REQUESTS = "429 Too Many Requests"s; -const std::string STATUS_CODE_HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = "431 Request Header Fields Too Large"s; -const std::string STATUS_CODE_HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = "451 Unavailable For Legal Reasons"s; - -const std::string STATUS_CODE_HTTP_500_INTERNAL_SERVER_ERROR = "500 Internal Server Error"s; -const std::string STATUS_CODE_HTTP_501_NOT_IMPLEMENTED = "501 Not Implemented"s; -const std::string STATUS_CODE_HTTP_502_BAD_GATEWAY = "502 Bad Gateway"s; -const std::string STATUS_CODE_HTTP_503_SERVICE_UNAVAILABLE = "503 Service Unavailable"s; -const std::string STATUS_CODE_HTTP_504_GATEWAY_TIMEOUT = "504 Gateway Timeout"s; -const std::string STATUS_CODE_HTTP_505_HTTP_VERSION_NOT_SUPPORTED = "505 HTTP Version Not Supported"s; -const std::string STATUS_CODE_HTTP_506_VARIANT_ALSO_NEGOTIATES = "506 Variant Also Negotiates"s; -const std::string STATUS_CODE_HTTP_507_INSUFFICIENT_STORAGE = "507 Insufficient Storage"s; -const std::string STATUS_CODE_HTTP_508_LOOP_DETECTED = "508 Loop Detected"s; -const std::string STATUS_CODE_HTTP_510_NOT_EXTENDED = "510 Not Extended"s; -const std::string STATUS_CODE_HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = "511 Network Authentication Required"s; - -auto to_string(StatusCode code) -> const std::string& +auto to_string(status_code code) -> const std::string& { switch (code) { - case StatusCode::HTTP_UNKNOWN: - return STATUS_CODE_HTTP_UNKNOWN; - case StatusCode::HTTP_100_CONTINUE: - return STATUS_CODE_HTTP_100_CONTINUE; - case StatusCode::HTTP_101_SWITCHING_PROTOCOLS: - return STATUS_CODE_HTTP_101_SWITCHING_PROTOCOLS; - case StatusCode::HTTP_102_PROCESSING: - return STATUS_CODE_HTTP_102_PROCESSING; - case StatusCode::HTTP_103_EARLY_HINTS: - return STATUS_CODE_HTTP_103_EARLY_HINTS; - case StatusCode::HTTP_200_OK: - return STATUS_CODE_HTTP_200_OK; - case StatusCode::HTTP_201_CREATED: - return STATUS_CODE_HTTP_201_CREATED; - case StatusCode::HTTP_202_ACCEPTED: - return STATUS_CODE_HTTP_202_ACCEPTED; - case StatusCode::HTTP_203_NON_AUTHORITATIVE_INFORMATION: - return STATUS_CODE_HTTP_203_NON_AUTHORITATIVE_INFORMATION; - case StatusCode::HTTP_204_NO_CONTENT: - return STATUS_CODE_HTTP_204_NO_CONTENT; - case StatusCode::HTTP_205_RESET_CONTENT: - return STATUS_CODE_HTTP_205_RESET_CONTENT; - case StatusCode::HTTP_206_PARTIAL_CONTENT: - return STATUS_CODE_HTTP_206_PARTIAL_CONTENT; - case StatusCode::HTTP_207_MULTI_STATUS: - return STATUS_CODE_HTTP_207_MULTI_STATUS; - case StatusCode::HTTP_208_ALREADY_REPORTED: - return STATUS_CODE_HTTP_208_ALREADY_REPORTED; - case StatusCode::HTTP_226_IM_USED: - return STATUS_CODE_HTTP_226_IM_USED; - case StatusCode::HTTP_300_MULTIPLE_CHOICES: - return STATUS_CODE_HTTP_300_MULTIPLE_CHOICES; - case StatusCode::HTTP_301_MOVED_PERMANENTLY: - return STATUS_CODE_HTTP_301_MOVED_PERMANENTLY; - case StatusCode::HTTP_302_FOUND: - return STATUS_CODE_HTTP_302_FOUND; - case StatusCode::HTTP_303_SEE_OTHER: - return STATUS_CODE_HTTP_303_SEE_OTHER; - case StatusCode::HTTP_304_NOT_MODIFIED: - return STATUS_CODE_HTTP_304_NOT_MODIFIED; - case StatusCode::HTTP_305_USE_PROXY: - return STATUS_CODE_HTTP_305_USE_PROXY; - case StatusCode::HTTP_306_SWITCH_PROXY: - return STATUS_CODE_HTTP_306_SWITCH_PROXY; - case StatusCode::HTTP_307_TEMPORARY_REDIRECT: - return STATUS_CODE_HTTP_307_TEMPORARY_REDIRECT; - case StatusCode::HTTP_308_PERMANENT_REDIRECT: - return STATUS_CODE_HTTP_308_PERMANENT_REDIRECT; - case StatusCode::HTTP_400_BAD_REQUEST: - return STATUS_CODE_HTTP_400_BAD_REQUEST; - case StatusCode::HTTP_401_UNAUTHORIZED: - return STATUS_CODE_HTTP_401_UNAUTHORIZED; - case StatusCode::HTTP_402_PAYMENT_REQUIRED: - return STATUS_CODE_HTTP_402_PAYMENT_REQUIRED; - case StatusCode::HTTP_403_FORBIDDEN: - return STATUS_CODE_HTTP_403_FORBIDDEN; - case StatusCode::HTTP_404_NOT_FOUND: - return STATUS_CODE_HTTP_404_NOT_FOUND; - case StatusCode::HTTP_405_METHOD_NOT_ALLOWED: - return STATUS_CODE_HTTP_405_METHOD_NOT_ALLOWED; - case StatusCode::HTTP_406_NOT_ACCEPTABLE: - return STATUS_CODE_HTTP_406_NOT_ACCEPTABLE; - case StatusCode::HTTP_407_PROXY_AUTHENTICATION_REQUIRED: - return STATUS_CODE_HTTP_407_PROXY_AUTHENTICATION_REQUIRED; - case StatusCode::HTTP_408_REQUEST_TIMEOUT: - return STATUS_CODE_HTTP_408_REQUEST_TIMEOUT; - case StatusCode::HTTP_409_CONFLICT: - return STATUS_CODE_HTTP_409_CONFLICT; - case StatusCode::HTTP_410_GONE: - return STATUS_CODE_HTTP_410_GONE; - case StatusCode::HTTP_411_LENGTH_REQUIRED: - return STATUS_CODE_HTTP_411_LENGTH_REQUIRED; - case StatusCode::HTTP_412_PRECONDITION_FAILED: - return STATUS_CODE_HTTP_412_PRECONDITION_FAILED; - case StatusCode::HTTP_413_PAYLOAD_TOO_LARGE: - return STATUS_CODE_HTTP_413_PAYLOAD_TOO_LARGE; - case StatusCode::HTTP_414_URI_TOO_LONG: - return STATUS_CODE_HTTP_414_URI_TOO_LONG; - case StatusCode::HTTP_415_UNSUPPORTED_MEDIA_TYPE: - return STATUS_CODE_HTTP_415_UNSUPPORTED_MEDIA_TYPE; - case StatusCode::HTTP_416_RANGE_NOT_SATISFIABLE: - return STATUS_CODE_HTTP_416_RANGE_NOT_SATISFIABLE; - case StatusCode::HTTP_417_EXPECTATION_FAILED: - return STATUS_CODE_HTTP_417_EXPECTATION_FAILED; - case StatusCode::HTTP_418_IM_A_TEAPOT: - return STATUS_CODE_HTTP_418_IM_A_TEAPOT; - case StatusCode::HTTP_421_MISDIRECTED_REQUEST: - return STATUS_CODE_HTTP_421_MISDIRECTED_REQUEST; - case StatusCode::HTTP_422_UNPROCESSABLE_ENTITY: - return STATUS_CODE_HTTP_422_UNPROCESSABLE_ENTITY; - case StatusCode::HTTP_423_LOCKED: - return STATUS_CODE_HTTP_423_LOCKED; - case StatusCode::HTTP_424_FAILED_DEPENDENCY: - return STATUS_CODE_HTTP_424_FAILED_DEPENDENCY; - case StatusCode::HTTP_425_TOO_EARLY: - return STATUS_CODE_HTTP_425_TOO_EARLY; - case StatusCode::HTTP_426_UPGRADE_REQUIRED: - return STATUS_CODE_HTTP_426_UPGRADE_REQUIRED; - case StatusCode::HTTP_428_PRECONDITION_REQUIRED: - return STATUS_CODE_HTTP_428_PRECONDITION_REQUIRED; - case StatusCode::HTTP_429_TOO_MANY_REQUESTS: - return STATUS_CODE_HTTP_429_TOO_MANY_REQUESTS; - case StatusCode::HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE: - return STATUS_CODE_HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE; - case StatusCode::HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS: - return STATUS_CODE_HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS; - case StatusCode::HTTP_500_INTERNAL_SERVER_ERROR: - return STATUS_CODE_HTTP_500_INTERNAL_SERVER_ERROR; - case StatusCode::HTTP_501_NOT_IMPLEMENTED: - return STATUS_CODE_HTTP_501_NOT_IMPLEMENTED; - case StatusCode::HTTP_502_BAD_GATEWAY: - return STATUS_CODE_HTTP_502_BAD_GATEWAY; - case StatusCode::HTTP_503_SERVICE_UNAVAILABLE: - return STATUS_CODE_HTTP_503_SERVICE_UNAVAILABLE; - case StatusCode::HTTP_504_GATEWAY_TIMEOUT: - return STATUS_CODE_HTTP_504_GATEWAY_TIMEOUT; - case StatusCode::HTTP_505_HTTP_VERSION_NOT_SUPPORTED: - return STATUS_CODE_HTTP_505_HTTP_VERSION_NOT_SUPPORTED; - case StatusCode::HTTP_506_VARIANT_ALSO_NEGOTIATES: - return STATUS_CODE_HTTP_506_VARIANT_ALSO_NEGOTIATES; - case StatusCode::HTTP_507_INSUFFICIENT_STORAGE: - return STATUS_CODE_HTTP_507_INSUFFICIENT_STORAGE; - case StatusCode::HTTP_508_LOOP_DETECTED: - return STATUS_CODE_HTTP_508_LOOP_DETECTED; - case StatusCode::HTTP_510_NOT_EXTENDED: - return STATUS_CODE_HTTP_510_NOT_EXTENDED; - case StatusCode::HTTP_511_NETWORK_AUTHENTICATION_REQUIRED: - return STATUS_CODE_HTTP_511_NETWORK_AUTHENTICATION_REQUIRED; + case status_code::http_unknown: + return status_code_http_unknown; + + case status_code::http_100_continue: + return status_code_http_100_continue; + case status_code::http_101_switching_protocols: + return status_code_http_101_switching_protocols; + case status_code::http_102_processing: + return status_code_http_102_processing; + case status_code::http_103_early_hints: + return status_code_http_103_early_hints; + + case status_code::http_200_ok: + return status_code_http_200_ok; + case status_code::http_201_created: + return status_code_http_201_created; + case status_code::http_202_accepted: + return status_code_http_202_accepted; + case status_code::http_203_non_authoritative_information: + return status_code_http_203_non_authoritative_information; + case status_code::http_204_no_content: + return status_code_http_204_no_content; + case status_code::http_205_reset_content: + return status_code_http_205_reset_content; + case status_code::http_206_partial_content: + return status_code_http_206_partial_content; + case status_code::http_207_multi_status: + return status_code_http_207_multi_status; + case status_code::http_208_already_reported: + return status_code_http_208_already_reported; + case status_code::http_226_im_used: + return status_code_http_226_im_used; + + case status_code::http_300_multiple_choices: + return status_code_http_300_multiple_choices; + case status_code::http_301_moved_permanently: + return status_code_http_301_moved_permanently; + case status_code::http_302_found: + return status_code_http_302_found; + case status_code::http_303_see_other: + return status_code_http_303_see_other; + case status_code::http_304_not_modified: + return status_code_http_304_not_modified; + case status_code::http_305_use_proxy: + return status_code_http_305_use_proxy; + case status_code::http_306_switch_proxy: + return status_code_http_306_switch_proxy; + case status_code::http_307_temporary_redirect: + return status_code_http_307_temporary_redirect; + case status_code::http_308_permanent_redirect: + return status_code_http_308_permanent_redirect; + + case status_code::http_400_bad_request: + return status_code_http_400_bad_request; + case status_code::http_401_unauthorized: + return status_code_http_401_unauthorized; + case status_code::http_402_payment_required: + return status_code_http_402_payment_required; + case status_code::http_403_forbidden: + return status_code_http_403_forbidden; + case status_code::http_404_not_found: + return status_code_http_404_not_found; + case status_code::http_405_method_not_allowed: + return status_code_http_405_method_not_allowed; + case status_code::http_406_not_acceptable: + return status_code_http_406_not_acceptable; + case status_code::http_407_proxy_authentication_required: + return status_code_http_407_proxy_authentication_required; + case status_code::http_408_request_timeout: + return status_code_http_408_request_timeout; + case status_code::http_409_conflict: + return status_code_http_409_conflict; + case status_code::http_410_gone: + return status_code_http_410_gone; + case status_code::http_411_length_required: + return status_code_http_411_length_required; + case status_code::http_412_precondition_failed: + return status_code_http_412_precondition_failed; + case status_code::http_413_payload_too_large: + return status_code_http_413_payload_too_large; + case status_code::http_414_uri_too_long: + return status_code_http_414_uri_too_long; + case status_code::http_415_unsupported_media_type: + return status_code_http_415_unsupported_media_type; + case status_code::http_416_range_not_satisfiable: + return status_code_http_416_range_not_satisfiable; + case status_code::http_417_expectation_failed: + return status_code_http_417_expectation_failed; + case status_code::http_418_im_a_teapot: + return status_code_http_418_im_a_teapot; + case status_code::http_421_misdirected_request: + return status_code_http_421_misdirected_request; + case status_code::http_422_unprocessable_entity: + return status_code_http_422_unprocessable_entity; + case status_code::http_423_locked: + return status_code_http_423_locked; + case status_code::http_424_failed_dependency: + return status_code_http_424_failed_dependency; + case status_code::http_425_too_early: + return status_code_http_425_too_early; + case status_code::http_426_upgrade_required: + return status_code_http_426_upgrade_required; + case status_code::http_428_precondition_required: + return status_code_http_428_precondition_required; + case status_code::http_429_too_many_requests: + return status_code_http_429_too_many_requests; + case status_code::http_431_request_header_fields_too_large: + return status_code_http_431_request_header_fields_too_large; + case status_code::http_451_unavailable_for_legal_reasons: + return status_code_http_451_unavailable_for_legal_reasons; + + case status_code::http_500_internal_server_error: + return status_code_http_500_internal_server_error; + case status_code::http_501_not_implemented: + return status_code_http_501_not_implemented; + case status_code::http_502_bad_gateway: + return status_code_http_502_bad_gateway; + case status_code::http_503_service_unavailable: + return status_code_http_503_service_unavailable; + case status_code::http_504_gateway_timeout: + return status_code_http_504_gateway_timeout; + case status_code::http_505_http_version_not_supported: + return status_code_http_505_http_version_not_supported; + case status_code::http_506_variant_also_negotiates: + return status_code_http_506_variant_also_negotiates; + case status_code::http_507_insufficient_storage: + return status_code_http_507_insufficient_storage; + case status_code::http_508_loop_detected: + return status_code_http_508_loop_detected; + case status_code::http_510_not_extended: + return status_code_http_510_not_extended; + case status_code::http_511_network_authentication_required: + return status_code_http_511_network_authentication_required; + default: - return STATUS_CODE_HTTP_UNKNOWN; + return status_code_http_unknown; } } -auto to_enum(int32_t code) -> StatusCode +auto to_enum(uint16_t code) -> status_code { switch (code) { case 100: - return StatusCode::HTTP_100_CONTINUE; + return status_code::http_100_continue; case 101: - return StatusCode::HTTP_101_SWITCHING_PROTOCOLS; + return status_code::http_101_switching_protocols; case 102: - return StatusCode::HTTP_102_PROCESSING; + return status_code::http_102_processing; case 103: - return StatusCode::HTTP_103_EARLY_HINTS; + return status_code::http_103_early_hints; case 200: - return StatusCode::HTTP_200_OK; + return status_code::http_200_ok; case 201: - return StatusCode::HTTP_201_CREATED; + return status_code::http_201_created; case 202: - return StatusCode::HTTP_202_ACCEPTED; + return status_code::http_202_accepted; case 203: - return StatusCode::HTTP_203_NON_AUTHORITATIVE_INFORMATION; + return status_code::http_203_non_authoritative_information; case 204: - return StatusCode::HTTP_204_NO_CONTENT; + return status_code::http_204_no_content; case 205: - return StatusCode::HTTP_205_RESET_CONTENT; + return status_code::http_205_reset_content; case 206: - return StatusCode::HTTP_206_PARTIAL_CONTENT; + return status_code::http_206_partial_content; case 207: - return StatusCode::HTTP_207_MULTI_STATUS; + return status_code::http_207_multi_status; case 208: - return StatusCode::HTTP_208_ALREADY_REPORTED; + return status_code::http_208_already_reported; case 226: - return StatusCode::HTTP_226_IM_USED; + return status_code::http_226_im_used; case 300: - return StatusCode::HTTP_300_MULTIPLE_CHOICES; + return status_code::http_300_multiple_choices; case 301: - return StatusCode::HTTP_301_MOVED_PERMANENTLY; + return status_code::http_301_moved_permanently; case 302: - return StatusCode::HTTP_302_FOUND; + return status_code::http_302_found; case 303: - return StatusCode::HTTP_303_SEE_OTHER; + return status_code::http_303_see_other; case 304: - return StatusCode::HTTP_304_NOT_MODIFIED; + return status_code::http_304_not_modified; case 305: - return StatusCode::HTTP_305_USE_PROXY; + return status_code::http_305_use_proxy; case 306: - return StatusCode::HTTP_306_SWITCH_PROXY; + return status_code::http_306_switch_proxy; case 307: - return StatusCode::HTTP_307_TEMPORARY_REDIRECT; + return status_code::http_307_temporary_redirect; case 308: - return StatusCode::HTTP_308_PERMANENT_REDIRECT; + return status_code::http_308_permanent_redirect; case 400: - return StatusCode::HTTP_400_BAD_REQUEST; + return status_code::http_400_bad_request; case 401: - return StatusCode::HTTP_401_UNAUTHORIZED; + return status_code::http_401_unauthorized; case 402: - return StatusCode::HTTP_402_PAYMENT_REQUIRED; + return status_code::http_402_payment_required; case 403: - return StatusCode::HTTP_403_FORBIDDEN; + return status_code::http_403_forbidden; case 404: - return StatusCode::HTTP_404_NOT_FOUND; + return status_code::http_404_not_found; case 405: - return StatusCode::HTTP_405_METHOD_NOT_ALLOWED; + return status_code::http_405_method_not_allowed; case 406: - return StatusCode::HTTP_406_NOT_ACCEPTABLE; + return status_code::http_406_not_acceptable; case 407: - return StatusCode::HTTP_407_PROXY_AUTHENTICATION_REQUIRED; + return status_code::http_407_proxy_authentication_required; case 408: - return StatusCode::HTTP_408_REQUEST_TIMEOUT; + return status_code::http_408_request_timeout; case 409: - return StatusCode::HTTP_409_CONFLICT; + return status_code::http_409_conflict; case 410: - return StatusCode::HTTP_410_GONE; + return status_code::http_410_gone; case 411: - return StatusCode::HTTP_411_LENGTH_REQUIRED; + return status_code::http_411_length_required; case 412: - return StatusCode::HTTP_412_PRECONDITION_FAILED; + return status_code::http_412_precondition_failed; case 413: - return StatusCode::HTTP_413_PAYLOAD_TOO_LARGE; + return status_code::http_413_payload_too_large; case 414: - return StatusCode::HTTP_414_URI_TOO_LONG; + return status_code::http_414_uri_too_long; case 415: - return StatusCode::HTTP_415_UNSUPPORTED_MEDIA_TYPE; + return status_code::http_415_unsupported_media_type; case 416: - return StatusCode::HTTP_416_RANGE_NOT_SATISFIABLE; + return status_code::http_416_range_not_satisfiable; case 417: - return StatusCode::HTTP_417_EXPECTATION_FAILED; + return status_code::http_417_expectation_failed; case 418: - return StatusCode::HTTP_418_IM_A_TEAPOT; + return status_code::http_418_im_a_teapot; case 421: - return StatusCode::HTTP_421_MISDIRECTED_REQUEST; + return status_code::http_421_misdirected_request; case 422: - return StatusCode::HTTP_422_UNPROCESSABLE_ENTITY; + return status_code::http_422_unprocessable_entity; case 423: - return StatusCode::HTTP_423_LOCKED; + return status_code::http_423_locked; case 424: - return StatusCode::HTTP_424_FAILED_DEPENDENCY; + return status_code::http_424_failed_dependency; case 425: - return StatusCode::HTTP_425_TOO_EARLY; + return status_code::http_425_too_early; case 426: - return StatusCode::HTTP_426_UPGRADE_REQUIRED; + return status_code::http_426_upgrade_required; case 428: - return StatusCode::HTTP_428_PRECONDITION_REQUIRED; + return status_code::http_428_precondition_required; case 429: - return StatusCode::HTTP_429_TOO_MANY_REQUESTS; + return status_code::http_429_too_many_requests; case 431: - return StatusCode::HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE; + return status_code::http_431_request_header_fields_too_large; case 451: - return StatusCode::HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS; + return status_code::http_451_unavailable_for_legal_reasons; case 500: - return StatusCode::HTTP_500_INTERNAL_SERVER_ERROR; + return status_code::http_500_internal_server_error; case 501: - return StatusCode::HTTP_501_NOT_IMPLEMENTED; + return status_code::http_501_not_implemented; case 502: - return StatusCode::HTTP_502_BAD_GATEWAY; + return status_code::http_502_bad_gateway; case 503: - return StatusCode::HTTP_503_SERVICE_UNAVAILABLE; + return status_code::http_503_service_unavailable; case 504: - return StatusCode::HTTP_504_GATEWAY_TIMEOUT; + return status_code::http_504_gateway_timeout; case 505: - return StatusCode::HTTP_505_HTTP_VERSION_NOT_SUPPORTED; + return status_code::http_505_http_version_not_supported; case 506: - return StatusCode::HTTP_506_VARIANT_ALSO_NEGOTIATES; + return status_code::http_506_variant_also_negotiates; case 507: - return StatusCode::HTTP_507_INSUFFICIENT_STORAGE; + return status_code::http_507_insufficient_storage; case 508: - return StatusCode::HTTP_508_LOOP_DETECTED; + return status_code::http_508_loop_detected; case 510: - return StatusCode::HTTP_510_NOT_EXTENDED; + return status_code::http_510_not_extended; case 511: - return StatusCode::HTTP_511_NETWORK_AUTHENTICATION_REQUIRED; + return status_code::http_511_network_authentication_required; case 0: default: - return StatusCode::HTTP_UNKNOWN; + return status_code::http_unknown; } } -const std::string CONTENT_TYPE_UNKNOWN = "UNKNOWN"s; - -const std::string CONTENT_TYPE_NO_CONTENT = ""s; - -const std::string CONTENT_TYPE_TEXT_CSS = "text/css"s; -const std::string CONTENT_TYPE_TEXT_CSV = "text/csv"s; -const std::string CONTENT_TYPE_TEXT_HTML = "text/html"s; -const std::string CONTENT_TYPE_TEXT_PLAIN = "text/plain"s; -const std::string CONTENT_TYPE_TEXT_XML = "text/xml"s; - -const std::string CONTENT_TYPE_IMAGE_GIF = "image/gif"s; -const std::string CONTENT_TYPE_IMAGE_JPEG = "image/jpeg"s; -const std::string CONTENT_TYPE_IMAGE_PNG = "image/png"s; -const std::string CONTENT_TYPE_IMAGE_TIFF = "image/tiff"s; -const std::string CONTENT_TYPE_IMAGE_X_ICON = "image/x-icon"s; -const std::string CONTENT_TYPE_IMAGE_SVG_XML = "image/svg+xml"s; - -const std::string CONTENT_TYPE_VIDEO_MPEG = "video/mpeg"s; -const std::string CONTENT_TYPE_VIDEO_MP4 = "video/mp4"s; -const std::string CONTENT_TYPE_VIDEO_X_FLV = "video/x-flv"s; -const std::string CONTENT_TYPE_VIDEO_WEBM = "video/webm"s; - -const std::string CONTENT_TYPE_MULTIPART_MIXED = "multipart/mixed"s; -const std::string CONTENT_TYPE_MULTIPART_ALTERNATIVE = "multipart/alternative"s; -const std::string CONTENT_TYPE_MULTIPART_RELATED = "multipart/related"s; -const std::string CONTENT_TYPE_MULTIPART_FORM_DATA = "multipart/form-data"s; - -const std::string CONTENT_TYPE_AUDIO_MPEG = "audio/mpeg"s; -const std::string CONTENT_TYPE_AUDIO_X_MS_WMA = "audio/x-ms-wma"s; -const std::string CONTENT_TYPE_AUDIO_X_WAV = "audio/x-wav"s; - -const std::string CONTENT_TYPE_APPLICATION_JAVASCRIPT = "application/javascript"s; -const std::string CONTENT_TYPE_APPLICATION_OCTET_STREAM = "application/octet-stream"s; -const std::string CONTENT_TYPE_APPLICATION_OGG = "application/ogg"s; -const std::string CONTENT_TYPE_APPLICATION_PDF = "application/pdf"s; -const std::string CONTENT_TYPE_APPLICATION_XHTML_XML = "application/xhtml+xml"s; -const std::string CONTENT_TYPE_APPLICATION_X_SHOCKWAVE_FLASH = "application/x-shockwave-flash"s; -const std::string CONTENT_TYPE_APPLICATION_JSON = "application/json"s; -const std::string CONTENT_TYPE_APPLICATION_LD_JSON = "application/ld+json"s; -const std::string CONTENT_TYPE_APPLICATION_XML = "application/xml"s; -const std::string CONTENT_TYPE_APPLICATION_ZIP = "application/zip"s; -const std::string CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"s; - -auto to_string(ContentType content_type) -> const std::string& +auto to_string(content_type ct) -> const std::string& { - switch (content_type) + switch (ct) { - case ContentType::NO_CONTENT: - return CONTENT_TYPE_NO_CONTENT; - - case ContentType::TEXT_CSS: - return CONTENT_TYPE_TEXT_CSS; - case ContentType::TEXT_CSV: - return CONTENT_TYPE_TEXT_CSV; - case ContentType::TEXT_HTML: - return CONTENT_TYPE_TEXT_HTML; - case ContentType::TEXT_PLAIN: - return CONTENT_TYPE_TEXT_PLAIN; - case ContentType::TEXT_XML: - return CONTENT_TYPE_TEXT_XML; - - case ContentType::IMAGE_GIF: - return CONTENT_TYPE_IMAGE_GIF; - case ContentType::IMAGE_JPEG: - return CONTENT_TYPE_IMAGE_JPEG; - case ContentType::IMAGE_PNG: - return CONTENT_TYPE_IMAGE_PNG; - case ContentType::IMAGE_TIFF: - return CONTENT_TYPE_IMAGE_TIFF; - case ContentType::IMAGE_X_ICON: - return CONTENT_TYPE_IMAGE_X_ICON; - case ContentType::IMAGE_SVG_XML: - return CONTENT_TYPE_IMAGE_SVG_XML; - - case ContentType::VIDEO_MPEG: - return CONTENT_TYPE_VIDEO_MPEG; - case ContentType::VIDEO_MP4: - return CONTENT_TYPE_VIDEO_MP4; - case ContentType::VIDEO_X_FLV: - return CONTENT_TYPE_VIDEO_X_FLV; - case ContentType::VIDEO_WEBM: - return CONTENT_TYPE_VIDEO_WEBM; - - case ContentType::MULTIPART_MIXED: - return CONTENT_TYPE_MULTIPART_MIXED; - case ContentType::MULTIPART_ALTERNATIVE: - return CONTENT_TYPE_MULTIPART_ALTERNATIVE; - case ContentType::MULTIPART_RELATED: - return CONTENT_TYPE_MULTIPART_RELATED; - case ContentType::MULTIPART_FORM_DATA: - return CONTENT_TYPE_MULTIPART_FORM_DATA; - - case ContentType::AUDIO_MPEG: - return CONTENT_TYPE_AUDIO_MPEG; - case ContentType::AUDIO_X_MS_WMA: - return CONTENT_TYPE_AUDIO_X_MS_WMA; - case ContentType::AUDIO_X_WAV: - return CONTENT_TYPE_AUDIO_X_WAV; - - case ContentType::APPLICATION_JAVASCRIPT: - return CONTENT_TYPE_APPLICATION_JAVASCRIPT; - case ContentType::APPLICATION_OCTET_STREAM: - return CONTENT_TYPE_APPLICATION_OCTET_STREAM; - case ContentType::APPLICATION_OGG: - return CONTENT_TYPE_APPLICATION_OGG; - case ContentType::APPLICATION_PDF: - return CONTENT_TYPE_APPLICATION_PDF; - case ContentType::APPLICATION_XHTML_XML: - return CONTENT_TYPE_APPLICATION_XHTML_XML; - case ContentType::APPLICATION_X_SHOCKWAVE_FLASH: - return CONTENT_TYPE_APPLICATION_X_SHOCKWAVE_FLASH; - case ContentType::APPLICATION_JSON: - return CONTENT_TYPE_APPLICATION_JSON; - case ContentType::APPLICATION_LD_JSON: - return CONTENT_TYPE_APPLICATION_LD_JSON; - case ContentType::APPLICATION_XML: - return CONTENT_TYPE_APPLICATION_XML; - case ContentType::APPLICATION_ZIP: - return CONTENT_TYPE_APPLICATION_ZIP; - case ContentType::APPLICATION_X_WWW_FORM_URLENCODED: - return CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED; + case content_type::no_content: + return content_type_no_content; + + case content_type::text_css: + return content_type_text_css; + case content_type::text_csv: + return content_type_text_csv; + case content_type::text_html: + return content_type_text_html; + case content_type::text_plain: + return content_type_text_plain; + case content_type::text_xml: + return content_type_text_xml; + + case content_type::image_gif: + return content_type_image_gif; + case content_type::image_jpeg: + return content_type_image_jpeg; + case content_type::image_png: + return content_type_image_png; + case content_type::image_tiff: + return content_type_image_tiff; + case content_type::image_x_icon: + return content_type_image_x_icon; + case content_type::image_svg_xml: + return content_type_image_svg_xml; + + case content_type::video_mpeg: + return content_type_video_mpeg; + case content_type::video_mp4: + return content_type_video_mp4; + case content_type::video_x_flv: + return content_type_video_x_flv; + case content_type::video_webm: + return content_type_video_webm; + + case content_type::multipart_mixed: + return content_type_multipart_mixed; + case content_type::multipart_alternative: + return content_type_multipart_alternative; + case content_type::multipart_related: + return content_type_multipart_related; + case content_type::multipart_form_data: + return content_type_multipart_form_data; + + case content_type::audio_mpeg: + return content_type_audio_mpeg; + case content_type::audio_x_ms_wma: + return content_type_audio_x_ms_wma; + case content_type::audio_x_wav: + return content_type_audio_x_wav; + + case content_type::application_javascript: + return content_type_application_javascript; + case content_type::application_octet_stream: + return content_type_application_octet_stream; + case content_type::application_ogg: + return content_type_application_ogg; + case content_type::application_pdf: + return content_type_application_pdf; + case content_type::application_xhtml_xml: + return content_type_application_xhtml_xml; + case content_type::application_x_shockwave_flash: + return content_type_application_x_shockwave_flash; + case content_type::application_json: + return content_type_application_json; + case content_type::application_ld_json: + return content_type_application_ld_json; + case content_type::application_xml: + return content_type_application_xml; + case content_type::application_zip: + return content_type_application_zip; + case content_type::application_x_www_form_urlencoded: + return content_type_application_x_www_form_urlencoded; default: - return CONTENT_TYPE_UNKNOWN; + return content_type_unknown; } } -const std::string CONNECTION_TYPE_UNKNOWN = "UNKNOWN"s; -const std::string CONNECTION_TYPE_CLOSE = "close"s; -const std::string CONNECTION_TYPE_KEEP_ALIVE = "keep-alive"s; -const std::string CONNECTION_TYPE_UPGRADE = "upgrade"s; - -auto to_string(ConnectionType connection_type) -> const std::string& +auto to_string(connection_type ct) -> const std::string& { - switch (connection_type) + switch (ct) { - case ConnectionType::CLOSE: - return CONNECTION_TYPE_CLOSE; - case ConnectionType::KEEP_ALIVE: - return CONNECTION_TYPE_KEEP_ALIVE; - case ConnectionType::UPGRADE: - return CONNECTION_TYPE_UPGRADE; + case connection_type::close: + return connection_type_close; + case connection_type::keep_alive: + return connection_type_keep_alive; + case connection_type::upgrade: + return connection_type_upgrade; default: - return CONNECTION_TYPE_UNKNOWN; + return connection_type_unknown; } } diff --git a/src/request.cpp b/src/request.cpp index 36a169a..ea120a3 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -32,8 +32,8 @@ Request::Request( auto Request::Perform(SharePtr share_ptr) -> Response { - Executor executor{this, share_ptr.get()}; - return executor.perform(); + executor exe{this, share_ptr.get()}; + return exe.perform(); } auto Request::OnCompleteHandler(OnCompleteHandlerType on_complete_handler) -> void @@ -90,7 +90,7 @@ auto Request::Data(std::string data) -> void m_request_data_set = true; m_request_data = std::move(data); - m_method = http::Method::POST; + m_method = http::method::post; } auto Request::MimeField(lift::MimeField mime_field) -> void diff --git a/src/response.cpp b/src/response.cpp index 1aa3c53..3885e5c 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -5,8 +5,7 @@ namespace lift { Response::Response() { - m_headers.reserve(HEADER_DEFAULT_COUNT); - m_data.reserve(HEADER_DEFAULT_MEMORY_BYTES); + m_headers.reserve(header_default_count); } auto operator<<(std::ostream& os, const Response& r) -> std::ostream& @@ -14,10 +13,13 @@ auto operator<<(std::ostream& os, const Response& r) -> std::ostream& os << lift::http::to_string(r.m_version) << ' ' << lift::http::to_string(r.m_status_code) << "\r\n"; for (const auto& header : r.m_headers) { - os << header.HeaderFull() << "\r\n"; + os << header << "\r\n"; } os << "\r\n"; - os << std::string_view{r.m_data.data(), r.m_data.size()}; + if (!r.m_data.empty()) + { + os << std::string_view{r.m_data.data(), r.m_data.size()}; + } return os; } diff --git a/test/test_async_request.cpp b/test/test_async_request.cpp index 43f6b78..7c4099c 100644 --- a/test/test_async_request.cpp +++ b/test/test_async_request.cpp @@ -9,7 +9,7 @@ TEST_CASE("Async 100 requests") { constexpr std::size_t COUNT = 100; - lift::EventLoop ev{}; + lift::event_loop ev{}; for (std::size_t i = 0; i < COUNT; ++i) { @@ -18,13 +18,13 @@ TEST_CASE("Async 100 requests") std::chrono::seconds{1}, [](std::unique_ptr rh, lift::Response response) -> void { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); }); - ev.StartRequest(std::move(r)); + ev.start_request(std::move(r)); } - while (ev.ActiveRequestCount() > 0) + while (!ev.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds{10}); } @@ -34,7 +34,7 @@ TEST_CASE("Async batch 100 requests") { constexpr std::size_t COUNT = 100; - lift::EventLoop ev{}; + lift::event_loop ev{}; std::vector> handles{}; handles.reserve(COUNT); @@ -46,15 +46,15 @@ TEST_CASE("Async batch 100 requests") std::chrono::seconds{1}, [](std::unique_ptr, lift::Response response) -> void { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); }); handles.emplace_back(std::move(r)); } - ev.StartRequests(std::move(handles)); + ev.start_requests(std::move(handles)); - while (ev.ActiveRequestCount() > 0) + while (!ev.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds{10}); } @@ -62,7 +62,7 @@ TEST_CASE("Async batch 100 requests") TEST_CASE("Async POST request") { - lift::EventLoop ev{}; + lift::event_loop ev{}; std::string data = "DATA DATA DATA!"; @@ -71,29 +71,29 @@ TEST_CASE("Async POST request") std::chrono::seconds{60}, [&](std::unique_ptr, lift::Response response) { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_405_METHOD_NOT_ALLOWED); + REQUIRE(response.StatusCode() == lift::http::status_code::http_405_method_not_allowed); }); request->Data(data); - request->Method(lift::http::Method::POST); + request->Method(lift::http::method::post); request->FollowRedirects(true); - request->Version(lift::http::Version::V1_1); - // request->AddHeader("Expect", ""); + request->Version(lift::http::version::v1_1); + // request->header("Expect", ""); - ev.StartRequest(std::move(request)); + ev.start_request(std::move(request)); request = std::make_unique( "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", std::chrono::seconds{60}, [&](std::unique_ptr, lift::Response response) { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_405_METHOD_NOT_ALLOWED); + REQUIRE(response.StatusCode() == lift::http::status_code::http_405_method_not_allowed); }); request->Data(data); - request->Method(lift::http::Method::POST); + request->Method(lift::http::method::post); request->FollowRedirects(true); - request->Version(lift::http::Version::V1_1); + request->Version(lift::http::version::v1_1); // There was a bug where no expect header caused liblift to fail, test it explicitly request->Header("Expect", ""); - ev.StartRequest(std::move(request)); + ev.start_request(std::move(request)); } diff --git a/test/test_event_loop.cpp b/test/test_event_loop.cpp index f685bdc..f811aaf 100644 --- a/test/test_event_loop.cpp +++ b/test/test_event_loop.cpp @@ -2,37 +2,37 @@ #include "setup.hpp" #include -TEST_CASE("EventLoop Start event loop, then stop and add a request.") +TEST_CASE("event_loop Start event loop, then stop and add a request.") { - lift::EventLoop ev{}; + lift::event_loop ev{}; auto request = lift::Request::make_unique( "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", std::chrono::seconds{60}, [&](std::unique_ptr, lift::Response response) { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); }); - REQUIRE(ev.StartRequest(std::move(request))); + REQUIRE(ev.start_request(std::move(request))); request = lift::Request::make_unique( "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", std::chrono::seconds{60}, [&](std::unique_ptr, lift::Response response) { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); }); // Adding requests after stopping should return false that they cannot be started. - ev.Stop(); + ev.stop(); - REQUIRE_FALSE(ev.StartRequest(std::move(request))); + REQUIRE_FALSE(ev.start_request(std::move(request))); } -TEST_CASE("EventLoop Start event loop, then stop and add multiple requests.") +TEST_CASE("event_loop Start event loop, then stop and add multiple requests.") { - lift::EventLoop ev{}; + lift::event_loop ev{}; std::vector requests1; requests1.emplace_back(lift::Request::make_unique( @@ -40,7 +40,7 @@ TEST_CASE("EventLoop Start event loop, then stop and add multiple requests.") std::chrono::seconds{60}, [&](std::unique_ptr, lift::Response response) { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); })); std::vector requests2; @@ -49,17 +49,17 @@ TEST_CASE("EventLoop Start event loop, then stop and add multiple requests.") std::chrono::seconds{60}, [&](std::unique_ptr, lift::Response response) { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); })); - REQUIRE(ev.StartRequests(std::move(requests1))); - ev.Stop(); - REQUIRE_FALSE(ev.StartRequests(std::move(requests2))); + REQUIRE(ev.start_requests(std::move(requests1))); + ev.stop(); + REQUIRE_FALSE(ev.start_requests(std::move(requests2))); } -TEST_CASE("EventLoop Provide nullptr request") +TEST_CASE("event_loop Provide nullptr request") { - lift::EventLoop ev{}; + lift::event_loop ev{}; - REQUIRE_FALSE(ev.StartRequest(nullptr)); + REQUIRE_FALSE(ev.start_request(nullptr)); } diff --git a/test/test_header.cpp b/test/test_header.cpp index a2d5e9b..0f7d1a4 100644 --- a/test/test_header.cpp +++ b/test/test_header.cpp @@ -2,23 +2,23 @@ #include "setup.hpp" #include -TEST_CASE("Header basic") +TEST_CASE("header basic") { - lift::Header header{"name", "value"}; - REQUIRE(header.HeaderFull() == "name: value"); - REQUIRE(header.Name() == "name"); - REQUIRE(header.Value() == "value"); + lift::header h{"name", "value"}; + REQUIRE(h.data() == "name: value"); + REQUIRE(h.name() == "name"); + REQUIRE(h.value() == "value"); } -TEST_CASE("Header no value") +TEST_CASE("header no value") { - lift::Header header{"name", ""}; - REQUIRE(header.HeaderFull() == "name: "); - REQUIRE(header.Name() == "name"); - REQUIRE(header.Value() == ""); + lift::header h{"name", ""}; + REQUIRE(h.data() == "name: "); + REQUIRE(h.name() == "name"); + REQUIRE(h.value() == ""); } -TEST_CASE("Header request that re-allocates the underlying vector a lot") +TEST_CASE("header request that re-allocates the underlying vector a lot") { constexpr size_t N_HEADERS = 65'000; // lets make a lot of headers to re-allocate a few times @@ -39,28 +39,28 @@ TEST_CASE("Header request that re-allocates the underlying vector a lot") auto value = "value" + idx_str; auto header_full = name + ": " + value; - REQUIRE(header.HeaderFull() == header_full); - REQUIRE(header.Name() == name); - REQUIRE(header.Value() == value); + REQUIRE(header.data() == header_full); + REQUIRE(header.name() == name); + REQUIRE(header.value() == value); ++idx; } } -TEST_CASE("Header from full") +TEST_CASE("header from full") { - lift::Header header{"name: value"}; + lift::header h{"name: value"}; - REQUIRE(header.HeaderFull() == "name: value"); - REQUIRE(header.Name() == "name"); - REQUIRE(header.Value() == "value"); + REQUIRE(h.data() == "name: value"); + REQUIRE(h.name() == "name"); + REQUIRE(h.value() == "value"); } -TEST_CASE("Header lots of allocations in a vector (simulate Response)") +TEST_CASE("header lots of allocations in a vector (simulate Response)") { constexpr size_t N_HEADERS = 65'000; // lets make a lot of headers to re-allocate a few times - std::vector headers{}; + std::vector headers{}; for (size_t i = 0; i < N_HEADERS; ++i) { @@ -78,41 +78,41 @@ TEST_CASE("Header lots of allocations in a vector (simulate Response)") auto value = "value" + idx_str; auto header_full = name + ": " + value; - REQUIRE(header.HeaderFull() == header_full); - REQUIRE(header.Name() == name); - REQUIRE(header.Value() == value); + REQUIRE(header.data() == header_full); + REQUIRE(header.name() == name); + REQUIRE(header.value() == value); ++idx; } } -TEST_CASE("Header parsing : from full strings") +TEST_CASE("header parsing : from full strings") { { - lift::Header header{"name"}; - REQUIRE(header.HeaderFull() == "name: "); - REQUIRE(header.Name() == "name"); - REQUIRE(header.Value() == ""); + lift::header h{"name"}; + REQUIRE(h.data() == "name: "); + REQUIRE(h.name() == "name"); + REQUIRE(h.value() == ""); } { - lift::Header header{"name:"}; - REQUIRE(header.HeaderFull() == "name: "); - REQUIRE(header.Name() == "name"); - REQUIRE(header.Value() == ""); + lift::header h{"name:"}; + REQUIRE(h.data() == "name: "); + REQUIRE(h.name() == "name"); + REQUIRE(h.value() == ""); } { - lift::Header header{"name:x"}; - REQUIRE(header.HeaderFull() == "name: x"); - REQUIRE(header.Name() == "name"); - REQUIRE(header.Value() == "x"); + lift::header h{"name:x"}; + REQUIRE(h.data() == "name: x"); + REQUIRE(h.name() == "name"); + REQUIRE(h.value() == "x"); } { - lift::Header header{"name : x "}; - REQUIRE(header.HeaderFull() == "name : x "); - REQUIRE(header.Name() == "name "); - REQUIRE(header.Value() == " x "); + lift::header h{"name : x "}; + REQUIRE(h.data() == "name : x "); + REQUIRE(h.name() == "name "); + REQUIRE(h.value() == " x "); } } diff --git a/test/test_http.cpp b/test/test_http.cpp index b4a3b1a..d497513 100644 --- a/test/test_http.cpp +++ b/test/test_http.cpp @@ -2,248 +2,242 @@ #include "setup.hpp" #include -TEST_CASE("HTTP Method to_string") +TEST_CASE("HTTP method to_string") { using namespace lift::http; - REQUIRE(to_string(Method::GET) == METHOD_GET); - REQUIRE(to_string(Method::HEAD) == METHOD_HEAD); - REQUIRE(to_string(Method::POST) == METHOD_POST); - REQUIRE(to_string(Method::PUT) == METHOD_PUT); - REQUIRE(to_string(Method::DELETE) == METHOD_DELETE); - REQUIRE(to_string(Method::CONNECT) == METHOD_CONNECT); - REQUIRE(to_string(Method::OPTIONS) == METHOD_OPTIONS); - REQUIRE(to_string(Method::PATCH) == METHOD_PATCH); - REQUIRE(to_string(static_cast(1024)) == METHOD_UNKNOWN); + REQUIRE(to_string(method::get) == method_get); + REQUIRE(to_string(method::head) == method_head); + REQUIRE(to_string(method::post) == method_post); + REQUIRE(to_string(method::put) == method_put); + REQUIRE(to_string(method::delete_t) == method_delete); + REQUIRE(to_string(method::connect) == method_connect); + REQUIRE(to_string(method::options) == method_options); + REQUIRE(to_string(method::patch) == method_patch); + REQUIRE(to_string(method::unknown) == method_unknown); + REQUIRE(to_string(static_cast(1024)) == method_unknown); } -TEST_CASE("HTTP Version to_string") +TEST_CASE("HTTP version to_string") { using namespace lift::http; - REQUIRE(to_string(Version::USE_BEST) == VERSION_USE_BEST); - REQUIRE(to_string(Version::V1_0) == VERSION_V1_0); - REQUIRE(to_string(Version::V1_1) == VERSION_V1_1); - REQUIRE(to_string(Version::V2_0) == VERSION_V2_0); - REQUIRE(to_string(Version::V2_0_TLS) == VERSION_V2_0_TLS); - REQUIRE(to_string(Version::V2_0_ONLY) == VERSION_V2_0_ONLY); - REQUIRE(to_string(static_cast(255)) == VERSION_UNKNOWN); + REQUIRE(to_string(version::use_best) == version_use_best); + REQUIRE(to_string(version::v1_0) == version_v1_0); + REQUIRE(to_string(version::v1_1) == version_v1_1); + REQUIRE(to_string(version::v2_0) == version_v2_0); + REQUIRE(to_string(version::v2_0_tls) == version_v2_0_tls); + REQUIRE(to_string(version::v2_0_only) == version_v2_0_only); + REQUIRE(to_string(version::unknown) == version_unknown); + REQUIRE(to_string(static_cast(255)) == version_unknown); } -TEST_CASE("HTTP StatusCode to_string") +TEST_CASE("HTTP status_code to_string") { + // clang-format off using namespace lift::http; - REQUIRE(to_string(StatusCode::HTTP_UNKNOWN) == STATUS_CODE_HTTP_UNKNOWN); - REQUIRE(to_string(static_cast(9001)) == STATUS_CODE_HTTP_UNKNOWN); - - REQUIRE(to_string(StatusCode::HTTP_100_CONTINUE) == STATUS_CODE_HTTP_100_CONTINUE); - REQUIRE(to_string(StatusCode::HTTP_101_SWITCHING_PROTOCOLS) == STATUS_CODE_HTTP_101_SWITCHING_PROTOCOLS); - REQUIRE(to_string(StatusCode::HTTP_102_PROCESSING) == STATUS_CODE_HTTP_102_PROCESSING); - REQUIRE(to_string(StatusCode::HTTP_103_EARLY_HINTS) == STATUS_CODE_HTTP_103_EARLY_HINTS); - - REQUIRE(to_string(StatusCode::HTTP_200_OK) == STATUS_CODE_HTTP_200_OK); - REQUIRE(to_string(StatusCode::HTTP_201_CREATED) == STATUS_CODE_HTTP_201_CREATED); - REQUIRE(to_string(StatusCode::HTTP_202_ACCEPTED) == STATUS_CODE_HTTP_202_ACCEPTED); - REQUIRE( - to_string(StatusCode::HTTP_203_NON_AUTHORITATIVE_INFORMATION) == - STATUS_CODE_HTTP_203_NON_AUTHORITATIVE_INFORMATION); - REQUIRE(to_string(StatusCode::HTTP_204_NO_CONTENT) == STATUS_CODE_HTTP_204_NO_CONTENT); - REQUIRE(to_string(StatusCode::HTTP_205_RESET_CONTENT) == STATUS_CODE_HTTP_205_RESET_CONTENT); - REQUIRE(to_string(StatusCode::HTTP_206_PARTIAL_CONTENT) == STATUS_CODE_HTTP_206_PARTIAL_CONTENT); - REQUIRE(to_string(StatusCode::HTTP_207_MULTI_STATUS) == STATUS_CODE_HTTP_207_MULTI_STATUS); - REQUIRE(to_string(StatusCode::HTTP_208_ALREADY_REPORTED) == STATUS_CODE_HTTP_208_ALREADY_REPORTED); - REQUIRE(to_string(StatusCode::HTTP_226_IM_USED) == STATUS_CODE_HTTP_226_IM_USED); - - REQUIRE(to_string(StatusCode::HTTP_300_MULTIPLE_CHOICES) == STATUS_CODE_HTTP_300_MULTIPLE_CHOICES); - REQUIRE(to_string(StatusCode::HTTP_301_MOVED_PERMANENTLY) == STATUS_CODE_HTTP_301_MOVED_PERMANENTLY); - REQUIRE(to_string(StatusCode::HTTP_302_FOUND) == STATUS_CODE_HTTP_302_FOUND); - REQUIRE(to_string(StatusCode::HTTP_303_SEE_OTHER) == STATUS_CODE_HTTP_303_SEE_OTHER); - REQUIRE(to_string(StatusCode::HTTP_304_NOT_MODIFIED) == STATUS_CODE_HTTP_304_NOT_MODIFIED); - REQUIRE(to_string(StatusCode::HTTP_305_USE_PROXY) == STATUS_CODE_HTTP_305_USE_PROXY); - REQUIRE(to_string(StatusCode::HTTP_306_SWITCH_PROXY) == STATUS_CODE_HTTP_306_SWITCH_PROXY); - REQUIRE(to_string(StatusCode::HTTP_307_TEMPORARY_REDIRECT) == STATUS_CODE_HTTP_307_TEMPORARY_REDIRECT); - REQUIRE(to_string(StatusCode::HTTP_308_PERMANENT_REDIRECT) == STATUS_CODE_HTTP_308_PERMANENT_REDIRECT); - - REQUIRE(to_string(StatusCode::HTTP_400_BAD_REQUEST) == STATUS_CODE_HTTP_400_BAD_REQUEST); - REQUIRE(to_string(StatusCode::HTTP_401_UNAUTHORIZED) == STATUS_CODE_HTTP_401_UNAUTHORIZED); - REQUIRE(to_string(StatusCode::HTTP_402_PAYMENT_REQUIRED) == STATUS_CODE_HTTP_402_PAYMENT_REQUIRED); - REQUIRE(to_string(StatusCode::HTTP_403_FORBIDDEN) == STATUS_CODE_HTTP_403_FORBIDDEN); - REQUIRE(to_string(StatusCode::HTTP_404_NOT_FOUND) == STATUS_CODE_HTTP_404_NOT_FOUND); - REQUIRE(to_string(StatusCode::HTTP_405_METHOD_NOT_ALLOWED) == STATUS_CODE_HTTP_405_METHOD_NOT_ALLOWED); - REQUIRE(to_string(StatusCode::HTTP_406_NOT_ACCEPTABLE) == STATUS_CODE_HTTP_406_NOT_ACCEPTABLE); - REQUIRE( - to_string(StatusCode::HTTP_407_PROXY_AUTHENTICATION_REQUIRED) == - STATUS_CODE_HTTP_407_PROXY_AUTHENTICATION_REQUIRED); - REQUIRE(to_string(StatusCode::HTTP_408_REQUEST_TIMEOUT) == STATUS_CODE_HTTP_408_REQUEST_TIMEOUT); - REQUIRE(to_string(StatusCode::HTTP_409_CONFLICT) == STATUS_CODE_HTTP_409_CONFLICT); - REQUIRE(to_string(StatusCode::HTTP_410_GONE) == STATUS_CODE_HTTP_410_GONE); - REQUIRE(to_string(StatusCode::HTTP_411_LENGTH_REQUIRED) == STATUS_CODE_HTTP_411_LENGTH_REQUIRED); - REQUIRE(to_string(StatusCode::HTTP_412_PRECONDITION_FAILED) == STATUS_CODE_HTTP_412_PRECONDITION_FAILED); - REQUIRE(to_string(StatusCode::HTTP_413_PAYLOAD_TOO_LARGE) == STATUS_CODE_HTTP_413_PAYLOAD_TOO_LARGE); - REQUIRE(to_string(StatusCode::HTTP_414_URI_TOO_LONG) == STATUS_CODE_HTTP_414_URI_TOO_LONG); - REQUIRE(to_string(StatusCode::HTTP_415_UNSUPPORTED_MEDIA_TYPE) == STATUS_CODE_HTTP_415_UNSUPPORTED_MEDIA_TYPE); - REQUIRE(to_string(StatusCode::HTTP_416_RANGE_NOT_SATISFIABLE) == STATUS_CODE_HTTP_416_RANGE_NOT_SATISFIABLE); - REQUIRE(to_string(StatusCode::HTTP_417_EXPECTATION_FAILED) == STATUS_CODE_HTTP_417_EXPECTATION_FAILED); - REQUIRE(to_string(StatusCode::HTTP_418_IM_A_TEAPOT) == STATUS_CODE_HTTP_418_IM_A_TEAPOT); - REQUIRE(to_string(StatusCode::HTTP_421_MISDIRECTED_REQUEST) == STATUS_CODE_HTTP_421_MISDIRECTED_REQUEST); - REQUIRE(to_string(StatusCode::HTTP_422_UNPROCESSABLE_ENTITY) == STATUS_CODE_HTTP_422_UNPROCESSABLE_ENTITY); - REQUIRE(to_string(StatusCode::HTTP_423_LOCKED) == STATUS_CODE_HTTP_423_LOCKED); - REQUIRE(to_string(StatusCode::HTTP_424_FAILED_DEPENDENCY) == STATUS_CODE_HTTP_424_FAILED_DEPENDENCY); - REQUIRE(to_string(StatusCode::HTTP_425_TOO_EARLY) == STATUS_CODE_HTTP_425_TOO_EARLY); - REQUIRE(to_string(StatusCode::HTTP_426_UPGRADE_REQUIRED) == STATUS_CODE_HTTP_426_UPGRADE_REQUIRED); - REQUIRE(to_string(StatusCode::HTTP_428_PRECONDITION_REQUIRED) == STATUS_CODE_HTTP_428_PRECONDITION_REQUIRED); - REQUIRE(to_string(StatusCode::HTTP_429_TOO_MANY_REQUESTS) == STATUS_CODE_HTTP_429_TOO_MANY_REQUESTS); - REQUIRE( - to_string(StatusCode::HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE) == - STATUS_CODE_HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE); - REQUIRE( - to_string(StatusCode::HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS) == - STATUS_CODE_HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS); - - REQUIRE(to_string(StatusCode::HTTP_500_INTERNAL_SERVER_ERROR) == STATUS_CODE_HTTP_500_INTERNAL_SERVER_ERROR); - REQUIRE(to_string(StatusCode::HTTP_501_NOT_IMPLEMENTED) == STATUS_CODE_HTTP_501_NOT_IMPLEMENTED); - REQUIRE(to_string(StatusCode::HTTP_502_BAD_GATEWAY) == STATUS_CODE_HTTP_502_BAD_GATEWAY); - REQUIRE(to_string(StatusCode::HTTP_503_SERVICE_UNAVAILABLE) == STATUS_CODE_HTTP_503_SERVICE_UNAVAILABLE); - REQUIRE(to_string(StatusCode::HTTP_504_GATEWAY_TIMEOUT) == STATUS_CODE_HTTP_504_GATEWAY_TIMEOUT); - REQUIRE( - to_string(StatusCode::HTTP_505_HTTP_VERSION_NOT_SUPPORTED) == STATUS_CODE_HTTP_505_HTTP_VERSION_NOT_SUPPORTED); - REQUIRE(to_string(StatusCode::HTTP_506_VARIANT_ALSO_NEGOTIATES) == STATUS_CODE_HTTP_506_VARIANT_ALSO_NEGOTIATES); - REQUIRE(to_string(StatusCode::HTTP_507_INSUFFICIENT_STORAGE) == STATUS_CODE_HTTP_507_INSUFFICIENT_STORAGE); - REQUIRE(to_string(StatusCode::HTTP_508_LOOP_DETECTED) == STATUS_CODE_HTTP_508_LOOP_DETECTED); - REQUIRE(to_string(StatusCode::HTTP_510_NOT_EXTENDED) == STATUS_CODE_HTTP_510_NOT_EXTENDED); - REQUIRE( - to_string(StatusCode::HTTP_511_NETWORK_AUTHENTICATION_REQUIRED) == - STATUS_CODE_HTTP_511_NETWORK_AUTHENTICATION_REQUIRED); + REQUIRE(to_string(status_code::http_unknown) == status_code_http_unknown); + REQUIRE(to_string(static_cast(9001)) == status_code_http_unknown); + + REQUIRE(to_string(status_code::http_100_continue) == status_code_http_100_continue); + REQUIRE(to_string(status_code::http_101_switching_protocols) == status_code_http_101_switching_protocols); + REQUIRE(to_string(status_code::http_102_processing) == status_code_http_102_processing); + REQUIRE(to_string(status_code::http_103_early_hints) == status_code_http_103_early_hints); + + REQUIRE(to_string(status_code::http_200_ok) == status_code_http_200_ok); + REQUIRE(to_string(status_code::http_201_created) == status_code_http_201_created); + REQUIRE(to_string(status_code::http_202_accepted) == status_code_http_202_accepted); + REQUIRE(to_string(status_code::http_203_non_authoritative_information) == status_code_http_203_non_authoritative_information); + REQUIRE(to_string(status_code::http_204_no_content) == status_code_http_204_no_content); + REQUIRE(to_string(status_code::http_205_reset_content) == status_code_http_205_reset_content); + REQUIRE(to_string(status_code::http_206_partial_content) == status_code_http_206_partial_content); + REQUIRE(to_string(status_code::http_207_multi_status) == status_code_http_207_multi_status); + REQUIRE(to_string(status_code::http_208_already_reported) == status_code_http_208_already_reported); + REQUIRE(to_string(status_code::http_226_im_used) == status_code_http_226_im_used); + + REQUIRE(to_string(status_code::http_300_multiple_choices) == status_code_http_300_multiple_choices); + REQUIRE(to_string(status_code::http_301_moved_permanently) == status_code_http_301_moved_permanently); + REQUIRE(to_string(status_code::http_302_found) == status_code_http_302_found); + REQUIRE(to_string(status_code::http_303_see_other) == status_code_http_303_see_other); + REQUIRE(to_string(status_code::http_304_not_modified) == status_code_http_304_not_modified); + REQUIRE(to_string(status_code::http_305_use_proxy) == status_code_http_305_use_proxy); + REQUIRE(to_string(status_code::http_306_switch_proxy) == status_code_http_306_switch_proxy); + REQUIRE(to_string(status_code::http_307_temporary_redirect) == status_code_http_307_temporary_redirect); + REQUIRE(to_string(status_code::http_308_permanent_redirect) == status_code_http_308_permanent_redirect); + + REQUIRE(to_string(status_code::http_400_bad_request) == status_code_http_400_bad_request); + REQUIRE(to_string(status_code::http_401_unauthorized) == status_code_http_401_unauthorized); + REQUIRE(to_string(status_code::http_402_payment_required) == status_code_http_402_payment_required); + REQUIRE(to_string(status_code::http_403_forbidden) == status_code_http_403_forbidden); + REQUIRE(to_string(status_code::http_404_not_found) == status_code_http_404_not_found); + REQUIRE(to_string(status_code::http_405_method_not_allowed) == status_code_http_405_method_not_allowed); + REQUIRE(to_string(status_code::http_406_not_acceptable) == status_code_http_406_not_acceptable); + REQUIRE(to_string(status_code::http_407_proxy_authentication_required) == status_code_http_407_proxy_authentication_required); + REQUIRE(to_string(status_code::http_408_request_timeout) == status_code_http_408_request_timeout); + REQUIRE(to_string(status_code::http_409_conflict) == status_code_http_409_conflict); + REQUIRE(to_string(status_code::http_410_gone) == status_code_http_410_gone); + REQUIRE(to_string(status_code::http_411_length_required) == status_code_http_411_length_required); + REQUIRE(to_string(status_code::http_412_precondition_failed) == status_code_http_412_precondition_failed); + REQUIRE(to_string(status_code::http_413_payload_too_large) == status_code_http_413_payload_too_large); + REQUIRE(to_string(status_code::http_414_uri_too_long) == status_code_http_414_uri_too_long); + REQUIRE(to_string(status_code::http_415_unsupported_media_type) == status_code_http_415_unsupported_media_type); + REQUIRE(to_string(status_code::http_416_range_not_satisfiable) == status_code_http_416_range_not_satisfiable); + REQUIRE(to_string(status_code::http_417_expectation_failed) == status_code_http_417_expectation_failed); + REQUIRE(to_string(status_code::http_418_im_a_teapot) == status_code_http_418_im_a_teapot); + REQUIRE(to_string(status_code::http_421_misdirected_request) == status_code_http_421_misdirected_request); + REQUIRE(to_string(status_code::http_422_unprocessable_entity) == status_code_http_422_unprocessable_entity); + REQUIRE(to_string(status_code::http_423_locked) == status_code_http_423_locked); + REQUIRE(to_string(status_code::http_424_failed_dependency) == status_code_http_424_failed_dependency); + REQUIRE(to_string(status_code::http_425_too_early) == status_code_http_425_too_early); + REQUIRE(to_string(status_code::http_426_upgrade_required) == status_code_http_426_upgrade_required); + REQUIRE(to_string(status_code::http_428_precondition_required) == status_code_http_428_precondition_required); + REQUIRE(to_string(status_code::http_429_too_many_requests) == status_code_http_429_too_many_requests); + REQUIRE(to_string(status_code::http_431_request_header_fields_too_large) == status_code_http_431_request_header_fields_too_large); + REQUIRE(to_string(status_code::http_451_unavailable_for_legal_reasons) == status_code_http_451_unavailable_for_legal_reasons); + + REQUIRE(to_string(status_code::http_500_internal_server_error) == status_code_http_500_internal_server_error); + REQUIRE(to_string(status_code::http_501_not_implemented) == status_code_http_501_not_implemented); + REQUIRE(to_string(status_code::http_502_bad_gateway) == status_code_http_502_bad_gateway); + REQUIRE(to_string(status_code::http_503_service_unavailable) == status_code_http_503_service_unavailable); + REQUIRE(to_string(status_code::http_504_gateway_timeout) == status_code_http_504_gateway_timeout); + REQUIRE(to_string(status_code::http_505_http_version_not_supported) == status_code_http_505_http_version_not_supported); + REQUIRE(to_string(status_code::http_506_variant_also_negotiates) == status_code_http_506_variant_also_negotiates); + REQUIRE(to_string(status_code::http_507_insufficient_storage) == status_code_http_507_insufficient_storage); + REQUIRE(to_string(status_code::http_508_loop_detected) == status_code_http_508_loop_detected); + REQUIRE(to_string(status_code::http_510_not_extended) == status_code_http_510_not_extended); + REQUIRE(to_string(status_code::http_511_network_authentication_required) == status_code_http_511_network_authentication_required); + // clang-format on } -TEST_CASE("HTTP StatusCode to_enum") +TEST_CASE("HTTP status_code to_enum") { using namespace lift::http; - REQUIRE(to_enum(0) == StatusCode::HTTP_UNKNOWN); - REQUIRE(to_enum(9001) == StatusCode::HTTP_UNKNOWN); - - REQUIRE(to_enum(100) == StatusCode::HTTP_100_CONTINUE); - REQUIRE(to_enum(101) == StatusCode::HTTP_101_SWITCHING_PROTOCOLS); - REQUIRE(to_enum(102) == StatusCode::HTTP_102_PROCESSING); - REQUIRE(to_enum(103) == StatusCode::HTTP_103_EARLY_HINTS); - - REQUIRE(to_enum(200) == StatusCode::HTTP_200_OK); - REQUIRE(to_enum(201) == StatusCode::HTTP_201_CREATED); - REQUIRE(to_enum(202) == StatusCode::HTTP_202_ACCEPTED); - REQUIRE(to_enum(203) == StatusCode::HTTP_203_NON_AUTHORITATIVE_INFORMATION); - REQUIRE(to_enum(204) == StatusCode::HTTP_204_NO_CONTENT); - REQUIRE(to_enum(205) == StatusCode::HTTP_205_RESET_CONTENT); - REQUIRE(to_enum(206) == StatusCode::HTTP_206_PARTIAL_CONTENT); - REQUIRE(to_enum(207) == StatusCode::HTTP_207_MULTI_STATUS); - REQUIRE(to_enum(208) == StatusCode::HTTP_208_ALREADY_REPORTED); - REQUIRE(to_enum(226) == StatusCode::HTTP_226_IM_USED); - - REQUIRE(to_enum(300) == StatusCode::HTTP_300_MULTIPLE_CHOICES); - REQUIRE(to_enum(301) == StatusCode::HTTP_301_MOVED_PERMANENTLY); - REQUIRE(to_enum(302) == StatusCode::HTTP_302_FOUND); - REQUIRE(to_enum(303) == StatusCode::HTTP_303_SEE_OTHER); - REQUIRE(to_enum(304) == StatusCode::HTTP_304_NOT_MODIFIED); - REQUIRE(to_enum(305) == StatusCode::HTTP_305_USE_PROXY); - REQUIRE(to_enum(306) == StatusCode::HTTP_306_SWITCH_PROXY); - REQUIRE(to_enum(307) == StatusCode::HTTP_307_TEMPORARY_REDIRECT); - REQUIRE(to_enum(308) == StatusCode::HTTP_308_PERMANENT_REDIRECT); - - REQUIRE(to_enum(400) == StatusCode::HTTP_400_BAD_REQUEST); - REQUIRE(to_enum(401) == StatusCode::HTTP_401_UNAUTHORIZED); - REQUIRE(to_enum(402) == StatusCode::HTTP_402_PAYMENT_REQUIRED); - REQUIRE(to_enum(403) == StatusCode::HTTP_403_FORBIDDEN); - REQUIRE(to_enum(404) == StatusCode::HTTP_404_NOT_FOUND); - REQUIRE(to_enum(405) == StatusCode::HTTP_405_METHOD_NOT_ALLOWED); - REQUIRE(to_enum(406) == StatusCode::HTTP_406_NOT_ACCEPTABLE); - REQUIRE(to_enum(407) == StatusCode::HTTP_407_PROXY_AUTHENTICATION_REQUIRED); - REQUIRE(to_enum(408) == StatusCode::HTTP_408_REQUEST_TIMEOUT); - REQUIRE(to_enum(409) == StatusCode::HTTP_409_CONFLICT); - REQUIRE(to_enum(410) == StatusCode::HTTP_410_GONE); - REQUIRE(to_enum(411) == StatusCode::HTTP_411_LENGTH_REQUIRED); - REQUIRE(to_enum(412) == StatusCode::HTTP_412_PRECONDITION_FAILED); - REQUIRE(to_enum(413) == StatusCode::HTTP_413_PAYLOAD_TOO_LARGE); - REQUIRE(to_enum(414) == StatusCode::HTTP_414_URI_TOO_LONG); - REQUIRE(to_enum(415) == StatusCode::HTTP_415_UNSUPPORTED_MEDIA_TYPE); - REQUIRE(to_enum(416) == StatusCode::HTTP_416_RANGE_NOT_SATISFIABLE); - REQUIRE(to_enum(417) == StatusCode::HTTP_417_EXPECTATION_FAILED); - REQUIRE(to_enum(418) == StatusCode::HTTP_418_IM_A_TEAPOT); - REQUIRE(to_enum(421) == StatusCode::HTTP_421_MISDIRECTED_REQUEST); - REQUIRE(to_enum(422) == StatusCode::HTTP_422_UNPROCESSABLE_ENTITY); - REQUIRE(to_enum(423) == StatusCode::HTTP_423_LOCKED); - REQUIRE(to_enum(424) == StatusCode::HTTP_424_FAILED_DEPENDENCY); - REQUIRE(to_enum(425) == StatusCode::HTTP_425_TOO_EARLY); - REQUIRE(to_enum(426) == StatusCode::HTTP_426_UPGRADE_REQUIRED); - REQUIRE(to_enum(428) == StatusCode::HTTP_428_PRECONDITION_REQUIRED); - REQUIRE(to_enum(429) == StatusCode::HTTP_429_TOO_MANY_REQUESTS); - REQUIRE(to_enum(431) == StatusCode::HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE); - REQUIRE(to_enum(451) == StatusCode::HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS); - - REQUIRE(to_enum(500) == StatusCode::HTTP_500_INTERNAL_SERVER_ERROR); - REQUIRE(to_enum(501) == StatusCode::HTTP_501_NOT_IMPLEMENTED); - REQUIRE(to_enum(502) == StatusCode::HTTP_502_BAD_GATEWAY); - REQUIRE(to_enum(503) == StatusCode::HTTP_503_SERVICE_UNAVAILABLE); - REQUIRE(to_enum(504) == StatusCode::HTTP_504_GATEWAY_TIMEOUT); - REQUIRE(to_enum(505) == StatusCode::HTTP_505_HTTP_VERSION_NOT_SUPPORTED); - REQUIRE(to_enum(506) == StatusCode::HTTP_506_VARIANT_ALSO_NEGOTIATES); - REQUIRE(to_enum(507) == StatusCode::HTTP_507_INSUFFICIENT_STORAGE); - REQUIRE(to_enum(508) == StatusCode::HTTP_508_LOOP_DETECTED); - REQUIRE(to_enum(510) == StatusCode::HTTP_510_NOT_EXTENDED); - REQUIRE(to_enum(511) == StatusCode::HTTP_511_NETWORK_AUTHENTICATION_REQUIRED); + REQUIRE(to_enum(0) == status_code::http_unknown); + REQUIRE(to_enum(9001) == status_code::http_unknown); + + REQUIRE(to_enum(100) == status_code::http_100_continue); + REQUIRE(to_enum(101) == status_code::http_101_switching_protocols); + REQUIRE(to_enum(102) == status_code::http_102_processing); + REQUIRE(to_enum(103) == status_code::http_103_early_hints); + + REQUIRE(to_enum(200) == status_code::http_200_ok); + REQUIRE(to_enum(201) == status_code::http_201_created); + REQUIRE(to_enum(202) == status_code::http_202_accepted); + REQUIRE(to_enum(203) == status_code::http_203_non_authoritative_information); + REQUIRE(to_enum(204) == status_code::http_204_no_content); + REQUIRE(to_enum(205) == status_code::http_205_reset_content); + REQUIRE(to_enum(206) == status_code::http_206_partial_content); + REQUIRE(to_enum(207) == status_code::http_207_multi_status); + REQUIRE(to_enum(208) == status_code::http_208_already_reported); + REQUIRE(to_enum(226) == status_code::http_226_im_used); + + REQUIRE(to_enum(300) == status_code::http_300_multiple_choices); + REQUIRE(to_enum(301) == status_code::http_301_moved_permanently); + REQUIRE(to_enum(302) == status_code::http_302_found); + REQUIRE(to_enum(303) == status_code::http_303_see_other); + REQUIRE(to_enum(304) == status_code::http_304_not_modified); + REQUIRE(to_enum(305) == status_code::http_305_use_proxy); + REQUIRE(to_enum(306) == status_code::http_306_switch_proxy); + REQUIRE(to_enum(307) == status_code::http_307_temporary_redirect); + REQUIRE(to_enum(308) == status_code::http_308_permanent_redirect); + + REQUIRE(to_enum(400) == status_code::http_400_bad_request); + REQUIRE(to_enum(401) == status_code::http_401_unauthorized); + REQUIRE(to_enum(402) == status_code::http_402_payment_required); + REQUIRE(to_enum(403) == status_code::http_403_forbidden); + REQUIRE(to_enum(404) == status_code::http_404_not_found); + REQUIRE(to_enum(405) == status_code::http_405_method_not_allowed); + REQUIRE(to_enum(406) == status_code::http_406_not_acceptable); + REQUIRE(to_enum(407) == status_code::http_407_proxy_authentication_required); + REQUIRE(to_enum(408) == status_code::http_408_request_timeout); + REQUIRE(to_enum(409) == status_code::http_409_conflict); + REQUIRE(to_enum(410) == status_code::http_410_gone); + REQUIRE(to_enum(411) == status_code::http_411_length_required); + REQUIRE(to_enum(412) == status_code::http_412_precondition_failed); + REQUIRE(to_enum(413) == status_code::http_413_payload_too_large); + REQUIRE(to_enum(414) == status_code::http_414_uri_too_long); + REQUIRE(to_enum(415) == status_code::http_415_unsupported_media_type); + REQUIRE(to_enum(416) == status_code::http_416_range_not_satisfiable); + REQUIRE(to_enum(417) == status_code::http_417_expectation_failed); + REQUIRE(to_enum(418) == status_code::http_418_im_a_teapot); + REQUIRE(to_enum(421) == status_code::http_421_misdirected_request); + REQUIRE(to_enum(422) == status_code::http_422_unprocessable_entity); + REQUIRE(to_enum(423) == status_code::http_423_locked); + REQUIRE(to_enum(424) == status_code::http_424_failed_dependency); + REQUIRE(to_enum(425) == status_code::http_425_too_early); + REQUIRE(to_enum(426) == status_code::http_426_upgrade_required); + REQUIRE(to_enum(428) == status_code::http_428_precondition_required); + REQUIRE(to_enum(429) == status_code::http_429_too_many_requests); + REQUIRE(to_enum(431) == status_code::http_431_request_header_fields_too_large); + REQUIRE(to_enum(451) == status_code::http_451_unavailable_for_legal_reasons); + + REQUIRE(to_enum(500) == status_code::http_500_internal_server_error); + REQUIRE(to_enum(501) == status_code::http_501_not_implemented); + REQUIRE(to_enum(502) == status_code::http_502_bad_gateway); + REQUIRE(to_enum(503) == status_code::http_503_service_unavailable); + REQUIRE(to_enum(504) == status_code::http_504_gateway_timeout); + REQUIRE(to_enum(505) == status_code::http_505_http_version_not_supported); + REQUIRE(to_enum(506) == status_code::http_506_variant_also_negotiates); + REQUIRE(to_enum(507) == status_code::http_507_insufficient_storage); + REQUIRE(to_enum(508) == status_code::http_508_loop_detected); + REQUIRE(to_enum(510) == status_code::http_510_not_extended); + REQUIRE(to_enum(511) == status_code::http_511_network_authentication_required); } -TEST_CASE("HTTP ContentType to_string") +TEST_CASE("HTTP content_type to_string") { + // clang-format off using namespace lift::http; - REQUIRE(to_string(ContentType::UNKNOWN) == CONTENT_TYPE_UNKNOWN); - REQUIRE(to_string(static_cast(928384)) == CONTENT_TYPE_UNKNOWN); - - REQUIRE(to_string(ContentType::NO_CONTENT) == CONTENT_TYPE_NO_CONTENT); - - REQUIRE(to_string(ContentType::TEXT_CSS) == CONTENT_TYPE_TEXT_CSS); - REQUIRE(to_string(ContentType::TEXT_CSV) == CONTENT_TYPE_TEXT_CSV); - REQUIRE(to_string(ContentType::TEXT_HTML) == CONTENT_TYPE_TEXT_HTML); - REQUIRE(to_string(ContentType::TEXT_PLAIN) == CONTENT_TYPE_TEXT_PLAIN); - REQUIRE(to_string(ContentType::TEXT_XML) == CONTENT_TYPE_TEXT_XML); - - REQUIRE(to_string(ContentType::IMAGE_GIF) == CONTENT_TYPE_IMAGE_GIF); - REQUIRE(to_string(ContentType::IMAGE_JPEG) == CONTENT_TYPE_IMAGE_JPEG); - REQUIRE(to_string(ContentType::IMAGE_PNG) == CONTENT_TYPE_IMAGE_PNG); - REQUIRE(to_string(ContentType::IMAGE_TIFF) == CONTENT_TYPE_IMAGE_TIFF); - REQUIRE(to_string(ContentType::IMAGE_X_ICON) == CONTENT_TYPE_IMAGE_X_ICON); - REQUIRE(to_string(ContentType::IMAGE_SVG_XML) == CONTENT_TYPE_IMAGE_SVG_XML); - - REQUIRE(to_string(ContentType::VIDEO_MPEG) == CONTENT_TYPE_VIDEO_MPEG); - REQUIRE(to_string(ContentType::VIDEO_MP4) == CONTENT_TYPE_VIDEO_MP4); - REQUIRE(to_string(ContentType::VIDEO_X_FLV) == CONTENT_TYPE_VIDEO_X_FLV); - REQUIRE(to_string(ContentType::VIDEO_WEBM) == CONTENT_TYPE_VIDEO_WEBM); - - REQUIRE(to_string(ContentType::MULTIPART_MIXED) == CONTENT_TYPE_MULTIPART_MIXED); - REQUIRE(to_string(ContentType::MULTIPART_ALTERNATIVE) == CONTENT_TYPE_MULTIPART_ALTERNATIVE); - REQUIRE(to_string(ContentType::MULTIPART_RELATED) == CONTENT_TYPE_MULTIPART_RELATED); - REQUIRE(to_string(ContentType::MULTIPART_FORM_DATA) == CONTENT_TYPE_MULTIPART_FORM_DATA); - - REQUIRE(to_string(ContentType::AUDIO_MPEG) == CONTENT_TYPE_AUDIO_MPEG); - REQUIRE(to_string(ContentType::AUDIO_X_MS_WMA) == CONTENT_TYPE_AUDIO_X_MS_WMA); - REQUIRE(to_string(ContentType::AUDIO_X_WAV) == CONTENT_TYPE_AUDIO_X_WAV); - - REQUIRE(to_string(ContentType::APPLICATION_JAVASCRIPT) == CONTENT_TYPE_APPLICATION_JAVASCRIPT); - REQUIRE(to_string(ContentType::APPLICATION_OCTET_STREAM) == CONTENT_TYPE_APPLICATION_OCTET_STREAM); - REQUIRE(to_string(ContentType::APPLICATION_OGG) == CONTENT_TYPE_APPLICATION_OGG); - REQUIRE(to_string(ContentType::APPLICATION_PDF) == CONTENT_TYPE_APPLICATION_PDF); - REQUIRE(to_string(ContentType::APPLICATION_XHTML_XML) == CONTENT_TYPE_APPLICATION_XHTML_XML); - REQUIRE(to_string(ContentType::APPLICATION_X_SHOCKWAVE_FLASH) == CONTENT_TYPE_APPLICATION_X_SHOCKWAVE_FLASH); - REQUIRE(to_string(ContentType::APPLICATION_JSON) == CONTENT_TYPE_APPLICATION_JSON); - REQUIRE(to_string(ContentType::APPLICATION_LD_JSON) == CONTENT_TYPE_APPLICATION_LD_JSON); - REQUIRE(to_string(ContentType::APPLICATION_XML) == CONTENT_TYPE_APPLICATION_XML); - REQUIRE(to_string(ContentType::APPLICATION_ZIP) == CONTENT_TYPE_APPLICATION_ZIP); - REQUIRE( - to_string(ContentType::APPLICATION_X_WWW_FORM_URLENCODED) == CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED); + REQUIRE(to_string(content_type::unknown) == content_type_unknown); + REQUIRE(to_string(static_cast(45678)) == content_type_unknown); + + REQUIRE(to_string(content_type::no_content) == content_type_no_content); + + REQUIRE(to_string(content_type::text_css) == content_type_text_css); + REQUIRE(to_string(content_type::text_csv) == content_type_text_csv); + REQUIRE(to_string(content_type::text_html) == content_type_text_html); + REQUIRE(to_string(content_type::text_plain) == content_type_text_plain); + REQUIRE(to_string(content_type::text_xml) == content_type_text_xml); + + REQUIRE(to_string(content_type::image_gif) == content_type_image_gif); + REQUIRE(to_string(content_type::image_jpeg) == content_type_image_jpeg); + REQUIRE(to_string(content_type::image_png) == content_type_image_png); + REQUIRE(to_string(content_type::image_tiff) == content_type_image_tiff); + REQUIRE(to_string(content_type::image_x_icon) == content_type_image_x_icon); + REQUIRE(to_string(content_type::image_svg_xml) == content_type_image_svg_xml); + + REQUIRE(to_string(content_type::video_mpeg) == content_type_video_mpeg); + REQUIRE(to_string(content_type::video_mp4) == content_type_video_mp4); + REQUIRE(to_string(content_type::video_x_flv) == content_type_video_x_flv); + REQUIRE(to_string(content_type::video_webm) == content_type_video_webm); + + REQUIRE(to_string(content_type::multipart_mixed) == content_type_multipart_mixed); + REQUIRE(to_string(content_type::multipart_alternative) == content_type_multipart_alternative); + REQUIRE(to_string(content_type::multipart_related) == content_type_multipart_related); + REQUIRE(to_string(content_type::multipart_form_data) == content_type_multipart_form_data); + + REQUIRE(to_string(content_type::audio_mpeg) == content_type_audio_mpeg); + REQUIRE(to_string(content_type::audio_x_ms_wma) == content_type_audio_x_ms_wma); + REQUIRE(to_string(content_type::audio_x_wav) == content_type_audio_x_wav); + + REQUIRE(to_string(content_type::application_javascript) == content_type_application_javascript); + REQUIRE(to_string(content_type::application_octet_stream) == content_type_application_octet_stream); + REQUIRE(to_string(content_type::application_ogg) == content_type_application_ogg); + REQUIRE(to_string(content_type::application_pdf) == content_type_application_pdf); + REQUIRE(to_string(content_type::application_xhtml_xml) == content_type_application_xhtml_xml); + REQUIRE(to_string(content_type::application_x_shockwave_flash) == content_type_application_x_shockwave_flash); + REQUIRE(to_string(content_type::application_json) == content_type_application_json); + REQUIRE(to_string(content_type::application_ld_json) == content_type_application_ld_json); + REQUIRE(to_string(content_type::application_xml) == content_type_application_xml); + REQUIRE(to_string(content_type::application_zip) == content_type_application_zip); + REQUIRE(to_string(content_type::application_x_www_form_urlencoded) == content_type_application_x_www_form_urlencoded); + // clang-format on } -TEST_CASE("HTTP ConnectionType to_string") +TEST_CASE("HTTP connection_type to_string") { using namespace lift::http; - REQUIRE(to_string(ConnectionType::CLOSE) == CONNECTION_TYPE_CLOSE); - REQUIRE(to_string(ConnectionType::KEEP_ALIVE) == CONNECTION_TYPE_KEEP_ALIVE); - REQUIRE(to_string(ConnectionType::UPGRADE) == CONNECTION_TYPE_UPGRADE); - REQUIRE(to_string(static_cast(3839)) == CONNECTION_TYPE_UNKNOWN); + REQUIRE(to_string(connection_type::close) == connection_type_close); + REQUIRE(to_string(connection_type::keep_alive) == connection_type_keep_alive); + REQUIRE(to_string(connection_type::upgrade) == connection_type_upgrade); + REQUIRE(to_string(static_cast(3839)) == connection_type_unknown); } diff --git a/test/test_proxy.cpp b/test/test_proxy.cpp index 7c1b482..ad08ec6 100644 --- a/test/test_proxy.cpp +++ b/test/test_proxy.cpp @@ -13,21 +13,21 @@ TEST_CASE("Proxy") const auto& response = request.Perform(); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); for (const auto& header : response.Headers()) { - if (header.Name() == "server") + if (header.name() == "server") { - REQUIRE(header.Value() == "nginx/1.18.0"); + REQUIRE(header.value() == "nginx/1.18.0"); } - else if (header.Name() == "content-length") + else if (header.name() == "content-length") { - uint64_t content_length = std::stoul(std::string{header.Value()}); + uint64_t content_length = std::stoul(std::string{header.value()}); REQUIRE(content_length > 0); } - else if (header.Name() == "content-type") + else if (header.name() == "content-type") { - REQUIRE(header.Value() == "text/html"); + REQUIRE(header.value() == "text/html"); } } } @@ -46,21 +46,21 @@ TEST_CASE("Proxy Basic Auth") const auto& response = request.Perform(); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); for (const auto& header : response.Headers()) { - if (header.Name() == "server") + if (header.name() == "server") { - REQUIRE(header.Value() == "nginx/1.18.0"); + REQUIRE(header.value() == "nginx/1.18.0"); } - else if (header.Name() == "content-length") + else if (header.name() == "content-length") { - uint64_t content_length = std::stoul(std::string{header.Value()}); + uint64_t content_length = std::stoul(std::string{header.value()}); REQUIRE(content_length > 0); } - else if (header.Name() == "content-type") + else if (header.name() == "content-type") { - REQUIRE(header.Value() == "text/html"); + REQUIRE(header.value() == "text/html"); } } } @@ -79,21 +79,21 @@ TEST_CASE("Proxy Any Auth") const auto& response = request.Perform(); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); for (const auto& header : response.Headers()) { - if (header.Name() == "server") + if (header.name() == "server") { - REQUIRE(header.Value() == "nginx/1.18.0"); + REQUIRE(header.value() == "nginx/1.18.0"); } - else if (header.Name() == "content-length") + else if (header.name() == "content-length") { - uint64_t content_length = std::stoul(std::string{header.Value()}); + uint64_t content_length = std::stoul(std::string{header.value()}); REQUIRE(content_length > 0); } - else if (header.Name() == "content-type") + else if (header.name() == "content-type") { - REQUIRE(header.Value() == "text/html"); + REQUIRE(header.value() == "text/html"); } } } diff --git a/test/test_resolve_host.cpp b/test/test_resolve_host.cpp index 3f94bee..41854d2 100644 --- a/test/test_resolve_host.cpp +++ b/test/test_resolve_host.cpp @@ -16,20 +16,20 @@ TEST_CASE("ResolveHost synchronous perform") auto response = request.Perform(); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); } -TEST_CASE("EventLoop ResolveHost") +TEST_CASE("ResolveHost event_loop") { std::vector rhosts{ lift::ResolveHost{"testhostname", NGINX_PORT, SERVICE_IP_ADDRESS}, lift::ResolveHost{"herpderp.com", NGINX_PORT, SERVICE_IP_ADDRESS}}; - lift::EventLoop ev{std::nullopt, std::nullopt, std::nullopt, std::move(rhosts)}; + lift::event_loop ev{lift::event_loop::options{.resolve_hosts = std::move(rhosts)}}; auto on_complete = [&](lift::RequestPtr, lift::Response response) -> void { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); }; std::vector requests; @@ -38,5 +38,5 @@ TEST_CASE("EventLoop ResolveHost") requests.emplace_back( lift::Request::make_unique("herpderp.com:" + NGINX_PORT_STR, std::chrono::seconds{60}, on_complete)); - REQUIRE(ev.StartRequests(std::move(requests))); + REQUIRE(ev.start_requests(std::move(requests))); } diff --git a/test/test_share.cpp b/test/test_share.cpp index 4134f0f..4980402 100644 --- a/test/test_share.cpp +++ b/test/test_share.cpp @@ -13,7 +13,7 @@ TEST_CASE("Share Requests ALL") auto response = request.Perform(lift_share_ptr); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); } } @@ -28,24 +28,24 @@ TEST_CASE("Share Requests NOTHING") auto response = request.Perform(lift_share_ptr); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); } } -TEST_CASE("Share EventLoop synchronous") +TEST_CASE("Share event_loop synchronous") { auto lift_share_ptr = std::make_shared(lift::ShareOptions::ALL); - lift::EventLoop ev1{std::nullopt, std::nullopt, std::nullopt, std::vector{}, lift_share_ptr}; + lift::event_loop ev1{lift::event_loop::options{.share_ptr = lift_share_ptr}}; - lift::EventLoop ev2{std::nullopt, std::nullopt, std::nullopt, std::vector{}, lift_share_ptr}; + lift::event_loop ev2{lift::event_loop::options{.share_ptr = lift_share_ptr}}; auto request1 = lift::Request::make_unique( "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", std::chrono::seconds{60}, [&](std::unique_ptr, lift::Response response) { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); }); auto request2 = lift::Request::make_unique( @@ -53,23 +53,23 @@ TEST_CASE("Share EventLoop synchronous") std::chrono::seconds{60}, [&](std::unique_ptr, lift::Response response) { REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); }); - ev1.StartRequest(std::move(request1)); + ev1.start_request(std::move(request1)); - while (ev1.ActiveRequestCount() > 0) + while (!ev1.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - ev2.StartRequest(std::move(request2)); + ev2.start_request(std::move(request2)); - ev1.Stop(); - ev2.Stop(); + ev1.stop(); + ev2.stop(); } -TEST_CASE("Share EventLoop overlapping requests") +TEST_CASE("Share event_loop overlapping requests") { std::atomic count{0}; @@ -84,13 +84,8 @@ TEST_CASE("Share EventLoop overlapping requests") } auto worker_func = [&count, &lift_share]() { - static size_t share_counter{0}; - lift::EventLoop event_loop{ - std::nullopt, - std::nullopt, - std::nullopt, - std::vector{}, - lift_share[share_counter++ % N_SHARE]}; + static size_t share_counter{0}; + lift::event_loop el{lift::event_loop::options{.share_ptr = lift_share[share_counter++ % N_SHARE]}}; for (size_t i = 0; i < N_REQUESTS; ++i) { @@ -101,12 +96,11 @@ TEST_CASE("Share EventLoop overlapping requests") count.fetch_add(1, std::memory_order_relaxed); }); - event_loop.StartRequest(std::move(request_ptr)); + el.start_request(std::move(request_ptr)); } - while (event_loop.ActiveRequestCount() > 0) + while (!el.empty()) { - // std::cerr << "Active=" << event_loop.ActiveRequestCount() << "\n"; std::this_thread::sleep_for(std::chrono::milliseconds(1)); } }; diff --git a/test/test_sync_request.cpp b/test/test_sync_request.cpp index 008ab5d..dcec870 100644 --- a/test/test_sync_request.cpp +++ b/test/test_sync_request.cpp @@ -10,7 +10,7 @@ TEST_CASE("Synchronous 200") const auto& response = request.Perform(); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); } TEST_CASE("Synchronous 404") @@ -19,17 +19,17 @@ TEST_CASE("Synchronous 404") const auto& response = request.Perform(); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_404_NOT_FOUND); + REQUIRE(response.StatusCode() == lift::http::status_code::http_404_not_found); } TEST_CASE("Synchronous HEAD") { lift::Request request("http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/"); - request.Method(lift::http::Method::HEAD); + request.Method(lift::http::method::head); const auto& response = request.Perform(); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); REQUIRE(response.Data().empty()); } @@ -40,9 +40,9 @@ TEST_CASE("Synchronous custom headers") for (const auto& header : request.Headers()) { - if (header.Name() == "x-custom-header-1") + if (header.name() == "x-custom-header-1") { - REQUIRE(header.Value() == "custom-value-1"); + REQUIRE(header.value() == "custom-value-1"); } } } @@ -59,35 +59,35 @@ TEST_CASE("Multiple headers added") const auto& response = request.Perform(); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); std::size_t count_found = 0; for (const auto& header : request.Headers()) { - if (header.Name() == "Connection") + if (header.name() == "Connection") { - REQUIRE(header.Value() == "keep-alive"); + REQUIRE(header.value() == "keep-alive"); ++count_found; } - else if (header.Name() == "x-custom-header-1") + else if (header.name() == "x-custom-header-1") { - REQUIRE(header.Value() == "value1"); + REQUIRE(header.value() == "value1"); ++count_found; } - else if (header.Name() == "x-custom-header-2") + else if (header.name() == "x-custom-header-2") { - REQUIRE(header.Value() == "value2"); + REQUIRE(header.value() == "value2"); ++count_found; } - else if (header.Name() == "x-herp-derp") + else if (header.name() == "x-herp-derp") { - REQUIRE(header.Value() == "merp"); + REQUIRE(header.value() == "merp"); ++count_found; } - else if (header.Name() == "x-420") + else if (header.name() == "x-420") { - REQUIRE(header.Value() == "blazeit"); + REQUIRE(header.value() == "blazeit"); ++count_found; } } @@ -104,7 +104,7 @@ TEST_CASE("Happy Eyeballs Test") const auto& response = request.Perform(); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); } TEST_CASE("SSL functions") diff --git a/test/test_timesup.cpp b/test/test_timesup.cpp index 4528b0e..e8f86bc 100644 --- a/test/test_timesup.cpp +++ b/test/test_timesup.cpp @@ -7,22 +7,22 @@ TEST_CASE("Timesup single request") { - lift::EventLoop ev{std::nullopt, std::nullopt, {std::chrono::seconds{1}}}; + lift::event_loop ev{lift::event_loop::options{.connect_timeout = std::chrono::seconds{1}}}; auto r = lift::Request::make_unique( "http://www.reddit.com", // should be slow enough /shrug std::chrono::milliseconds{25}, [](std::unique_ptr rh, lift::Response response) -> void { REQUIRE(response.LiftStatus() == lift::LiftStatus::TIMEOUT); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_504_GATEWAY_TIMEOUT); + REQUIRE(response.StatusCode() == lift::http::status_code::http_504_gateway_timeout); REQUIRE(response.TotalTime() == std::chrono::milliseconds{25}); REQUIRE(response.NumConnects() == 0); REQUIRE(response.NumRedirects() == 0); }); - ev.StartRequest(std::move(r)); + ev.start_request(std::move(r)); - while (ev.ActiveRequestCount() > 0) + while (!ev.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds{10}); } @@ -30,7 +30,7 @@ TEST_CASE("Timesup single request") TEST_CASE("Timesup two requests") { - lift::EventLoop ev{std::nullopt, std::nullopt, {std::chrono::seconds{1}}}; + lift::event_loop ev{lift::event_loop::options{.connect_timeout = std::chrono::seconds{1}}}; std::vector requests{}; @@ -39,7 +39,7 @@ TEST_CASE("Timesup two requests") std::chrono::milliseconds{25}, [](std::unique_ptr rh, lift::Response response) -> void { REQUIRE(response.LiftStatus() == lift::LiftStatus::TIMEOUT); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_504_GATEWAY_TIMEOUT); + REQUIRE(response.StatusCode() == lift::http::status_code::http_504_gateway_timeout); REQUIRE(response.TotalTime() == std::chrono::milliseconds{25}); })); @@ -48,13 +48,13 @@ TEST_CASE("Timesup two requests") std::chrono::milliseconds{50}, [](std::unique_ptr rh, lift::Response response) -> void { REQUIRE(response.LiftStatus() == lift::LiftStatus::TIMEOUT); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_504_GATEWAY_TIMEOUT); + REQUIRE(response.StatusCode() == lift::http::status_code::http_504_gateway_timeout); REQUIRE(response.TotalTime() == std::chrono::milliseconds{50}); })); - ev.StartRequests(std::move(requests)); + ev.start_requests(std::move(requests)); - while (ev.ActiveRequestCount() > 0) + while (!ev.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds{10}); } diff --git a/test/test_transfer_progress_request.cpp b/test/test_transfer_progress_request.cpp index 32389b6..50023d7 100644 --- a/test/test_transfer_progress_request.cpp +++ b/test/test_transfer_progress_request.cpp @@ -19,7 +19,7 @@ TEST_CASE("Transfer Progress synchronous") REQUIRE(handler_called > 0); REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); } TEST_CASE("Download bytes test synchronous") @@ -50,5 +50,5 @@ TEST_CASE("Download bytes test synchronous") // Its possible the test downloads the entire file before finishing, take the appropriate action. REQUIRE(response.LiftStatus() == ((should_failed) ? lift::LiftStatus::ERROR : lift::LiftStatus::SUCCESS)); - REQUIRE(response.StatusCode() == lift::http::StatusCode::HTTP_200_OK); + REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); } diff --git a/test/test_user_data_request.cpp b/test/test_user_data_request.cpp index 2c95e94..26a1951 100644 --- a/test/test_user_data_request.cpp +++ b/test/test_user_data_request.cpp @@ -22,7 +22,7 @@ static auto user_data_on_complete( TEST_CASE("User data") { - lift::EventLoop event_loop{}; + lift::event_loop el{}; // Technically can hard code in this instance for the lambda captures, but to make it a bit // more like an example we'll include a unique "request_id" that gets captured as the user data. @@ -33,7 +33,7 @@ TEST_CASE("User data") req1->OnCompleteHandler([request_id](lift::RequestPtr request, lift::Response response) { user_data_on_complete(std::move(request), std::move(response), request_id, 100.5); }); - event_loop.StartRequest(std::move(req1)); + el.start_request(std::move(req1)); request_id = 2; @@ -42,9 +42,9 @@ TEST_CASE("User data") req2->OnCompleteHandler([request_id](lift::RequestPtr request, lift::Response response) { user_data_on_complete(std::move(request), std::move(response), request_id, 1234.567); }); - event_loop.StartRequest(std::move(req2)); + el.start_request(std::move(req2)); - while (event_loop.ActiveRequestCount() > 0) + while (!el.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds{10}); } From e702265ea7f01bf74ad707c40a2532706ba86fee Mon Sep 17 00:00:00 2001 From: jbaldwin Date: Sun, 22 Nov 2020 12:19:07 -0700 Subject: [PATCH 3/6] revert header to use std::size_t for colon pos --- inc/lift/header.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/lift/header.hpp b/inc/lift/header.hpp index 537b631..5eaa22d 100644 --- a/inc/lift/header.hpp +++ b/inc/lift/header.hpp @@ -60,7 +60,7 @@ class header private: /// The full header data. std::string m_header{}; - uint16_t m_colon_pos{0}; + std::size_t m_colon_pos{0}; }; } // namespace lift From 2f468a2efcb972b4d6de18244d3228a8c13f6442 Mon Sep 17 00:00:00 2001 From: jbaldwin Date: Sun, 22 Nov 2020 18:25:24 -0700 Subject: [PATCH 4/6] finish it! --- README.md | 14 +- examples/async_simple.cpp | 10 +- examples/benchmark.cpp | 10 +- examples/readme.cpp | 14 +- examples/synch_simple.cpp | 14 +- inc/lift/event_loop.hpp | 20 +-- inc/lift/executor.hpp | 34 ++-- inc/lift/lift_status.hpp | 30 ++-- inc/lift/mime_field.hpp | 10 +- inc/lift/query_builder.hpp | 30 ++-- inc/lift/request.hpp | 203 ++++++++++++------------ inc/lift/resolve_host.hpp | 24 +-- inc/lift/response.hpp | 42 ++--- inc/lift/share.hpp | 60 +++---- src/event_loop.cpp | 28 ++-- src/executor.cpp | 103 ++++++------ src/lift_status.cpp | 68 ++++---- src/mime_field.cpp | 4 +- src/query_builder.cpp | 16 +- src/request.cpp | 42 ++--- src/resolve_host.cpp | 2 +- src/response.cpp | 19 ++- src/share.cpp | 20 +-- test/main.cpp | 10 +- test/setup.hpp | 20 +-- test/test_async_request.cpp | 60 +++---- test/test_event_loop.cpp | 44 ++--- test/test_header.cpp | 8 +- test/test_mime_field.cpp | 46 +++--- test/test_proxy.cpp | 58 +++---- test/test_query_builder.cpp | 22 +-- test/test_resolve_host.cpp | 40 ++--- test/test_share.cpp | 66 ++++---- test/test_sync_request.cpp | 64 ++++---- test/test_timesup.cpp | 36 ++--- test/test_transfer_progress_request.cpp | 24 +-- test/test_user_data_request.cpp | 14 +- 37 files changed, 677 insertions(+), 652 deletions(-) diff --git a/README.md b/README.md index a0e1ea0..0deae7e 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,10 @@ to get your started on using liblifthttp with both the synchronous and asynchron int main() { // Synchronous requests can be created on the stack. - lift::Request request{"http://www.example.com"}; + lift::request request{"http://www.example.com"}; // This is the blocking synchronous HTTP call. - auto response = request.Perform(); - std::cout << "Lift status: " << lift::to_string(response.LiftStatus()) << "\n"; + auto response = request.perform(); + std::cout << "Lift status: " << lift::to_string(response.lift_status()) << "\n"; std::cout << response << "\n"; // Will print the raw http response. // Creating the event loop starts it immediately, it spawns a background thread for executing requests. @@ -48,12 +48,12 @@ to get your started on using liblifthttp with both the synchronous and asynchron // on completion processing on this main thread you need to std::move() it back via a queue or inter-thread // communication. This is imporant if any resources are shared between the threads. // NOTE: The request is created on the heap so ownership can be passed easily via an std::unique_ptr - // to the lift::event_loop! lift::Request::make_unique() is a handy function to easily do so. - auto request_ptr = lift::Request::make_unique( + // to the lift::event_loop! lift::request::make_unique() is a handy function to easily do so. + auto request_ptr = lift::request::make_unique( "http://www.example.com", std::chrono::seconds{10}, // Give the request 10 seconds to complete or timeout. - [](lift::RequestPtr req_ptr, lift::Response response) { - std::cout << "Lift status: " << lift::to_string(response.LiftStatus()) << "\n"; + [](lift::request_ptr req_ptr, lift::response response) { + std::cout << "Lift status: " << lift::to_string(response.lift_status()) << "\n"; std::cout << response << "\n"; }); diff --git a/examples/async_simple.cpp b/examples/async_simple.cpp index 2be3788..71395f0 100644 --- a/examples/async_simple.cpp +++ b/examples/async_simple.cpp @@ -6,15 +6,15 @@ #include #include -static auto on_complete(std::unique_ptr request_ptr, lift::Response response) -> void +static auto on_complete(lift::request_ptr request_ptr, lift::response response) -> void { - if (response.LiftStatus() == lift::LiftStatus::SUCCESS) + if (response.lift_status() == lift::lift_status::success) { - std::cout << "Completed " << request_ptr->Url() << " ms:" << response.TotalTime().count() << std::endl; + std::cout << "Completed " << request_ptr->url() << " ms:" << response.total_time().count() << std::endl; } else { - std::cout << "Error: " << request_ptr->Url() << " : " << lift::to_string(response.LiftStatus()) << std::endl; + std::cout << "Error: " << request_ptr->url() << " : " << lift::to_string(response.lift_status()) << std::endl; } } @@ -35,7 +35,7 @@ int main() for (auto& url : urls) { std::cout << "Requesting " << url << std::endl; - auto request_ptr = lift::Request::make_unique(url, timeout, on_complete); + auto request_ptr = lift::request::make_unique(url, timeout, on_complete); el.start_request(std::move(request_ptr)); timeout += 250ms; std::this_thread::sleep_for(50ms); diff --git a/examples/benchmark.cpp b/examples/benchmark.cpp index 9aee6f7..39885ae 100644 --- a/examples/benchmark.cpp +++ b/examples/benchmark.cpp @@ -108,9 +108,9 @@ int main(int argc, char* argv[]) { auto& event_loop = *event_loop_ptr; - auto request_ptr = lift::Request::make_unique( - url, 30s, [&event_loop, &success, &error](lift::RequestPtr req_ptr, lift::Response response) { - if (response.LiftStatus() == lift::LiftStatus::SUCCESS) + auto request_ptr = lift::request::make_unique( + url, 30s, [&event_loop, &success, &error](lift::request_ptr req_ptr, lift::response response) { + if (response.lift_status() == lift::lift_status::success) { success.fetch_add(1, std::memory_order_relaxed); } @@ -123,8 +123,8 @@ int main(int argc, char* argv[]) event_loop.start_request(std::move(req_ptr)); }); - request_ptr->FollowRedirects(false); - request_ptr->Header("Connection", "Keep-Alive"); + request_ptr->follow_redirects(false); + request_ptr->header("Connection", "Keep-Alive"); event_loop_ptr->start_request(std::move(request_ptr)); } diff --git a/examples/readme.cpp b/examples/readme.cpp index 004ad7f..292093f 100644 --- a/examples/readme.cpp +++ b/examples/readme.cpp @@ -4,10 +4,10 @@ int main() { // Synchronous requests can be created on the stack. - lift::Request request{"http://www.example.com"}; + lift::request request{"http://www.example.com"}; // This is the blocking synchronous HTTP call. - auto response = request.Perform(); - std::cout << "Lift status: " << lift::to_string(response.LiftStatus()) << "\n"; + auto response = request.perform(); + std::cout << "Lift status: " << lift::to_string(response.lift_status()) << "\n"; std::cout << response << "\n"; // Will print the raw http response. // Creating the event loop starts it immediately, it spawns a background thread for executing requests. @@ -18,12 +18,12 @@ int main() // on completion processing on this main thread you need to std::move() it back via a queue or inter-thread // communication. This is imporant if any resources are shared between the threads. // NOTE: The request is created on the heap so ownership can be passed easily via an std::unique_ptr - // to the lift::event_loop! lift::Request::make_unique() is a handy function to easily do so. - auto request_ptr = lift::Request::make_unique( + // to the lift::event_loop! lift::request::make_unique() is a handy function to easily do so. + auto request_ptr = lift::request::make_unique( "http://www.example.com", std::chrono::seconds{10}, // Give the request 10 seconds to complete or timeout. - [](lift::RequestPtr req_ptr, lift::Response response) { - std::cout << "Lift status: " << lift::to_string(response.LiftStatus()) << "\n"; + [](lift::request_ptr req_ptr, lift::response response) { + std::cout << "Lift status: " << lift::to_string(response.lift_status()) << "\n"; std::cout << response << "\n"; }); diff --git a/examples/synch_simple.cpp b/examples/synch_simple.cpp index 0c21ec4..f3ff811 100644 --- a/examples/synch_simple.cpp +++ b/examples/synch_simple.cpp @@ -5,19 +5,19 @@ int main() { { - lift::Request request{"http://www.example.com"}; + lift::request request{"http://www.example.com"}; std::cout << "Requesting http://www.example.com" << std::endl; - const auto& response = request.Perform(); - std::cout << response.Data() << std::endl; + const auto& response = request.perform(); + std::cout << response.data() << std::endl; } { - lift::Request request{"http://www.google.com"}; + lift::request request{"http://www.google.com"}; std::cout << "Requesting http://www.google.com" << std::endl; - const auto& response = request.Perform(); - std::cout << response.Data() << std::endl; + const auto& response = request.perform(); + std::cout << response.data() << std::endl; - for (const auto& header : response.Headers()) + for (const auto& header : response.headers()) { std::cout << header.name() << ": " << header.value() << "\n"; } diff --git a/inc/lift/event_loop.hpp b/inc/lift/event_loop.hpp index 477b68c..bf74b00 100644 --- a/inc/lift/event_loop.hpp +++ b/inc/lift/event_loop.hpp @@ -52,9 +52,9 @@ class event_loop /// the keep-alive connection is established. std::optional connect_timeout{std::nullopt}; /// A set of host:port combinations to bypass DNS resolving. - std::optional> resolve_hosts{std::nullopt}; + std::optional> resolve_hosts{std::nullopt}; /// Should separate event loops share connection information? - SharePtr share_ptr{nullptr}; + share_ptr share{nullptr}; /// If this functor is provided it is called on the background /// thread starting and thread stopping. This can be used to set the /// thread's priority/niceness or possibly changes its thread name. @@ -117,7 +117,7 @@ class event_loop * will have its OnComplete() handler called * when its completed/error'ed/etc. */ - auto start_request(RequestPtr request_ptr) -> bool; + auto start_request(request_ptr request_ptr) -> bool; /** * Adds a batch of requests to process. The requests in the container will be moved @@ -165,9 +165,9 @@ class event_loop * the pending requests vector into the grabbed requests vector -- this is done * because the pending requests lock could deadlock with internal curl locks! */ - std::vector m_pending_requests{}; + std::vector m_pending_requests{}; /// Only accessible from within the event_loop thread. - std::vector m_grabbed_requests{}; + std::vector m_grabbed_requests{}; /// The background thread spawned to drive the event loop. std::thread m_background_thread{}; @@ -180,15 +180,15 @@ class event_loop std::deque> m_executors{}; /// The set of resolve hosts to apply to all requests in this event loop. - std::vector m_resolve_hosts{}; + std::vector m_resolve_hosts{}; /// When connection time is enabled on an event loop the curl timeout is the longer /// timeout value and these timeouts are the shorter value. std::multimap m_timeouts{}; - /// If the event loop is provided a Share object then connection information like + /// If the event loop is provided a share object then connection information like /// DNS/SSL/Data pipelining can be shared across event loops. - SharePtr m_share_ptr{nullptr}; + share_ptr m_share_ptr{nullptr}; /// Functor to call on background thread start/stop. on_thread_callback_type m_on_thread_callback{nullptr}; @@ -211,11 +211,11 @@ class event_loop /** * Completes a request to pass ownership back to the user land. * Manages internal state accordingly, always call this function rather - * than the Request->OnComplete() function directly. + * than the request->OnComplete() function directly. * @param exe The request handle to complete. * @param status The status of the request when completing. */ - auto complete_request_normal(executor& exe, LiftStatus status) -> void; + auto complete_request_normal(executor& exe, lift_status status) -> void; /** * Completes a request that has timed out but still has connection time remaining. diff --git a/inc/lift/executor.hpp b/inc/lift/executor.hpp index d418322..bf03282 100644 --- a/inc/lift/executor.hpp +++ b/inc/lift/executor.hpp @@ -9,7 +9,7 @@ namespace lift { -class Request; +class request; class event_loop; /** @@ -19,8 +19,8 @@ class event_loop; * A previous design exposed the CURL* as well as CURLM* objects * behind well formed C++ objects, unfortunately the user could * mutate these CURL objects at certain points during execution - * and cause 'bad things to happen'. By splitting the Request and - * Response objects out from any underlying CURL objects the lifetimes + * and cause 'bad things to happen'. By splitting the request and + * response objects out from any underlying CURL objects the lifetimes * can be appropriately managed. * * This class should never be used directly by the user of liblifthttp, @@ -31,7 +31,7 @@ class executor /// Allowed to create executor and Timesup! friend event_loop; /// Allowed to create executors. - friend Request; + friend request; public: executor(const executor&) = delete; @@ -53,22 +53,22 @@ class executor CURLSH* m_curl_share_handle{nullptr}; /// If sync request the pointer to the request. - Request* m_request_sync{nullptr}; + request* m_request_sync{nullptr}; /// If async request the event loop executing this request. event_loop* m_event_loop{nullptr}; /// If async request the pointer to the request. - RequestPtr m_request_async{nullptr}; + request_ptr m_request_async{nullptr}; /// If the async request has a timeout set then this is the position to delete when completed. std::optional::iterator> m_timeout_iterator{}; // Has the on complete callback been called already? bool m_on_complete_callback_called{false}; /// Used internally to point at one of the sync or async requests. - Request* m_request{nullptr}; + request* m_request{nullptr}; /// The HTTP response data. - Response m_response{}; + response m_response{}; static auto make_unique(event_loop* event_loop) -> std::unique_ptr { @@ -80,7 +80,7 @@ class executor * @param request The synchronous request pointer. * @param share Curl share handle to use for this request. */ - executor(Request* request, Share* share); + executor(request* request, share* share); /** * This constructor is used for executing an asynchronous requests. @@ -89,25 +89,25 @@ class executor executor(event_loop* event_loop); /** - * @param request_ptr The asynchronous request to execute. + * @param req_ptr The asynchronous request to execute. * @param share Curl share handle to use for this request. */ - auto start_async(RequestPtr request_ptr, Share* share) -> void; + auto start_async(request_ptr req_ptr, share* share) -> void; /** - * Synchronously performs the request and returns the Response. + * Synchronously performs the request and returns the response. * @return The HTTP response. */ - auto perform() -> Response; + auto perform() -> response; /** * Prepares the request to be executed. This will setup all required - * curl_easy_setopt() calls based on what has been set on the lift::Request. + * curl_easy_setopt() calls based on what has been set on the lift::request. */ auto prepare() -> void; /** - * Copies all available HTTP response fields into the lift::Response from + * Copies all available HTTP response fields into the lift::response from * the curl handle. */ auto copy_curl_to_response() -> void; @@ -121,10 +121,10 @@ class executor auto reset() -> void; /** - * Converts a CURLcode into a LiftStatus. + * Converts a CURLcode into a lift_status. * @param curl_code The CURLcode to convert. */ - static auto convert(CURLcode curl_code) -> LiftStatus; + static auto convert(CURLcode curl_code) -> lift_status; /// libcurl will call this function when a header is received for the HTTP request. friend auto curl_write_header(char* buffer, size_t size, size_t nitems, void* user_ptr) -> size_t; diff --git a/inc/lift/lift_status.hpp b/inc/lift/lift_status.hpp index 392886e..b2fe7f8 100644 --- a/inc/lift/lift_status.hpp +++ b/inc/lift/lift_status.hpp @@ -6,46 +6,46 @@ namespace lift { /** * This is the status of a request/response pair locally. It does not - * have anything in common with the http::StatusCode. This will tell you + * have anything in common with the http::status_code. This will tell you * if the request/response pair failed to connect, had a dns error, had an * ssl error, timed out, or any other various errors, or if it successfully - * completed! Always check this value on the lift::Response before using + * completed! Always check this value on the lift::response before using * any other data. */ -enum class LiftStatus : uint8_t +enum class lift_status : uint8_t { /// The request is under construction. - BUILDING, + building, /// The request is being executed. - EXECUTING, + executing, /// The request completed successfully. This is the one you want. - SUCCESS, + success, /// The request had a connect error. - CONNECT_ERROR, + connect_error, /// The request couldn't lookup the DNS for the url. - CONNECT_DNS_ERROR, + connect_dns_error, /// The request has an SSL connection error. - CONNECT_SSL_ERROR, + connect_ssl_error, /// The request timed out. - TIMEOUT, + timeout, /// The request has an empty response (socket severed). - RESPONSE_EMPTY, + response_empty, /// The request had an error and failed. - ERROR, + error, /// The request had an error and failed to start, did the event loop shutdown? - ERROR_FAILED_TO_START, + error_failed_to_start, /// The request had an error when attempting to read data off the socket. - DOWNLOAD_ERROR + download_error }; /** * @param status Convert the lift status to human readable string. * @return String representation of the status. */ -auto to_string(LiftStatus status) -> const std::string&; +auto to_string(lift_status status) -> const std::string&; } // namespace lift diff --git a/inc/lift/mime_field.hpp b/inc/lift/mime_field.hpp index 730e10a..306007e 100644 --- a/inc/lift/mime_field.hpp +++ b/inc/lift/mime_field.hpp @@ -6,18 +6,18 @@ namespace lift { -class MimeField +class mime_field { public: - MimeField(std::string field_name, std::string field_value); + mime_field(std::string field_name, std::string field_value); /** * @throw std::runtime_error If field_filepath does not exist on disk. */ - MimeField(std::string field_name, std::filesystem::path field_filepath); + mime_field(std::string field_name, std::filesystem::path field_filepath); - auto Name() const -> const std::string& { return m_field_name; } - auto Value() const -> const std::variant& { return m_field_value; } + auto name() const -> const std::string& { return m_field_name; } + auto value() const -> const std::variant& { return m_field_value; } private: std::string m_field_name{}; diff --git a/inc/lift/query_builder.hpp b/inc/lift/query_builder.hpp index 5175f00..fec5769 100644 --- a/inc/lift/query_builder.hpp +++ b/inc/lift/query_builder.hpp @@ -20,10 +20,10 @@ namespace lift * Note that the user is responsible for the lifetime of all string_view's * passed into the query builder. They must be 'alive' until Build() is called. */ -class QueryBuilder +class query_builder { public: - QueryBuilder() = default; + query_builder() = default; /** * Sets the scheme for the url. @@ -31,25 +31,25 @@ class QueryBuilder * Do not include the :// as the builder will include it for you. * * @param scheme Examples are "http" or "https". - * @return QueryBuilder + * @return query_builder */ - auto Scheme(std::string_view scheme) -> QueryBuilder&; + auto scheme(std::string_view scheme) -> query_builder&; /** * Sets the hostname for the url. * @param hostname Examples are www.example.com or google.com. Note that the builder * currently will not inject a www. prefix so if you want it then make * sure it is already there. - * @return QueryBuilder + * @return query_builder */ - auto Hostname(std::string_view hostname) -> QueryBuilder&; + auto hostname(std::string_view hostname) -> query_builder&; /** * Sets the port. * @param port The url port. - * @return QueryBuidler + * @return query_builder */ - auto Port(uint16_t port) -> QueryBuilder&; + auto port(uint16_t port) -> query_builder&; /** * Adds a path part to the url. Path parts shouldn't include '/' as the builder @@ -61,9 +61,9 @@ class QueryBuilder * This function will append the path parts in the same order they are provided in. * * @param path_part The path part to add to the query. - * @return QueryBuilder + * @return query_builder */ - auto AppendPathPart(std::string_view path_part) -> QueryBuilder&; + auto append_path_part(std::string_view path_part) -> query_builder&; /** * Adds a query parameter to the url. @@ -74,16 +74,16 @@ class QueryBuilder * * @param name The name of the parameter. * @param value The unescaped value of the parameter. - * @return QueryBuilder + * @return query_builder */ - auto AppendQueryParameter(std::string_view name, std::string_view value) -> QueryBuilder&; + auto append_query_parameter(std::string_view name, std::string_view value) -> query_builder&; /** * Sets the fragment for the url. * @param fragment #imafragment - * @return QueryBuilder + * @return query_builder */ - auto Fragment(std::string_view fragment) -> QueryBuilder&; + auto fragment(std::string_view fragment) -> query_builder&; /** * This function will build the HTTP query string based on the provided @@ -92,7 +92,7 @@ class QueryBuilder * next query. * @return Builds the query into a well formed string. */ - auto Build() -> std::string; + auto build() -> std::string; private: /// A buffer for generating the url from its parts. diff --git a/inc/lift/request.hpp b/inc/lift/request.hpp index 757aff6..e5be661 100644 --- a/inc/lift/request.hpp +++ b/inc/lift/request.hpp @@ -19,33 +19,33 @@ namespace lift class event_loop; class executor; -enum class SslCertificateType +enum class ssl_certificate_type { - PEM, - DER + pem, + der }; -enum class ProxyType +enum class proxy_type { - HTTP, - HTTPS + http, + https }; -enum class HttpAuthType +enum class http_auth_type { /// Basic HTTP authentication, this is the default value. - BASIC, + basic, /// Sets all available authentication methods and attempts to pick the most secure. - ANY, + any, /// Sets all available 'secure/safe' authentication methods. - ANY_SAFE + any_safe // TODO: Support setting individual http authentication methods. }; -struct ProxyData +struct proxy_data { /// The type of HTTP proxy to connect to, HTTP or HTTPS. - ProxyType m_type; + proxy_type m_type; /// The proxy hostname to connect to. std::string m_host; /// The proxy port to connect to. @@ -55,12 +55,12 @@ struct ProxyData /// The password for authentication with the proxy. std::optional m_password; /// The authentication type(s) to use for communication with the proxy, if not specified ANY is used. - std::optional> m_auth_types; + std::optional> m_auth_types; }; -auto to_string(SslCertificateType type) -> const std::string&; +auto to_string(ssl_certificate_type type) -> const std::string&; -class Request +class request { friend event_loop; friend executor; @@ -71,7 +71,7 @@ class Request * @param request_ptr Passes ownership of the request back to the user of liblifthttp. * @param response Response of the request_ptr. */ - using OnCompleteHandlerType = std::function request_ptr, Response response)>; + using on_complete_handler_type = std::function request_ptr, response response)>; /** * Transfer progress handler callback signature. @@ -81,8 +81,8 @@ class Request * @param upload_now_bytes Number of bytes uploaded so far. * @return True to continue the request, false to abort the request. */ - using TransferProgressHandlerType = std::function timeout = std::nullopt, - OnCompleteHandlerType on_complete_handler = nullptr); + on_complete_handler_type on_complete_handler = nullptr); /** * Creates a new request on the heap, this is a useful utility for asynchronous requests. @@ -113,20 +113,20 @@ class Request * @param timeout An optional timeout for this request. If not provided the request * could hang/block forever if it is never responded to. * @param on_complete_handler For asynchronous requests provide this if you want to - * know when the request completes with the Response information. + * know when the request completes with the response information. */ static auto make_unique( std::string url, std::optional timeout = std::nullopt, - OnCompleteHandlerType on_complete_handler = nullptr) -> std::unique_ptr + on_complete_handler_type on_complete_handler = nullptr) -> std::unique_ptr { - return std::make_unique(std::move(url), std::move(timeout), std::move(on_complete_handler)); + return std::make_unique(std::move(url), std::move(timeout), std::move(on_complete_handler)); } - Request(const Request&) = default; - Request(Request&&) = default; - auto operator=(const Request&) noexcept -> Request& = default; - auto operator=(Request&&) noexcept -> Request& = default; + request(const request&) = default; + request(request&&) = default; + auto operator=(const request&) noexcept -> request& = default; + auto operator=(request&&) noexcept -> request& = default; /** * Synchronously executes this request. @@ -134,22 +134,22 @@ class Request * Note: If there is no timeout set on the request and the remote * server fails to respond this call can block forever. * - * @param share_ptr An optional lift::Share for reusing/sharing connection information. + * @param share_ptr An optional lift::share for reusing/sharing connection information. * @return The HTTP response. */ - auto Perform(SharePtr share_ptr = nullptr) -> Response; + auto perform(share_ptr share_ptr = nullptr) -> response; /** - * This on complete handler event is called when a Request is executed + * This on complete handler event is called when a request is executed * asynchronously. This is not used for synchronous requests. * @param on_complete_handler When this request completes this handle is called. */ - auto OnCompleteHandler(OnCompleteHandlerType on_complete_handler) -> void; + auto on_complete_handler(on_complete_handler_type on_complete_handler) -> void; /** * @return The current on complete handler callback. */ - auto OnCompleteHandler() const -> const OnCompleteHandlerType& { return m_on_complete_handler; } + auto on_complete_handler() const -> const on_complete_handler_type& { return m_on_complete_handler; } /** * Sets or unsets a transfer progress handler callback. Called periodically to update the @@ -157,12 +157,12 @@ class Request * @param transfer_progress_handler If an empty optional then transfer progress callbacks are disabled, * if set with a function then transfer progress callbacks are enabled. */ - auto TransferProgressHandler(std::optional transfer_progress_handler) -> void; + auto transfer_progress_handler(std::optional transfer_progress_handler) -> void; /** * @return The amount of time for the request to connect, or std::nullopt signals the default, 300s. */ - auto ConnectTimeout() const -> const std::optional& { return m_connect_timeout; } + auto connect_timeout() const -> const std::optional& { return m_connect_timeout; } /** * This value for synchronous requests should be less than the total timeout value for the entire request. @@ -171,7 +171,7 @@ class Request * very quickly. * @param connect_timeout The amount of time for the request to connect, or std::nullopt to use the default, 300s. */ - auto ConnectTimeout(std::optional connect_timeout) -> void + auto connect_timeout(std::optional connect_timeout) -> void { m_connect_timeout = std::move(connect_timeout); } @@ -179,51 +179,51 @@ class Request /** * @return The amount of time for the request to complete, or std::nullopt if no timeout is set. */ - auto Timeout() const -> const std::optional& { return m_timeout; } + auto timeout() const -> const std::optional& { return m_timeout; } /** * @param timeout The amount of time for the request to complete, or std::nullopt for no timeout. */ - auto Timeout(std::optional timeout) -> void { m_timeout = std::move(timeout); } + auto timeout(std::optional timeout) -> void { m_timeout = std::move(timeout); } /** * @return The URL of the HTTP request. */ - auto Url() const -> const std::string& { return m_url; } + auto url() const -> const std::string& { return m_url; } /** * @param url The URL of the HTTP request. */ - auto Url(std::string url) -> void { m_url = std::move(url); } + auto url(std::string url) -> void { m_url = std::move(url); } /** * @return The HTTP method this request will use. */ - auto Method() const -> http::method { return m_method; } + auto method() const -> http::method { return m_method; } /** * @param method The HTTP method this request should use. */ - auto Method(http::method method) -> void { m_method = method; } + auto method(http::method method) -> void { m_method = method; } /** * @return The HTTP version this request will use. */ - auto Version() const -> http::version { return m_version; } + auto version() const -> http::version { return m_version; } /** * @param version The HTTP version this request should use. */ - auto Version(http::version version) -> void { m_version = version; } + auto version(http::version version) -> void { m_version = version; } /** * @return Is the HTTP request automatically following redirects? */ - auto FollowRedirects() const -> bool { return m_follow_redirects; } + auto follow_redirects() const -> bool { return m_follow_redirects; } /** * @return If following HTTP redirects, what is the maximum allowed to follow? */ - auto MaxRedirects() const -> int64_t { return m_max_redirects; } + auto max_redirects() const -> int64_t { return m_max_redirects; } /** * Sets if this request should follow redirects. By default following redirects is @@ -231,84 +231,84 @@ class Request * @param follow_redirects True to follow redirects, false to stop. * @param max_redirects The maximum number of redirects to follow, if not provided then infinite. */ - auto FollowRedirects(bool follow_redirects, std::optional max_redirects = std::nullopt) -> void; + auto follow_redirects(bool follow_redirects, std::optional max_redirects = std::nullopt) -> void; /** * @return Is the peer SSL/TLS verified? */ - auto VerifySslPeer() const -> bool { return m_verify_ssl_peer; } + auto verify_ssl_peer() const -> bool { return m_verify_ssl_peer; } /** * This feature defaults to enabled. * @param verify_ssl_peer Should the SSl/TLS peer be verified? */ - auto VerifySslPeer(bool verify_ssl_peer) -> void { m_verify_ssl_peer = verify_ssl_peer; } + auto verify_ssl_peer(bool verify_ssl_peer) -> void { m_verify_ssl_peer = verify_ssl_peer; } /** * This feature defaultes to enabled. * @return Is the SSL/TLS host verified? */ - auto VerifySslHost() const -> bool { return m_verify_ssl_host; } + auto verify_ssl_host() const -> bool { return m_verify_ssl_host; } /** * @param verify_ssl_host Should the SSL/TLS host be verified? */ - auto VerifySslHost(bool verify_ssl_host) -> void { m_verify_ssl_host = verify_ssl_host; } + auto verify_ssl_host(bool verify_ssl_host) -> void { m_verify_ssl_host = verify_ssl_host; } /** * @param verify_ssl_status Should the SSL/TLS certificate status be checked? */ - auto VerifySslStatus(bool verify_ssl_status) -> void { m_verify_ssl_status = verify_ssl_status; } + auto verify_ssl_status(bool verify_ssl_status) -> void { m_verify_ssl_status = verify_ssl_status; } /** * @return Is the SSL/TLS certificate status be checked? */ - auto VerifySslStatus() const -> bool { return m_verify_ssl_status; } + auto verify_ssl_status() const -> bool { return m_verify_ssl_status; } /** * @param cert_file The SSL/TLS certificate file to use. */ - auto SslCert(std::filesystem::path cert_file) -> void { m_cert_file = std::move(cert_file); } + auto ssl_cert(std::filesystem::path cert_file) -> void { m_cert_file = std::move(cert_file); } /** * @return The SSL/TLS certificate file being used. */ - auto SslCert() const -> const std::optional& { return m_cert_file; } + auto ssl_cert() const -> const std::optional& { return m_cert_file; } /** * @param type The SSL/TLS certificate type. */ - auto SslCertType(SslCertificateType type) -> void { m_ssl_cert_type = type; } + auto ssl_cert_type(ssl_certificate_type type) -> void { m_ssl_cert_type = type; } /** * @return The SSL/TSL certificate type being used. */ - auto SslCertType() const -> const std::optional& { return m_ssl_cert_type; } + auto ssl_cert_type() const -> const std::optional& { return m_ssl_cert_type; } /** * @param key_file The SSL/TLS key file to use. */ - auto SslKey(std::filesystem::path key_file) -> void { m_ssl_key_file = std::move(key_file); } + auto ssl_key(std::filesystem::path key_file) -> void { m_ssl_key_file = std::move(key_file); } /** * @return The SSL/TLS key file being used. */ - auto SslKey() const -> const std::optional& { return m_ssl_key_file; } + auto ssl_key() const -> const std::optional& { return m_ssl_key_file; } /** * @param password The pass phrase for the private key. */ - auto KeyPassword(std::string password) -> void { m_password = std::move(password); } + auto key_password(std::string password) -> void { m_password = std::move(password); } /** * @return The pass phrase for the private key. */ - auto KeyPassword() const -> const std::optional& { return m_password; } + auto key_password() const -> const std::optional& { return m_password; } /** * @return The proxy information for this request. */ - auto Proxy() const -> const std::optional& { return m_proxy_data; } + auto proxy() const -> const std::optional& { return m_proxy_data; } /** * Sets proxy information for this request. @@ -320,34 +320,34 @@ class Request * @param auth_types The authentication type(s) to use for communication with the proxy. * If not specified BASIC is used, default=std::nullopt (BASIC). */ - auto Proxy( - ProxyType type, - std::string host, - uint32_t port = 80, - std::optional username = std::nullopt, - std::optional password = std::nullopt, - std::optional> auth_types = std::nullopt) -> void + auto proxy( + proxy_type type, + std::string host, + uint32_t port = 80, + std::optional username = std::nullopt, + std::optional password = std::nullopt, + std::optional> auth_types = std::nullopt) -> void { m_proxy_data = - ProxyData{type, std::move(host), port, std::move(username), std::move(password), std::move(auth_types)}; + proxy_data{type, std::move(host), port, std::move(username), std::move(password), std::move(auth_types)}; } /** * Sets proxy information for this request. - * @param data The full proxy data to set for this request, @see `ProxyData`. + * @param data The full proxy data to set for this request, @see `proxy_data`. */ - auto Proxy(ProxyData data) -> void { m_proxy_data = std::move(data); } + auto proxy(proxy_data data) -> void { m_proxy_data = std::move(data); } /** * @return The list of currently set HTTP Accept-Encoding values. Note that if set via * `AcceptEndcodingAllAvaliable()` this function will return an empty list. */ - auto AcceptEncodings() const -> const std::optional>& { return m_accept_encodings; } + auto accept_encodings() const -> const std::optional>& { return m_accept_encodings; } /** * IMPORTANT: Using this is mutually exclusive with adding your own Accept-Encoding header. * @param encodings A list of accept encodings to send in the request. */ - auto AcceptEncoding(std::optional> encodings) -> void + auto accept_encoding(std::optional> encodings) -> void { m_accept_encodings = std::move(encodings); } @@ -355,22 +355,25 @@ class Request /** * Sets the accept encoding header to all supported encodings that this platform was built with. */ - auto AcceptEncodingAllAvailable() -> void { m_accept_encodings = std::vector{}; } + auto accept_encoding_all_available() -> void { m_accept_encodings = std::vector{}; } /** * @return Custom `host:port => ip_addr` resolve hosts for this request. */ - auto ResolveHosts() const -> const std::vector& { return m_resolve_hosts; } + auto resolve_hosts() const -> const std::vector& { return m_resolve_hosts; } /** * @param resolve_host Adds a resolve host to this request to bypass DNS lookups. */ - auto ResolveHost(lift::ResolveHost resolve_host) -> void { m_resolve_hosts.emplace_back(std::move(resolve_host)); } + auto resolve_host(lift::resolve_host resolve_host) -> void + { + m_resolve_hosts.emplace_back(std::move(resolve_host)); + } /** * Clears all set resolve hosts on this request. */ - auto ClearResolveHosts() -> void { m_resolve_hosts.clear(); } + auto clear_resolve_hosts() -> void { m_resolve_hosts.clear(); } /** * Specifically removes the header from the request. There are a few @@ -378,71 +381,71 @@ class Request * allows for the user to manually remove them. * @param name The name of the header, e.g. 'Accept' or 'Expect'. */ - auto RemoveHeader(std::string_view name) -> void { header(name, std::string_view{}); } + auto remove_header(std::string_view name) -> void { header(name, std::string_view{}); } /** * Adds a request header with its value. * @param name The name of the header, e.g. 'Connection'. * @param value The value of the header, e.g. 'Keep-Alive'. */ - auto Header(std::string_view name, std::string_view value) -> void; + auto header(std::string_view name, std::string_view value) -> void; /** * @return The current list of headers added to this request. Note that if more headers are added - * the Header classes Name() and Value() string_views might become invalidated. + * the header classes Name() and Value() string_views might become invalidated. */ - auto Headers() const -> const std::vector& { return m_request_headers; } + auto headers() const -> const std::vector& { return m_request_headers; } /** * Clears the current set of headers for this request. */ - auto ClearHeaders() -> void { m_request_headers.clear(); } + auto clear_headers() -> void { m_request_headers.clear(); } /** * @return The HTTP body data for this request, if it was never set this will be an empty string. */ - auto Data() const -> const std::string& { return m_request_data; } + auto data() const -> const std::string& { return m_request_data; } /** * Sets the request to HTTP POST and the body of the request * to the provided data. Override the method after this call to PUT if desired. * - * NOTE: this is mutually exclusive with using MimeField + * NOTE: this is mutually exclusive with using mime_field * as you cannot include traditional POST data in a mime-type form submission. * * @param data The request data to send in the HTTP POST. - * @throw std::logic_error If called after using AddMimeField. + * @throw std::logic_error If called after using mime_field(). */ - auto Data(std::string data) -> void; + auto data(std::string data) -> void; /** * @return The set mime fields for this request. */ - auto MimeFields() const -> const std::vector& { return m_mime_fields; } + auto mime_fields() const -> const std::vector& { return m_mime_fields; } /** * @param mime_field Adds this mime field to this mime HTTP request. */ - auto MimeField(lift::MimeField mime_field) -> void; + auto mime_field(lift::mime_field mf) -> void; /** * https://en.wikipedia.org/wiki/Happy_Eyeballs * @param timeout Sets the happy eyeballs algorithm timeout. */ - auto HappyEyeballsTimeout(std::chrono::milliseconds timeout) -> void { m_happy_eyeballs_timeout = timeout; } + auto happy_eyeballs_timeout(std::chrono::milliseconds timeout) -> void { m_happy_eyeballs_timeout = timeout; } /** * @return Gets the setting of the happy eyeballs timeout if set. */ - auto HappyEyeballsTimeout() const -> const std::optional& + auto happy_eyeballs_timeout() const -> const std::optional& { return m_happy_eyeballs_timeout; } private: /// The on complete handler callback. - OnCompleteHandlerType m_on_complete_handler{nullptr}; + on_complete_handler_type m_on_complete_handler{nullptr}; /// The transfer progress handler callback. - TransferProgressHandlerType m_on_transfer_progress_handler{nullptr}; + transfer_progress_handler_type m_on_transfer_progress_handler{nullptr}; /// The timeout to connect, or none. std::optional m_connect_timeout{}; /// The timeout for the request, or none. @@ -468,25 +471,25 @@ class Request /// The SSL/TLS certificate file to use. std::optional m_cert_file{}; /// The SSL/TLS certificate type. - std::optional m_ssl_cert_type{}; + std::optional m_ssl_cert_type{}; /// The SSL/TLS key file. std::optional m_ssl_key_file{}; /// The SSL/TLS key file's pass phrase. std::optional m_password{}; /// Proxy information. - std::optional m_proxy_data{}; + std::optional m_proxy_data{}; /// Specific Accept-Encoding header fields. std::optional> m_accept_encodings{}; /// A set of host:port to ip addresses that will be resolved before DNS. - std::vector m_resolve_hosts{}; + std::vector m_resolve_hosts{}; /// The request headers preformatted into the curl "Header: value\0" format. std::vector m_request_headers{}; - /// The POST request body data, mutually exclusive with MimeField requests. + /// The POST request body data, mutually exclusive with mime field requests. bool m_request_data_set{false}; std::string m_request_data{}; /// The Mime request fields, mutually exclusive with POST request body data. - bool m_mime_fields_set{false}; - std::vector m_mime_fields{}; + bool m_mime_fields_set{false}; + std::vector m_mime_fields{}; /// Happy eyeballs algorithm timeout https://curl.haxx.se/libcurl/c/CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.html std::optional m_happy_eyeballs_timeout{}; @@ -499,6 +502,6 @@ class Request curl_off_t upload_now_bytes) -> int; }; -using RequestPtr = std::unique_ptr; +using request_ptr = std::unique_ptr; } // namespace lift diff --git a/inc/lift/resolve_host.hpp b/inc/lift/resolve_host.hpp index 6f202c9..77f71b6 100644 --- a/inc/lift/resolve_host.hpp +++ b/inc/lift/resolve_host.hpp @@ -6,9 +6,9 @@ namespace lift { class executor; -class ResolveHost +class resolve_host { - /// For getCurlFormattedResolveHost(). + /// For curl_formatted_resolve_host(). friend executor; public: @@ -18,28 +18,28 @@ class ResolveHost * @param resolve_port The port to resolve. * @param resolved_ip_addr The IP Address that the host + port combination should resolve to. */ - ResolveHost(std::string resolve_host, uint16_t resolve_port, std::string resolved_ip_addr); - ~ResolveHost() = default; + resolve_host(std::string resolve_host, uint16_t resolve_port, std::string resolved_ip_addr); + ~resolve_host() = default; - ResolveHost(const ResolveHost&) = default; - ResolveHost(ResolveHost&&) noexcept = default; - auto operator=(const ResolveHost&) -> ResolveHost& = default; - auto operator=(ResolveHost&&) noexcept -> ResolveHost& = default; + resolve_host(const resolve_host&) = default; + resolve_host(resolve_host&&) noexcept = default; + auto operator=(const resolve_host&) -> resolve_host& = default; + auto operator=(resolve_host&&) noexcept -> resolve_host& = default; /** * @return Gets the given host that should be resolved. */ - [[nodiscard]] auto Host() const noexcept -> const std::string& { return m_resolve_host; } + [[nodiscard]] auto host() const noexcept -> const std::string& { return m_resolve_host; } /** * @return Gets the given port that should be resolved. */ - [[nodiscard]] auto Port() const noexcept -> uint16_t { return m_resolve_port; } + [[nodiscard]] auto port() const noexcept -> uint16_t { return m_resolve_port; } /** * @return Gets the given IP Address that is being resolved to. */ - [[nodiscard]] auto IpAddr() const noexcept -> const std::string& { return m_resolved_ip_addr; } + [[nodiscard]] auto ip_addr() const noexcept -> const std::string& { return m_resolved_ip_addr; } private: /// The given input resolve host. @@ -55,7 +55,7 @@ class ResolveHost /** * @return Gets the "host:port:ipaddress" curl formatted resolve host. */ - [[nodiscard]] auto getCurlFormattedResolveHost() const noexcept -> const std::string& { return m_curl_formatted; } + [[nodiscard]] auto curl_formatted_resolve_host() const noexcept -> const std::string& { return m_curl_formatted; } }; } // namespace lift diff --git a/inc/lift/response.hpp b/inc/lift/response.hpp index b9dee75..864f50e 100644 --- a/inc/lift/response.hpp +++ b/inc/lift/response.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -17,19 +18,19 @@ namespace lift class event_loop; class executor; -class Response +class response { friend event_loop; friend executor; public: - Response(); - ~Response() = default; + response(); + ~response() = default; - Response(const Response&) = default; - Response(Response&&) = default; - auto operator=(const Response&) noexcept -> Response& = default; - auto operator=(Response&&) noexcept -> Response& = default; + response(const response&) = default; + response(response&&) = default; + auto operator=(const response&) noexcept -> response& = default; + auto operator=(response&&) noexcept -> response& = default; /** * The Lift status is how the request ended up in the event loop. @@ -39,32 +40,37 @@ class Response * * @return Gets the request completion status. */ - [[nodiscard]] auto LiftStatus() const -> lift::LiftStatus { return m_lift_status; } + [[nodiscard]] auto lift_status() const -> lift::lift_status { return m_lift_status; } /** * @return The HTTP version of the response. */ - auto Version() const -> http::version { return m_version; } + auto version() const -> http::version { return m_version; } /** * @return The HTTP response status code. */ - [[nodiscard]] auto StatusCode() const -> http::status_code { return m_status_code; } + [[nodiscard]] auto status_code() const -> http::status_code { return m_status_code; } /** * @return The HTTP response headers. */ - [[nodiscard]] auto Headers() const -> const std::vector
& { return m_headers; } + [[nodiscard]] auto headers() const -> const std::vector
& { return m_headers; } + + /** + * @return The header if it exists on this response, otherwise std::nullopt. + */ + [[nodiscard]] auto header(std::string_view name) const -> std::optional>; /** * @return The HTTP download payload. */ - [[nodiscard]] auto Data() const -> std::string_view { return std::string_view{m_data.data(), m_data.size()}; } + [[nodiscard]] auto data() const -> std::string_view { return std::string_view{m_data.data(), m_data.size()}; } /** * @return The total HTTP request time in milliseconds. */ - [[nodiscard]] auto TotalTime() const -> std::chrono::milliseconds + [[nodiscard]] auto total_time() const -> std::chrono::milliseconds { return std::chrono::milliseconds{m_total_time}; } @@ -72,23 +78,23 @@ class Response /** * @return The number of connections made to make this request */ - [[nodiscard]] auto NumConnects() const -> uint8_t { return m_num_connects; } + [[nodiscard]] auto num_connects() const -> uint8_t { return m_num_connects; } /** * @return The number of redirects made during this request. */ - [[nodiscard]] auto NumRedirects() const -> uint8_t { return m_num_redirects; } + [[nodiscard]] auto num_redirects() const -> uint8_t { return m_num_redirects; } /** * Formats the response in the raw HTTP format. */ - friend auto operator<<(std::ostream& os, const Response& r) -> std::ostream&; + friend auto operator<<(std::ostream& os, const response& r) -> std::ostream&; private: /// Ordered by sizeof() since response gets std::moved()'ed back to the client. /// The response headers. - std::vector
m_headers{}; + std::vector m_headers{}; /// The response data if any. std::vector m_data{}; /// The total time in milliseconds to execute the request, stored as uint32_t since that is enough @@ -97,7 +103,7 @@ class Response /// The HTTP response status code. lift::http::status_code m_status_code{lift::http::status_code::http_unknown}; /// The status of this HTTP request. - lift::LiftStatus m_lift_status{lift::LiftStatus::BUILDING}; + lift::lift_status m_lift_status{lift::lift_status::building}; /// The HTTP response version. http::version m_version{http::version::v1_1}; /// The number of times attempted to connect to the remote server. diff --git a/inc/lift/share.hpp b/inc/lift/share.hpp index a55e8cb..a1956c4 100644 --- a/inc/lift/share.hpp +++ b/inc/lift/share.hpp @@ -10,42 +10,42 @@ namespace lift { class executor; -enum class ShareOptions : uint64_t -{ - /// Share nothing across requests. - NOTHING = 0, - /// Share DNS information across requests. - DNS = 1 << 1, - /// Share SSL information across requests. - SSL = 1 << 2, - /// Share Data pipeline'ing across requests. - DATA = 1 << 3, - - /// Share DNS with SSL. - DNS_SSL = (DNS + SSL), - /// Share DNS with Data. - DNS_DATA = (DNS + DATA), - /// Share SSL with Data. - SSL_DATA = (SSL + DATA), - /// Share all available types. - ALL = (DNS + SSL + DATA) -}; - -class Share +class share { friend executor; public: + enum class options : uint64_t + { + /// Share nothing across requests. + nothing = 0, + /// Share DNS information across requests. + dns = 1 << 1, + /// Share SSL information across requests. + ssl = 1 << 2, + /// Share Data pipeline'ing across requests. + data = 1 << 3, + + /// Share DNS with SSL. + dns_ssl = (dns + ssl), + /// Share DNS with Data. + dns_data = (dns + data), + /// Share SSL with Data. + ssl_data = (ssl + data), + /// Share all available types. + all = (dns + ssl + data) + }; + /** - * @param share_options The specific items to share between requests. + * @param opts The specific items to share between requests. */ - Share(ShareOptions share_options); - ~Share(); + share(options opts); + ~share(); - Share(const Share&) = delete; - Share(Share&&) = delete; - auto operator=(const Share&) noexcept -> Share& = delete; - auto operator=(Share&&) noexcept -> Share& = delete; + share(const share&) = delete; + share(share&&) = delete; + auto operator=(const share&) noexcept -> share& = delete; + auto operator=(share&&) noexcept -> share& = delete; private: CURLSH* m_curl_share_ptr{curl_share_init()}; @@ -57,6 +57,6 @@ class Share friend auto curl_share_unlock(CURL* curl_ptr, curl_lock_data data, void* user_ptr) -> void; }; -using SharePtr = std::shared_ptr; +using share_ptr = std::shared_ptr; } // namespace lift diff --git a/src/event_loop.cpp b/src/event_loop.cpp index df82407..b4b6b1b 100644 --- a/src/event_loop.cpp +++ b/src/event_loop.cpp @@ -84,8 +84,8 @@ auto on_uv_timesup_callback(uv_timer_t* handle) -> void; event_loop::event_loop(options opts) : m_connect_timeout(std::move(opts.connect_timeout)), m_curl_context_ready(), - m_resolve_hosts(std::move(opts.resolve_hosts.value_or(std::vector{}))), - m_share_ptr(std::move(opts.share_ptr)), + m_resolve_hosts(std::move(opts.resolve_hosts.value_or(std::vector{}))), + m_share_ptr(std::move(opts.share)), m_on_thread_callback(std::move(opts.on_thread_callback)) { global_init(); @@ -156,7 +156,7 @@ event_loop::~event_loop() global_cleanup(); } -auto event_loop::start_request(RequestPtr request_ptr) -> bool +auto event_loop::start_request(request_ptr request_ptr) -> bool { if (request_ptr == nullptr) { @@ -234,7 +234,7 @@ auto event_loop::check_actions(curl_socket_t socket, int event_bitmask) -> void } } -auto event_loop::complete_request_normal(executor& exe, LiftStatus status) -> void +auto event_loop::complete_request_normal(executor& exe, lift_status status) -> void { if (exe.m_on_complete_callback_called == false) { @@ -262,8 +262,8 @@ auto event_loop::complete_request_timeout(executor& exe) -> void if (exe.m_on_complete_callback_called == false && on_complete_handler != nullptr) { exe.m_on_complete_callback_called = true; - exe.m_response.m_lift_status = lift::LiftStatus::TIMEOUT; - exe.set_timesup_response(exe.m_request->Timeout().value()); + exe.m_response.m_lift_status = lift::lift_status::timeout; + exe.set_timesup_response(exe.m_request->timeout().value()); // Removing the timesup is done in the uv timesup callback so it can prune // every single item that has timesup'ed. Doing it here will cause 1 item @@ -276,7 +276,7 @@ auto event_loop::complete_request_timeout(executor& exe) -> void // own timeout. Shared ownership would most likely require locks as well since any curl // handle still in the curl multi handle could be mutated by curl at any moment, copying // seems far safer. - auto copy_ptr = std::make_unique(*exe.m_request_async); + auto copy_ptr = std::make_unique(*exe.m_request_async); on_complete_handler(std::move(copy_ptr), std::move(exe.m_response)); } @@ -287,15 +287,15 @@ auto event_loop::complete_request_timeout(executor& exe) -> void auto event_loop::add_timeout(executor& exe) -> void { auto* request = exe.m_request; - if (request->Timeout().has_value()) + if (request->timeout().has_value()) { - auto timeout = exe.m_request->Timeout().value(); + auto timeout = exe.m_request->timeout().value(); std::optional connect_timeout{std::nullopt}; - if (request->ConnectTimeout().has_value()) + if (request->connect_timeout().has_value()) { // Prefer the individual connect timeout over the event loop default. - connect_timeout = request->ConnectTimeout().value(); + connect_timeout = request->connect_timeout().value(); } else if (m_connect_timeout.has_value()) { @@ -529,7 +529,7 @@ auto on_uv_requests_accept_async(uv_async_t* handle) -> void * while it is held, curl has its own internal locks and * it can cause a deadlock. This means we intentionally swap * vectors before working on them so we have exclusive access - * to the Request objects on the event_loop thread. + * to the request objects on the event_loop thread. */ { std::lock_guard guard{el->m_pending_requests_lock}; @@ -561,9 +561,9 @@ auto on_uv_requests_accept_async(uv_async_t* handle) -> void else { /** - * Drop the unique_ptr safety around the RequestHandle while it is being + * Drop the unique_ptr safety around the request_ptr while it is being * processed by curl. When curl is finished completing the request - * it will be put back into a Request object for the client to use. + * it will be put back into a request object for the client to use. */ (void)executor_ptr.release(); diff --git a/src/executor.cpp b/src/executor.cpp index 52b663c..dfc52e8 100644 --- a/src/executor.cpp +++ b/src/executor.cpp @@ -15,7 +15,7 @@ auto curl_xfer_info( curl_off_t upload_total_bytes, curl_off_t upload_now_bytes) -> int; -executor::executor(Request* request, Share* share) : m_request_sync(request), m_request(m_request_sync), m_response() +executor::executor(request* request, share* share) : m_request_sync(request), m_request(m_request_sync), m_response() { if (share != nullptr) { @@ -33,9 +33,9 @@ executor::~executor() curl_easy_cleanup(m_curl_handle); } -auto executor::start_async(RequestPtr request_ptr, Share* share) -> void +auto executor::start_async(request_ptr req_ptr, share* share) -> void { - m_request_async = std::move(request_ptr); + m_request_async = std::move(req_ptr); m_request = m_request_async.get(); if (share != nullptr) { @@ -43,7 +43,7 @@ auto executor::start_async(RequestPtr request_ptr, Share* share) -> void } } -auto executor::perform() -> Response +auto executor::perform() -> response { global_init(); @@ -67,9 +67,9 @@ auto executor::prepare() -> void curl_easy_setopt(m_curl_handle, CURLOPT_WRITEDATA, this); curl_easy_setopt(m_curl_handle, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt(m_curl_handle, CURLOPT_URL, m_request->Url().c_str()); + curl_easy_setopt(m_curl_handle, CURLOPT_URL, m_request->url().c_str()); - switch (m_request->Method()) + switch (m_request->method()) { case http::method::unknown: // default to GET on unknown/bad value. /* INTENTIONAL FALLTHROUGH */ @@ -99,7 +99,7 @@ auto executor::prepare() -> void break; } - switch (m_request->Version()) + switch (m_request->version()) { case http::version::unknown: // default to USE_BEST on unknown/bad value. /* INTENTIONAL FALLTHROUGH */ @@ -123,31 +123,31 @@ auto executor::prepare() -> void break; } - // Synchronous Requests get their timeout value set directly on the curl easy handle. + // Synchronous requests get their timeout value set directly on the curl easy handle. // Asynchronous requests will handle timeouts on the event loop due to Connection Time. if (m_request_sync != nullptr) { - if (m_request->ConnectTimeout().has_value()) + if (m_request->connect_timeout().has_value()) { curl_easy_setopt( m_curl_handle, CURLOPT_CONNECTTIMEOUT_MS, - static_cast(m_request->ConnectTimeout().value().count())); + static_cast(m_request->connect_timeout().value().count())); } - if (m_request->Timeout().has_value()) + if (m_request->timeout().has_value()) { curl_easy_setopt( - m_curl_handle, CURLOPT_TIMEOUT_MS, static_cast(m_request->Timeout().value().count())); + m_curl_handle, CURLOPT_TIMEOUT_MS, static_cast(m_request->timeout().value().count())); } } // Connection timeout is handled when injecting into the CURLM* event loop for asynchronous requests. - if (m_request->FollowRedirects()) + if (m_request->follow_redirects()) { curl_easy_setopt(m_curl_handle, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(m_curl_handle, CURLOPT_MAXREDIRS, static_cast(m_request->MaxRedirects())); + curl_easy_setopt(m_curl_handle, CURLOPT_MAXREDIRS, static_cast(m_request->max_redirects())); } else { @@ -155,48 +155,49 @@ auto executor::prepare() -> void } // https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html - curl_easy_setopt(m_curl_handle, CURLOPT_SSL_VERIFYPEER, (m_request->VerifySslPeer()) ? 1L : 0L); + curl_easy_setopt(m_curl_handle, CURLOPT_SSL_VERIFYPEER, (m_request->verify_ssl_peer()) ? 1L : 0L); // Note that 1L is valid, but curl docs say its basically deprecated. // https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html - curl_easy_setopt(m_curl_handle, CURLOPT_SSL_VERIFYHOST, (m_request->VerifySslHost()) ? 2L : 0L); + curl_easy_setopt(m_curl_handle, CURLOPT_SSL_VERIFYHOST, (m_request->verify_ssl_host()) ? 2L : 0L); // https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYSTATUS.html - curl_easy_setopt(m_curl_handle, CURLOPT_SSL_VERIFYSTATUS, (m_request->VerifySslStatus()) ? 1L : 0L); + curl_easy_setopt(m_curl_handle, CURLOPT_SSL_VERIFYSTATUS, (m_request->verify_ssl_status()) ? 1L : 0L); // https://curl.haxx.se/libcurl/c/CURLOPT_SSLCERT.html - if (const auto& cert = m_request->SslCert(); cert.has_value()) + if (const auto& cert = m_request->ssl_cert(); cert.has_value()) { curl_easy_setopt(m_curl_handle, CURLOPT_SSLCERT, cert.value().c_str()); } // https://curl.haxx.se/libcurl/c/CURLOPT_SSLCERTTYPE.html - if (const auto& cert_type = m_request->SslCertType(); cert_type.has_value()) + if (const auto& cert_type = m_request->ssl_cert_type(); cert_type.has_value()) { curl_easy_setopt(m_curl_handle, CURLOPT_SSLCERTTYPE, to_string(cert_type.value()).data()); } // https://curl.haxx.se/libcurl/c/CURLOPT_SSLKEY.html - if (const auto& key = m_request->SslKey(); key.has_value()) + if (const auto& key = m_request->ssl_key(); key.has_value()) { curl_easy_setopt(m_curl_handle, CURLOPT_SSLKEY, key.value().c_str()); } // https://curl.haxx.se/libcurl/c/CURLOPT_KEYPASSWD.html - if (const auto& password = m_request->KeyPassword(); password.has_value()) + if (const auto& password = m_request->key_password(); password.has_value()) { curl_easy_setopt(m_curl_handle, CURLOPT_KEYPASSWD, password.value().data()); } // Set proxy information for the requst if provided. // https://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html - if (m_request->Proxy().has_value()) + if (m_request->proxy().has_value()) { - auto& proxy_data = m_request->Proxy().value(); + auto& proxy_data = m_request->proxy().value(); curl_easy_setopt(m_curl_handle, CURLOPT_PROXY, proxy_data.m_host.data()); switch (proxy_data.m_type) { - case ProxyType::HTTPS: + case proxy_type::https: curl_easy_setopt(m_curl_handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); break; - case ProxyType::HTTP: + case proxy_type::http: + /* intentional fallthrough */ default: curl_easy_setopt(m_curl_handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); break; @@ -220,13 +221,13 @@ auto executor::prepare() -> void { switch (auth_type) { - case HttpAuthType::BASIC: + case http_auth_type::basic: auth_types |= CURLAUTH_BASIC; break; - case HttpAuthType::ANY: + case http_auth_type::any: auth_types |= CURLAUTH_ANY; break; - case HttpAuthType::ANY_SAFE: + case http_auth_type::any_safe: auth_types |= CURLAUTH_ANYSAFE; break; } @@ -239,7 +240,7 @@ auto executor::prepare() -> void } } - const auto& encodings = m_request->AcceptEncodings(); + const auto& encodings = m_request->accept_encodings(); if (encodings.has_value()) { if (!encodings.value().empty()) @@ -313,7 +314,7 @@ auto executor::prepare() -> void for (const auto& resolve_host : m_request->m_resolve_hosts) { m_curl_resolve_hosts = - curl_slist_append(m_curl_resolve_hosts, resolve_host.getCurlFormattedResolveHost().data()); + curl_slist_append(m_curl_resolve_hosts, resolve_host.curl_formatted_resolve_host().data()); } if (m_event_loop != nullptr) @@ -321,7 +322,7 @@ auto executor::prepare() -> void for (const auto& resolve_host : m_event_loop->m_resolve_hosts) { m_curl_resolve_hosts = - curl_slist_append(m_curl_resolve_hosts, resolve_host.getCurlFormattedResolveHost().data()); + curl_slist_append(m_curl_resolve_hosts, resolve_host.curl_formatted_resolve_host().data()); } } @@ -331,27 +332,27 @@ auto executor::prepare() -> void // POST or MIME data if (m_request->m_request_data_set) { - curl_easy_setopt(m_curl_handle, CURLOPT_POSTFIELDSIZE, static_cast(m_request->Data().size())); - curl_easy_setopt(m_curl_handle, CURLOPT_POSTFIELDS, m_request->Data().data()); + curl_easy_setopt(m_curl_handle, CURLOPT_POSTFIELDSIZE, static_cast(m_request->data().size())); + curl_easy_setopt(m_curl_handle, CURLOPT_POSTFIELDS, m_request->data().data()); } else if (m_request->m_mime_fields_set) { m_mime_handle = curl_mime_init(m_curl_handle); - for (const auto& mime_field : m_request->MimeFields()) + for (const auto& mime_field : m_request->mime_fields()) { auto* field = curl_mime_addpart(m_mime_handle); - if (std::holds_alternative(mime_field.Value())) + if (std::holds_alternative(mime_field.value())) { - curl_mime_name(field, mime_field.Name().data()); - const auto& value = std::get(mime_field.Value()); + curl_mime_name(field, mime_field.name().data()); + const auto& value = std::get(mime_field.value()); curl_mime_data(field, value.data(), value.length()); } else { - curl_mime_filename(field, mime_field.Name().data()); - curl_mime_filedata(field, std::get(mime_field.Value()).c_str()); + curl_mime_filename(field, mime_field.name().data()); + curl_mime_filedata(field, std::get(mime_field.value()).c_str()); } } @@ -369,7 +370,7 @@ auto executor::prepare() -> void curl_easy_setopt(m_curl_handle, CURLOPT_NOPROGRESS, 1L); } - if (const auto& timeout = m_request->HappyEyeballsTimeout(); timeout.has_value()) + if (const auto& timeout = m_request->happy_eyeballs_timeout(); timeout.has_value()) { curl_easy_setopt(m_curl_handle, CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, static_cast(timeout.value().count())); } @@ -445,7 +446,7 @@ auto executor::reset() -> void m_timeout_iterator.reset(); m_on_complete_callback_called = false; - m_response = Response{}; + m_response = response{}; curl_easy_setopt(m_curl_handle, CURLOPT_SHARE, nullptr); m_curl_share_handle = nullptr; @@ -453,30 +454,30 @@ auto executor::reset() -> void curl_easy_reset(m_curl_handle); } -auto executor::convert(CURLcode curl_code) -> LiftStatus +auto executor::convert(CURLcode curl_code) -> lift_status { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch-enum" switch (curl_code) { case CURLcode::CURLE_OK: - return LiftStatus::SUCCESS; + return lift_status::success; case CURLcode::CURLE_GOT_NOTHING: - return LiftStatus::RESPONSE_EMPTY; + return lift_status::response_empty; case CURLcode::CURLE_OPERATION_TIMEDOUT: - return LiftStatus::TIMEOUT; + return lift_status::timeout; case CURLcode::CURLE_COULDNT_CONNECT: - return LiftStatus::CONNECT_ERROR; + return lift_status::connect_error; case CURLcode::CURLE_COULDNT_RESOLVE_HOST: - return LiftStatus::CONNECT_DNS_ERROR; + return lift_status::connect_dns_error; case CURLcode::CURLE_SSL_CONNECT_ERROR: - return LiftStatus::CONNECT_SSL_ERROR; + return lift_status::connect_ssl_error; case CURLcode::CURLE_WRITE_ERROR: - return LiftStatus::DOWNLOAD_ERROR; + return lift_status::download_error; case CURLcode::CURLE_SEND_ERROR: - return LiftStatus::ERROR_FAILED_TO_START; + return lift_status::error_failed_to_start; default: - return LiftStatus::ERROR; + return lift_status::error; } #pragma GCC diagnostic pop } diff --git a/src/lift_status.cpp b/src/lift_status.cpp index f905066..29c6cd7 100644 --- a/src/lift_status.cpp +++ b/src/lift_status.cpp @@ -4,45 +4,45 @@ namespace lift { using namespace std::string_literals; -static const std::string LIFT_STATUS_BUILDING = "BUILDING"s; -static const std::string LIFT_STATUS_EXECUTING = "EXECUTING"s; -static const std::string LIFT_STATUS_SUCCESS = "SUCCESS"s; -static const std::string LIFT_STATUS_CONNECT_ERROR = "CONNECT_ERROR"s; -static const std::string LIFT_STATUS_CONNECT_DNS_ERROR = "CONNECT_DNS_ERROR"s; -static const std::string LIFT_STATUS_CONNECT_SSL_ERROR = "CONNECT_SSL_ERROR"s; -static const std::string LIFT_STATUS_TIMEOUT = "TIMEOUT"s; -static const std::string LIFT_STATUS_RESPONSE_EMPTY = "RESPONSE_EMPTY"s; -static const std::string LIFT_STATUS_ERROR_FAILED_TO_START = "ERROR_FAILED_TO_START"s; -static const std::string LIFT_STATUS_ERROR = "ERROR"s; -static const std::string LIFT_STATUS_DOWNLOAD_ERROR = "DOWNLOAD_ERROR"s; +static const std::string lift_status_building = "building"s; +static const std::string lift_status_executing = "executing"s; +static const std::string lift_status_success = "success"s; +static const std::string lift_status_connect_error = "connect_error"s; +static const std::string lift_status_connect_dns_error = "connect_dns_error"s; +static const std::string lift_status_connect_ssl_error = "connect_ssl_error"s; +static const std::string lift_status_timeout = "timeout"s; +static const std::string lift_status_response_empty = "response_empty"s; +static const std::string lift_status_error = "error"s; +static const std::string lift_status_error_failed_to_start = "error_failed_to_start"s; +static const std::string lift_status_download_error = "download_error"s; -auto to_string(LiftStatus status) -> const std::string& +auto to_string(lift_status status) -> const std::string& { switch (status) { - case LiftStatus::BUILDING: - return LIFT_STATUS_BUILDING; - case LiftStatus::EXECUTING: - return LIFT_STATUS_EXECUTING; - case LiftStatus::SUCCESS: - return LIFT_STATUS_SUCCESS; - case LiftStatus::CONNECT_ERROR: - return LIFT_STATUS_CONNECT_ERROR; - case LiftStatus::CONNECT_DNS_ERROR: - return LIFT_STATUS_CONNECT_DNS_ERROR; - case LiftStatus::CONNECT_SSL_ERROR: - return LIFT_STATUS_CONNECT_SSL_ERROR; - case LiftStatus::TIMEOUT: - return LIFT_STATUS_TIMEOUT; - case LiftStatus::RESPONSE_EMPTY: - return LIFT_STATUS_RESPONSE_EMPTY; - case LiftStatus::DOWNLOAD_ERROR: - return LIFT_STATUS_DOWNLOAD_ERROR; - case LiftStatus::ERROR_FAILED_TO_START: - return LIFT_STATUS_ERROR_FAILED_TO_START; - case LiftStatus::ERROR: + case lift_status::building: + return lift_status_building; + case lift_status::executing: + return lift_status_executing; + case lift_status::success: + return lift_status_success; + case lift_status::connect_error: + return lift_status_connect_error; + case lift_status::connect_dns_error: + return lift_status_connect_dns_error; + case lift_status::connect_ssl_error: + return lift_status_connect_ssl_error; + case lift_status::timeout: + return lift_status_timeout; + case lift_status::response_empty: + return lift_status_response_empty; + case lift_status::download_error: + return lift_status_download_error; + case lift_status::error_failed_to_start: + return lift_status_error_failed_to_start; + case lift_status::error: default: - return LIFT_STATUS_ERROR; + return lift_status_error; } } diff --git a/src/mime_field.cpp b/src/mime_field.cpp index c148b62..78e4231 100644 --- a/src/mime_field.cpp +++ b/src/mime_field.cpp @@ -2,13 +2,13 @@ namespace lift { -MimeField::MimeField(std::string field_name, std::string field_value) +mime_field::mime_field(std::string field_name, std::string field_value) : m_field_name(std::move(field_name)), m_field_value(std::move(field_value)) { } -MimeField::MimeField(std::string field_name, std::filesystem::path field_filepath) +mime_field::mime_field(std::string field_name, std::filesystem::path field_filepath) : m_field_name(std::move(field_name)), m_field_value(std::move(field_filepath)) { diff --git a/src/query_builder.cpp b/src/query_builder.cpp index f450da6..9fee258 100644 --- a/src/query_builder.cpp +++ b/src/query_builder.cpp @@ -3,43 +3,43 @@ namespace lift { -auto QueryBuilder::Scheme(std::string_view scheme) -> QueryBuilder& +auto query_builder::scheme(std::string_view scheme) -> query_builder& { m_scheme = scheme; return *this; } -auto QueryBuilder::Hostname(std::string_view hostname) -> QueryBuilder& +auto query_builder::hostname(std::string_view hostname) -> query_builder& { m_hostname = hostname; return *this; } -auto QueryBuilder::Port(uint16_t port) -> QueryBuilder& +auto query_builder::port(uint16_t port) -> query_builder& { m_port = port; return *this; } -auto QueryBuilder::AppendPathPart(std::string_view path_part) -> QueryBuilder& +auto query_builder::append_path_part(std::string_view path_part) -> query_builder& { m_path_parts.emplace_back(path_part); return *this; } -auto QueryBuilder::AppendQueryParameter(std::string_view name, std::string_view value) -> QueryBuilder& +auto query_builder::append_query_parameter(std::string_view name, std::string_view value) -> query_builder& { m_query_parameters.emplace_back(name, value); return *this; } -auto QueryBuilder::Fragment(std::string_view fragment) -> QueryBuilder& +auto query_builder::fragment(std::string_view fragment) -> query_builder& { m_fragment = fragment; return *this; } -auto QueryBuilder::Build() -> std::string +auto query_builder::build() -> std::string { if (!m_scheme.empty()) { @@ -90,7 +90,7 @@ auto QueryBuilder::Build() -> std::string return copy; } -auto QueryBuilder::reset() -> void +auto query_builder::reset() -> void { m_query.clear(); m_query.str(""); diff --git a/src/request.cpp b/src/request.cpp index ea120a3..6057f1a 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -5,43 +5,43 @@ namespace lift { using namespace std::string_literals; -static const std::string SSL_CERT_TYPE_UNKNOWN = "UNKNOWN"s; -static const std::string SSL_CERT_TYPE_PEM = "PEM"s; -static const std::string SSL_CERT_TYPE_DER = "DER"s; +static const std::string ssl_cert_type_unknown = "unknown"s; +static const std::string ssl_cert_type_pem = "PEM"s; +static const std::string ssl_cert_type_der = "DER"s; -auto to_string(SslCertificateType type) -> const std::string& +auto to_string(ssl_certificate_type type) -> const std::string& { switch (type) { - case SslCertificateType::PEM: - return SSL_CERT_TYPE_PEM; - case SslCertificateType::DER: - return SSL_CERT_TYPE_DER; + case ssl_certificate_type::pem: + return ssl_cert_type_pem; + case ssl_certificate_type::der: + return ssl_cert_type_der; default: - return SSL_CERT_TYPE_UNKNOWN; + return ssl_cert_type_unknown; } } -Request::Request( - std::string url, std::optional timeout, OnCompleteHandlerType on_complete_handler) +request::request( + std::string url, std::optional timeout, on_complete_handler_type on_complete_handler) : m_on_complete_handler(std::move(on_complete_handler)), m_timeout(std::move(timeout)), m_url(std::move(url)) { } -auto Request::Perform(SharePtr share_ptr) -> Response +auto request::perform(share_ptr share_ptr) -> response { executor exe{this, share_ptr.get()}; return exe.perform(); } -auto Request::OnCompleteHandler(OnCompleteHandlerType on_complete_handler) -> void +auto request::on_complete_handler(on_complete_handler_type on_complete_handler) -> void { m_on_complete_handler = std::move(on_complete_handler); } -auto Request::TransferProgressHandler(std::optional transfer_progress_handler) -> void +auto request::transfer_progress_handler(std::optional transfer_progress_handler) -> void { if (transfer_progress_handler.has_value() && transfer_progress_handler.value()) { @@ -53,7 +53,7 @@ auto Request::TransferProgressHandler(std::optional } } -auto Request::FollowRedirects(bool follow_redirects, std::optional max_redirects) -> void +auto request::follow_redirects(bool follow_redirects, std::optional max_redirects) -> void { if (follow_redirects) { @@ -76,16 +76,16 @@ auto Request::FollowRedirects(bool follow_redirects, std::optional max } } -auto Request::Header(std::string_view name, std::string_view value) -> void +auto request::header(std::string_view name, std::string_view value) -> void { m_request_headers.emplace_back(name, value); } -auto Request::Data(std::string data) -> void +auto request::data(std::string data) -> void { if (m_mime_fields_set) { - throw std::logic_error("Cannot set POST request data on Request after using adding Mime Fields."); + throw std::logic_error("Cannot set POST request data on request after using adding Mime Fields."); } m_request_data_set = true; @@ -93,15 +93,15 @@ auto Request::Data(std::string data) -> void m_method = http::method::post; } -auto Request::MimeField(lift::MimeField mime_field) -> void +auto request::mime_field(lift::mime_field mf) -> void { if (m_request_data_set) { - throw std::logic_error("Cannot add Mime Fields on Request after using POST request data."); + throw std::logic_error("Cannot add Mime Fields on request after using POST request data."); } m_mime_fields_set = true; - m_mime_fields.emplace_back(std::move(mime_field)); + m_mime_fields.emplace_back(std::move(mf)); } } // namespace lift diff --git a/src/resolve_host.cpp b/src/resolve_host.cpp index 2558cc4..29f1293 100644 --- a/src/resolve_host.cpp +++ b/src/resolve_host.cpp @@ -2,7 +2,7 @@ namespace lift { -ResolveHost::ResolveHost(std::string resolve_host, uint16_t resolve_port, std::string resolved_ip_addr) +resolve_host::resolve_host(std::string resolve_host, uint16_t resolve_port, std::string resolved_ip_addr) : m_resolve_host(std::move(resolve_host)), m_resolve_port(resolve_port), m_resolved_ip_addr(std::move(resolved_ip_addr)), diff --git a/src/response.cpp b/src/response.cpp index 3885e5c..e220edd 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -1,14 +1,29 @@ #include "lift/response.hpp" #include "lift/const.hpp" +#include + namespace lift { -Response::Response() +response::response() { m_headers.reserve(header_default_count); } -auto operator<<(std::ostream& os, const Response& r) -> std::ostream& +auto response::header(std::string_view name) const -> std::optional> +{ + for (const auto& header : m_headers) + { + if (header.name() == name) + { + return std::optional{std::cref(header)}; + } + } + + return std::nullopt; +} + +auto operator<<(std::ostream& os, const response& r) -> std::ostream& { os << lift::http::to_string(r.m_version) << ' ' << lift::http::to_string(r.m_status_code) << "\r\n"; for (const auto& header : r.m_headers) diff --git a/src/share.cpp b/src/share.cpp index fb67881..33b9ab6 100644 --- a/src/share.cpp +++ b/src/share.cpp @@ -6,50 +6,50 @@ auto curl_share_lock(CURL*, curl_lock_data data, curl_lock_access, void* user_pt auto curl_share_unlock(CURL*, curl_lock_data data, void* user_ptr) -> void; -Share::Share(ShareOptions share_options) +share::share(options opts) { curl_share_setopt(m_curl_share_ptr, CURLSHOPT_LOCKFUNC, curl_share_lock); curl_share_setopt(m_curl_share_ptr, CURLSHOPT_UNLOCKFUNC, curl_share_unlock); curl_share_setopt(m_curl_share_ptr, CURLSHOPT_USERDATA, this); - if (share_options == ShareOptions::NOTHING) + if (opts == options::nothing) { curl_share_setopt(m_curl_share_ptr, CURLSHOPT_SHARE, CURL_LOCK_DATA_NONE); } else { - if (static_cast(share_options) & static_cast(ShareOptions::DNS)) + if (static_cast(opts) & static_cast(options::dns)) { curl_share_setopt(m_curl_share_ptr, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); } - if (static_cast(share_options) & static_cast(ShareOptions::SSL)) + if (static_cast(opts) & static_cast(options::ssl)) { curl_share_setopt(m_curl_share_ptr, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); } - if (static_cast(share_options) & static_cast(ShareOptions::DATA)) + if (static_cast(opts) & static_cast(options::data)) { curl_share_setopt(m_curl_share_ptr, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); } } } -Share::~Share() +share::~share() { curl_share_cleanup(m_curl_share_ptr); } auto curl_share_lock(CURL*, curl_lock_data data, curl_lock_access, void* user_ptr) -> void { - auto& share = *static_cast(user_ptr); - share.m_curl_locks[static_cast(data)].lock(); + auto& s = *static_cast(user_ptr); + s.m_curl_locks[static_cast(data)].lock(); } auto curl_share_unlock(CURL*, curl_lock_data data, void* user_ptr) -> void { - auto& share = *static_cast(user_ptr); - share.m_curl_locks[static_cast(data)].unlock(); + auto& s = *static_cast(user_ptr); + s.m_curl_locks[static_cast(data)].unlock(); } } // namespace lift diff --git a/test/main.cpp b/test/main.cpp index 037fbc7..5698f40 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -7,12 +7,12 @@ struct TestSetupInfo { TestSetupInfo() { - std::cout << "SERVICE_IP_ADDRESS = " << SERVICE_IP_ADDRESS << "\n"; - std::cout << "NGINX_HOSTNAME = " - << "http://" << NGINX_HOSTNAME << ":" << NGINX_PORT_STR << "/" + std::cout << "service_ip_address = " << service_ip_address << "\n"; + std::cout << "nginx_hostname = " + << "http://" << nginx_hostname << ":" << nginx_port_str << "/" << "\n"; - std::cout << "HAPROXY_HOSTNAME = " - << "http://" << HAPROXY_HOSTNAME << ":" << HAPROXY_PORT_STR << "/" + std::cout << "haproxy_hostname = " + << "http://" << haproxy_hostname << ":" << haproxy_port_str << "/" << "\n"; } } test_setup_info_instance; diff --git a/test/setup.hpp b/test/setup.hpp index 21bab89..d729aed 100644 --- a/test/setup.hpp +++ b/test/setup.hpp @@ -2,17 +2,17 @@ #include #ifdef LIFT_LOCALHOST_TESTS -static inline const std::string SERVICE_IP_ADDRESS = "127.0.0.1"; -static inline const std::string NGINX_HOSTNAME = "localhost"; -static inline const std::string HAPROXY_HOSTNAME = "localhost"; +static inline const std::string service_ip_address = "127.0.0.1"; +static inline const std::string nginx_hostname = "localhost"; +static inline const std::string haproxy_hostname = "localhost"; #else // Note that this IP Address is asigned by github actions and is subject to change. -static inline const std::string SERVICE_IP_ADDRESS = "172.18.0.3"; -static inline const std::string NGINX_HOSTNAME = "nginx"; -static inline const std::string HAPROXY_HOSTNAME = "haproxy"; +static inline const std::string service_ip_address = "172.18.0.3"; +static inline const std::string nginx_hostname = "nginx"; +static inline const std::string haproxy_hostname = "haproxy"; #endif -static inline const uint16_t NGINX_PORT = 80; -static inline const std::string NGINX_PORT_STR = "80"; -static inline const uint32_t HAPROXY_PORT = 3128; -static inline const std::string HAPROXY_PORT_STR = "3128"; +static inline const uint16_t nginx_port = 80; +static inline const std::string nginx_port_str = "80"; +static inline const uint32_t haproxy_port = 3128; +static inline const std::string haproxy_port_str = "3128"; diff --git a/test/test_async_request.cpp b/test/test_async_request.cpp index 7c4099c..ab65be6 100644 --- a/test/test_async_request.cpp +++ b/test/test_async_request.cpp @@ -13,12 +13,12 @@ TEST_CASE("Async 100 requests") for (std::size_t i = 0; i < COUNT; ++i) { - auto r = std::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + auto r = std::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{1}, - [](std::unique_ptr rh, lift::Response response) -> void { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + [](std::unique_ptr rh, lift::response response) -> void { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); }); ev.start_request(std::move(r)); @@ -36,17 +36,17 @@ TEST_CASE("Async batch 100 requests") lift::event_loop ev{}; - std::vector> handles{}; + std::vector> handles{}; handles.reserve(COUNT); for (std::size_t i = 0; i < COUNT; ++i) { - auto r = std::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + auto r = std::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{1}, - [](std::unique_ptr, lift::Response response) -> void { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + [](std::unique_ptr, lift::response response) -> void { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); }); handles.emplace_back(std::move(r)); @@ -66,34 +66,34 @@ TEST_CASE("Async POST request") std::string data = "DATA DATA DATA!"; - auto request = std::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + auto request = std::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}, - [&](std::unique_ptr, lift::Response response) { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_405_method_not_allowed); + [&](std::unique_ptr, lift::response response) { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_405_method_not_allowed); }); - request->Data(data); - request->Method(lift::http::method::post); - request->FollowRedirects(true); - request->Version(lift::http::version::v1_1); + request->data(data); + request->method(lift::http::method::post); + request->follow_redirects(true); + request->version(lift::http::version::v1_1); // request->header("Expect", ""); ev.start_request(std::move(request)); - request = std::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + request = std::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}, - [&](std::unique_ptr, lift::Response response) { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_405_method_not_allowed); + [&](std::unique_ptr, lift::response response) { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_405_method_not_allowed); }); - request->Data(data); - request->Method(lift::http::method::post); - request->FollowRedirects(true); - request->Version(lift::http::version::v1_1); + request->data(data); + request->method(lift::http::method::post); + request->follow_redirects(true); + request->version(lift::http::version::v1_1); // There was a bug where no expect header caused liblift to fail, test it explicitly - request->Header("Expect", ""); + request->header("Expect", ""); ev.start_request(std::move(request)); } diff --git a/test/test_event_loop.cpp b/test/test_event_loop.cpp index f811aaf..75a841e 100644 --- a/test/test_event_loop.cpp +++ b/test/test_event_loop.cpp @@ -6,22 +6,22 @@ TEST_CASE("event_loop Start event loop, then stop and add a request.") { lift::event_loop ev{}; - auto request = lift::Request::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + auto request = lift::request::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}, - [&](std::unique_ptr, lift::Response response) { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + [&](std::unique_ptr, lift::response response) { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); }); REQUIRE(ev.start_request(std::move(request))); - request = lift::Request::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + request = lift::request::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}, - [&](std::unique_ptr, lift::Response response) { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + [&](std::unique_ptr, lift::response response) { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); }); // Adding requests after stopping should return false that they cannot be started. @@ -34,22 +34,22 @@ TEST_CASE("event_loop Start event loop, then stop and add multiple requests.") { lift::event_loop ev{}; - std::vector requests1; - requests1.emplace_back(lift::Request::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + std::vector requests1; + requests1.emplace_back(lift::request::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}, - [&](std::unique_ptr, lift::Response response) { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + [&](std::unique_ptr, lift::response response) { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); })); - std::vector requests2; - requests2.emplace_back(lift::Request::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + std::vector requests2; + requests2.emplace_back(lift::request::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}, - [&](std::unique_ptr, lift::Response response) { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + [&](std::unique_ptr, lift::response response) { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); })); REQUIRE(ev.start_requests(std::move(requests1))); diff --git a/test/test_header.cpp b/test/test_header.cpp index 0f7d1a4..89ec634 100644 --- a/test/test_header.cpp +++ b/test/test_header.cpp @@ -22,17 +22,17 @@ TEST_CASE("header request that re-allocates the underlying vector a lot") { constexpr size_t N_HEADERS = 65'000; // lets make a lot of headers to re-allocate a few times - lift::Request request{"http://herpderp.com"}; + lift::request request{"http://herpderp.com"}; for (size_t i = 0; i < N_HEADERS; ++i) { auto name = "name" + std::to_string(i); auto value = "value" + std::to_string(i); - request.Header(name, value); + request.header(name, value); } size_t idx = 0; - for (const auto& header : request.Headers()) + for (const auto& header : request.headers()) { auto idx_str = std::to_string(idx); auto name = "name" + idx_str; @@ -56,7 +56,7 @@ TEST_CASE("header from full") REQUIRE(h.value() == "value"); } -TEST_CASE("header lots of allocations in a vector (simulate Response)") +TEST_CASE("header lots of allocations in a vector (simulate response)") { constexpr size_t N_HEADERS = 65'000; // lets make a lot of headers to re-allocate a few times diff --git a/test/test_mime_field.cpp b/test/test_mime_field.cpp index eaac425..957cf58 100644 --- a/test/test_mime_field.cpp +++ b/test/test_mime_field.cpp @@ -2,42 +2,42 @@ #include "setup.hpp" #include -TEST_CASE("MimeField field_value") +TEST_CASE("mime_field field_value") { - lift::MimeField mime{"name", std::string{"value"}}; + lift::mime_field mime{"name", std::string{"value"}}; - REQUIRE(mime.Name() == "name"); - REQUIRE(std::holds_alternative(mime.Value())); - auto value = std::get(mime.Value()); + REQUIRE(mime.name() == "name"); + REQUIRE(std::holds_alternative(mime.value())); + auto value = std::get(mime.value()); REQUIRE(value == "value"); } -TEST_CASE("MimeField field_filepath") +TEST_CASE("mime_field field_filepath") { - lift::MimeField mime{"name2", std::filesystem::path{"/var/log/lift.log"}}; + lift::mime_field mime{"name2", std::filesystem::path{"/var/log/lift.log"}}; - REQUIRE(mime.Name() == "name2"); - REQUIRE(std::holds_alternative(mime.Value())); - auto path = std::get(mime.Value()); + REQUIRE(mime.name() == "name2"); + REQUIRE(std::holds_alternative(mime.value())); + auto path = std::get(mime.value()); REQUIRE(path.string() == "/var/log/lift.log"); } -TEST_CASE("MimeField added to Request") +TEST_CASE("mime_field added to request") { - lift::MimeField mime1{"name1", std::string{"value"}}; - lift::MimeField mime2{"name2", std::filesystem::path{"/var/log/lift.log"}}; + lift::mime_field mime1{"name1", std::string{"value"}}; + lift::mime_field mime2{"name2", std::filesystem::path{"/var/log/lift.log"}}; - lift::Request request{"http://derp.com"}; + lift::request request{"http://derp.com"}; - request.MimeField(std::move(mime1)); - request.MimeField(std::move(mime2)); + request.mime_field(std::move(mime1)); + request.mime_field(std::move(mime2)); - const auto& mime_fields = request.MimeFields(); + const auto& mime_fields = request.mime_fields(); REQUIRE(mime_fields.size() == 2); - REQUIRE(mime_fields[0].Name() == "name1"); - REQUIRE(std::holds_alternative(mime_fields[0].Value())); - REQUIRE(std::get(mime_fields[0].Value()) == "value"); - REQUIRE(mime_fields[1].Name() == "name2"); - REQUIRE(std::holds_alternative(mime_fields[1].Value())); - REQUIRE(std::get(mime_fields[1].Value()) == "/var/log/lift.log"); + REQUIRE(mime_fields[0].name() == "name1"); + REQUIRE(std::holds_alternative(mime_fields[0].value())); + REQUIRE(std::get(mime_fields[0].value()) == "value"); + REQUIRE(mime_fields[1].name() == "name2"); + REQUIRE(std::holds_alternative(mime_fields[1].value())); + REQUIRE(std::get(mime_fields[1].value()) == "/var/log/lift.log"); } diff --git a/test/test_proxy.cpp b/test/test_proxy.cpp index ad08ec6..fd0d241 100644 --- a/test/test_proxy.cpp +++ b/test/test_proxy.cpp @@ -4,17 +4,17 @@ #include -TEST_CASE("Proxy") +TEST_CASE("proxy") { // Need to do research but cannot add a port for the proxied request, leaving off for now. - lift::Request request{"http://" + NGINX_HOSTNAME + "/"}; - request.Proxy(lift::ProxyType::HTTP, HAPROXY_HOSTNAME, HAPROXY_PORT); + lift::request request{"http://" + nginx_hostname + "/"}; + request.proxy(lift::proxy_type::http, haproxy_hostname, haproxy_port); - const auto& response = request.Perform(); + const auto& response = request.perform(); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); - for (const auto& header : response.Headers()) + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); + for (const auto& header : response.headers()) { if (header.name() == "server") { @@ -32,22 +32,22 @@ TEST_CASE("Proxy") } } -TEST_CASE("Proxy Basic Auth") +TEST_CASE("proxy Basic Auth") { - lift::Request request{"http://" + NGINX_HOSTNAME + "/"}; - request.Proxy( - lift::ProxyType::HTTP, - HAPROXY_HOSTNAME, - HAPROXY_PORT, + lift::request request{"http://" + nginx_hostname + "/"}; + request.proxy( + lift::proxy_type::http, + haproxy_hostname, + haproxy_port, "guest", "guestpassword", - std::vector{lift::HttpAuthType::BASIC}); + std::vector{lift::http_auth_type::basic}); - const auto& response = request.Perform(); + const auto& response = request.perform(); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); - for (const auto& header : response.Headers()) + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); + for (const auto& header : response.headers()) { if (header.name() == "server") { @@ -65,22 +65,22 @@ TEST_CASE("Proxy Basic Auth") } } -TEST_CASE("Proxy Any Auth") +TEST_CASE("proxy Any Auth") { - lift::Request request{"http://" + NGINX_HOSTNAME + "/"}; - request.Proxy( - lift::ProxyType::HTTP, - HAPROXY_HOSTNAME, - HAPROXY_PORT, + lift::request request{"http://" + nginx_hostname + "/"}; + request.proxy( + lift::proxy_type::http, + haproxy_hostname, + haproxy_port, "guest", "guestpassword", - std::vector{lift::HttpAuthType::ANY}); + std::vector{lift::http_auth_type::any_safe}); - const auto& response = request.Perform(); + const auto& response = request.perform(); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); - for (const auto& header : response.Headers()) + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); + for (const auto& header : response.headers()) { if (header.name() == "server") { diff --git a/test/test_query_builder.cpp b/test/test_query_builder.cpp index 5b3d4ed..c9de2a4 100644 --- a/test/test_query_builder.cpp +++ b/test/test_query_builder.cpp @@ -4,21 +4,21 @@ TEST_CASE("Query Builder simple") { - lift::QueryBuilder query_builder{}; - query_builder.Scheme("https") - .Hostname("www.example.com") - .Port(443) - .AppendPathPart("test") - .AppendPathPart("path") - .AppendQueryParameter("param1", "value1") - .AppendQueryParameter("param2", "value2"); + lift::query_builder qb{}; + qb.scheme("https") + .hostname("www.example.com") + .port(443) + .append_path_part("test") + .append_path_part("path") + .append_query_parameter("param1", "value1") + .append_query_parameter("param2", "value2"); - auto url = query_builder.Build(); + auto url = qb.build(); REQUIRE(url == "https://www.example.com:443/test/path?param1=value1¶m2=value2"); - query_builder.Scheme("http").Hostname("www.reddit.com").AppendPathPart("r").AppendPathPart("funny"); - url = query_builder.Build(); + qb.scheme("http").hostname("www.reddit.com").append_path_part("r").append_path_part("funny"); + url = qb.build(); REQUIRE(url == "http://www.reddit.com/r/funny"); } diff --git a/test/test_resolve_host.cpp b/test/test_resolve_host.cpp index 41854d2..2299096 100644 --- a/test/test_resolve_host.cpp +++ b/test/test_resolve_host.cpp @@ -2,41 +2,41 @@ #include "setup.hpp" #include -TEST_CASE("ResolveHost synchronous perform") +TEST_CASE("resolve_host synchronous perform") { - lift::ResolveHost rhost{"testhostname", NGINX_PORT, SERVICE_IP_ADDRESS}; + lift::resolve_host rhost{"testhostname", nginx_port, service_ip_address}; - REQUIRE(rhost.Host() == "testhostname"); - REQUIRE(rhost.Port() == NGINX_PORT); - REQUIRE(rhost.IpAddr() == SERVICE_IP_ADDRESS); + REQUIRE(rhost.host() == "testhostname"); + REQUIRE(rhost.port() == nginx_port); + REQUIRE(rhost.ip_addr() == service_ip_address); - lift::Request request{"http://testhostname:" + NGINX_PORT_STR + "/"}; + lift::request request{"http://testhostname:" + nginx_port_str + "/"}; - request.ResolveHost(std::move(rhost)); + request.resolve_host(std::move(rhost)); - auto response = request.Perform(); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + auto response = request.perform(); + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); } -TEST_CASE("ResolveHost event_loop") +TEST_CASE("resolve_host event_loop") { - std::vector rhosts{ - lift::ResolveHost{"testhostname", NGINX_PORT, SERVICE_IP_ADDRESS}, - lift::ResolveHost{"herpderp.com", NGINX_PORT, SERVICE_IP_ADDRESS}}; + std::vector rhosts{ + lift::resolve_host{"testhostname", nginx_port, service_ip_address}, + lift::resolve_host{"herpderp.com", nginx_port, service_ip_address}}; lift::event_loop ev{lift::event_loop::options{.resolve_hosts = std::move(rhosts)}}; - auto on_complete = [&](lift::RequestPtr, lift::Response response) -> void { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + auto on_complete = [&](lift::request_ptr, lift::response response) -> void { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); }; - std::vector requests; + std::vector requests; requests.emplace_back( - lift::Request::make_unique("testhostname:" + NGINX_PORT_STR, std::chrono::seconds{60}, on_complete)); + lift::request::make_unique("testhostname:" + nginx_port_str, std::chrono::seconds{60}, on_complete)); requests.emplace_back( - lift::Request::make_unique("herpderp.com:" + NGINX_PORT_STR, std::chrono::seconds{60}, on_complete)); + lift::request::make_unique("herpderp.com:" + nginx_port_str, std::chrono::seconds{60}, on_complete)); REQUIRE(ev.start_requests(std::move(requests))); } diff --git a/test/test_share.cpp b/test/test_share.cpp index 4980402..c3da36f 100644 --- a/test/test_share.cpp +++ b/test/test_share.cpp @@ -2,58 +2,58 @@ #include "setup.hpp" #include -TEST_CASE("Share Requests ALL") +TEST_CASE("share requests ALL") { - auto lift_share_ptr = std::make_shared(lift::ShareOptions::ALL); + auto lift_share_ptr = std::make_shared(lift::share::options::all); for (std::size_t i = 0; i < 5; ++i) { - lift::Request request{"http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", std::chrono::seconds{60}}; + lift::request request{"http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}}; - auto response = request.Perform(lift_share_ptr); + auto response = request.perform(lift_share_ptr); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); } } -TEST_CASE("Share Requests NOTHING") +TEST_CASE("share requests NOTHING") { - auto lift_share_ptr = std::make_shared(lift::ShareOptions::NOTHING); + auto lift_share_ptr = std::make_shared(lift::share::options::nothing); for (std::size_t i = 0; i < 5; ++i) { - lift::Request request{"http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", std::chrono::seconds{60}}; + lift::request request{"http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}}; - auto response = request.Perform(lift_share_ptr); + auto response = request.perform(lift_share_ptr); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); } } -TEST_CASE("Share event_loop synchronous") +TEST_CASE("share event_loop synchronous") { - auto lift_share_ptr = std::make_shared(lift::ShareOptions::ALL); + auto lift_share_ptr = std::make_shared(lift::share::options::all); - lift::event_loop ev1{lift::event_loop::options{.share_ptr = lift_share_ptr}}; + lift::event_loop ev1{lift::event_loop::options{.share = lift_share_ptr}}; - lift::event_loop ev2{lift::event_loop::options{.share_ptr = lift_share_ptr}}; + lift::event_loop ev2{lift::event_loop::options{.share = lift_share_ptr}}; - auto request1 = lift::Request::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + auto request1 = lift::request::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}, - [&](std::unique_ptr, lift::Response response) { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + [&](std::unique_ptr, lift::response response) { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); }); - auto request2 = lift::Request::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + auto request2 = lift::request::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{60}, - [&](std::unique_ptr, lift::Response response) { - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + [&](std::unique_ptr, lift::response response) { + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); }); ev1.start_request(std::move(request1)); @@ -69,7 +69,7 @@ TEST_CASE("Share event_loop synchronous") ev2.stop(); } -TEST_CASE("Share event_loop overlapping requests") +TEST_CASE("share event_loop overlapping requests") { std::atomic count{0}; @@ -77,22 +77,22 @@ TEST_CASE("Share event_loop overlapping requests") constexpr size_t N_EVENT_LOOPS = 2; constexpr size_t N_REQUESTS = 10'000; - std::vector> lift_share{}; + std::vector> lift_share{}; for (size_t i = 0; i < N_SHARE; ++i) { - lift_share.emplace_back(std::make_shared(lift::ShareOptions::ALL)); + lift_share.emplace_back(std::make_shared(lift::share::options::all)); } auto worker_func = [&count, &lift_share]() { static size_t share_counter{0}; - lift::event_loop el{lift::event_loop::options{.share_ptr = lift_share[share_counter++ % N_SHARE]}}; + lift::event_loop el{lift::event_loop::options{.share = lift_share[share_counter++ % N_SHARE]}}; for (size_t i = 0; i < N_REQUESTS; ++i) { - auto request_ptr = lift::Request::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", + auto request_ptr = lift::request::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{5}, - [&](std::unique_ptr, lift::Response response) { + [&](std::unique_ptr, lift::response response) { count.fetch_add(1, std::memory_order_relaxed); }); diff --git a/test/test_sync_request.cpp b/test/test_sync_request.cpp index dcec870..bc9f1d5 100644 --- a/test/test_sync_request.cpp +++ b/test/test_sync_request.cpp @@ -6,39 +6,39 @@ TEST_CASE("Synchronous 200") { - lift::Request request("http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/"); - const auto& response = request.Perform(); + lift::request request("http://" + nginx_hostname + ":" + nginx_port_str + "/"); + const auto& response = request.perform(); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); } TEST_CASE("Synchronous 404") { - lift::Request request("http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/not/here"); - const auto& response = request.Perform(); + lift::request request("http://" + nginx_hostname + ":" + nginx_port_str + "/not/here"); + const auto& response = request.perform(); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_404_not_found); + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_404_not_found); } TEST_CASE("Synchronous HEAD") { - lift::Request request("http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/"); - request.Method(lift::http::method::head); - const auto& response = request.Perform(); + lift::request request("http://" + nginx_hostname + ":" + nginx_port_str + "/"); + request.method(lift::http::method::head); + const auto& response = request.perform(); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); - REQUIRE(response.Data().empty()); + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); + REQUIRE(response.data().empty()); } TEST_CASE("Synchronous custom headers") { - lift::Request request("http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/"); - request.Header("x-custom-header-1", "custom-value-1"); + lift::request request("http://" + nginx_hostname + ":" + nginx_port_str + "/"); + request.header("x-custom-header-1", "custom-value-1"); - for (const auto& header : request.Headers()) + for (const auto& header : request.headers()) { if (header.name() == "x-custom-header-1") { @@ -49,21 +49,21 @@ TEST_CASE("Synchronous custom headers") TEST_CASE("Multiple headers added") { - lift::Request request("http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/"); - request.Header("Connection", "keep-alive"); - request.Header("x-custom-header-1", "value1"); - request.Header("x-custom-header-2", "value2"); - request.Header("x-herp-derp", "merp"); - request.Header("x-420", "blazeit"); + lift::request request("http://" + nginx_hostname + ":" + nginx_port_str + "/"); + request.header("Connection", "keep-alive"); + request.header("x-custom-header-1", "value1"); + request.header("x-custom-header-2", "value2"); + request.header("x-herp-derp", "merp"); + request.header("x-420", "blazeit"); - const auto& response = request.Perform(); + const auto& response = request.perform(); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); std::size_t count_found = 0; - for (const auto& header : request.Headers()) + for (const auto& header : request.headers()) { if (header.name() == "Connection") { @@ -98,13 +98,13 @@ TEST_CASE("Multiple headers added") TEST_CASE("Happy Eyeballs Test") { using namespace std::chrono_literals; - lift::Request request{"http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/"}; - request.HappyEyeballsTimeout(0ms); + lift::request request{"http://" + nginx_hostname + ":" + nginx_port_str + "/"}; + request.happy_eyeballs_timeout(0ms); - const auto& response = request.Perform(); + const auto& response = request.perform(); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); } TEST_CASE("SSL functions") diff --git a/test/test_timesup.cpp b/test/test_timesup.cpp index e8f86bc..31b1805 100644 --- a/test/test_timesup.cpp +++ b/test/test_timesup.cpp @@ -9,15 +9,15 @@ TEST_CASE("Timesup single request") { lift::event_loop ev{lift::event_loop::options{.connect_timeout = std::chrono::seconds{1}}}; - auto r = lift::Request::make_unique( + auto r = lift::request::make_unique( "http://www.reddit.com", // should be slow enough /shrug std::chrono::milliseconds{25}, - [](std::unique_ptr rh, lift::Response response) -> void { - REQUIRE(response.LiftStatus() == lift::LiftStatus::TIMEOUT); - REQUIRE(response.StatusCode() == lift::http::status_code::http_504_gateway_timeout); - REQUIRE(response.TotalTime() == std::chrono::milliseconds{25}); - REQUIRE(response.NumConnects() == 0); - REQUIRE(response.NumRedirects() == 0); + [](std::unique_ptr rh, lift::response response) -> void { + REQUIRE(response.lift_status() == lift::lift_status::timeout); + REQUIRE(response.status_code() == lift::http::status_code::http_504_gateway_timeout); + REQUIRE(response.total_time() == std::chrono::milliseconds{25}); + REQUIRE(response.num_connects() == 0); + REQUIRE(response.num_redirects() == 0); }); ev.start_request(std::move(r)); @@ -32,24 +32,24 @@ TEST_CASE("Timesup two requests") { lift::event_loop ev{lift::event_loop::options{.connect_timeout = std::chrono::seconds{1}}}; - std::vector requests{}; + std::vector requests{}; - requests.push_back(lift::Request::make_unique( + requests.push_back(lift::request::make_unique( "http://www.reddit.com", // should be slow enough /shrug std::chrono::milliseconds{25}, - [](std::unique_ptr rh, lift::Response response) -> void { - REQUIRE(response.LiftStatus() == lift::LiftStatus::TIMEOUT); - REQUIRE(response.StatusCode() == lift::http::status_code::http_504_gateway_timeout); - REQUIRE(response.TotalTime() == std::chrono::milliseconds{25}); + [](std::unique_ptr rh, lift::response response) -> void { + REQUIRE(response.lift_status() == lift::lift_status::timeout); + REQUIRE(response.status_code() == lift::http::status_code::http_504_gateway_timeout); + REQUIRE(response.total_time() == std::chrono::milliseconds{25}); })); - requests.push_back(lift::Request::make_unique( + requests.push_back(lift::request::make_unique( "http://www.reddit.com", // should be slow enough /shrug std::chrono::milliseconds{50}, - [](std::unique_ptr rh, lift::Response response) -> void { - REQUIRE(response.LiftStatus() == lift::LiftStatus::TIMEOUT); - REQUIRE(response.StatusCode() == lift::http::status_code::http_504_gateway_timeout); - REQUIRE(response.TotalTime() == std::chrono::milliseconds{50}); + [](std::unique_ptr rh, lift::response response) -> void { + REQUIRE(response.lift_status() == lift::lift_status::timeout); + REQUIRE(response.status_code() == lift::http::status_code::http_504_gateway_timeout); + REQUIRE(response.total_time() == std::chrono::milliseconds{50}); })); ev.start_requests(std::move(requests)); diff --git a/test/test_transfer_progress_request.cpp b/test/test_transfer_progress_request.cpp index 50023d7..13a411f 100644 --- a/test/test_transfer_progress_request.cpp +++ b/test/test_transfer_progress_request.cpp @@ -6,31 +6,31 @@ TEST_CASE("Transfer Progress synchronous") { - auto request = std::make_unique("http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/"); + auto request = std::make_unique("http://" + nginx_hostname + ":" + nginx_port_str + "/"); std::size_t handler_called = 0; - request->TransferProgressHandler( - [&](const lift::Request& r, int64_t dltotal, int64_t dlnow, int64_t ultotal, int64_t ulnow) -> bool { + request->transfer_progress_handler( + [&](const lift::request& r, int64_t dltotal, int64_t dlnow, int64_t ultotal, int64_t ulnow) -> bool { handler_called++; return true; // continue the request }); - const auto& response = request->Perform(); + const auto& response = request->perform(); REQUIRE(handler_called > 0); - REQUIRE(response.LiftStatus() == lift::LiftStatus::SUCCESS); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + REQUIRE(response.lift_status() == lift::lift_status::success); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); } TEST_CASE("Download bytes test synchronous") { - auto request = std::make_unique("http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/"); + auto request = std::make_unique("http://" + nginx_hostname + ":" + nginx_port_str + "/"); bool should_failed = true; static constexpr std::size_t BYTES_TO_DOWNLOAD = 5; - request->TransferProgressHandler( - [&](const lift::Request& r, int64_t dltotal, int64_t dlnow, int64_t, int64_t) -> bool { + request->transfer_progress_handler( + [&](const lift::request& r, int64_t dltotal, int64_t dlnow, int64_t, int64_t) -> bool { if (dlnow >= BYTES_TO_DOWNLOAD) { should_failed = true; @@ -46,9 +46,9 @@ TEST_CASE("Download bytes test synchronous") } }); - const auto& response = request->Perform(); + const auto& response = request->perform(); // Its possible the test downloads the entire file before finishing, take the appropriate action. - REQUIRE(response.LiftStatus() == ((should_failed) ? lift::LiftStatus::ERROR : lift::LiftStatus::SUCCESS)); - REQUIRE(response.StatusCode() == lift::http::status_code::http_200_ok); + REQUIRE(response.lift_status() == ((should_failed) ? lift::lift_status::error : lift::lift_status::success)); + REQUIRE(response.status_code() == lift::http::status_code::http_200_ok); } diff --git a/test/test_user_data_request.cpp b/test/test_user_data_request.cpp index 26a1951..227a724 100644 --- a/test/test_user_data_request.cpp +++ b/test/test_user_data_request.cpp @@ -3,7 +3,7 @@ #include static auto user_data_on_complete( - lift::RequestPtr request_ptr, lift::Response response, uint64_t user_data_value1, double user_data_value2) -> void + lift::request_ptr request_ptr, lift::response response, uint64_t user_data_value1, double user_data_value2) -> void { if (user_data_value1 == 1) { @@ -28,18 +28,18 @@ TEST_CASE("User data") // more like an example we'll include a unique "request_id" that gets captured as the user data. uint64_t request_id = 1; - auto req1 = std::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", std::chrono::seconds{1}); - req1->OnCompleteHandler([request_id](lift::RequestPtr request, lift::Response response) { + auto req1 = std::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{1}); + req1->on_complete_handler([request_id](lift::request_ptr request, lift::response response) { user_data_on_complete(std::move(request), std::move(response), request_id, 100.5); }); el.start_request(std::move(req1)); request_id = 2; - auto req2 = std::make_unique( - "http://" + NGINX_HOSTNAME + ":" + NGINX_PORT_STR + "/", std::chrono::seconds{1}); - req2->OnCompleteHandler([request_id](lift::RequestPtr request, lift::Response response) { + auto req2 = std::make_unique( + "http://" + nginx_hostname + ":" + nginx_port_str + "/", std::chrono::seconds{1}); + req2->on_complete_handler([request_id](lift::request_ptr request, lift::response response) { user_data_on_complete(std::move(request), std::move(response), request_id, 1234.567); }); el.start_request(std::move(req2)); From bfd8f531a734563bc4390d40da8c923ed92aec8c Mon Sep 17 00:00:00 2001 From: jbaldwin Date: Sun, 22 Nov 2020 18:51:46 -0700 Subject: [PATCH 5/6] share explicit ctor --- inc/lift/share.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/lift/share.hpp b/inc/lift/share.hpp index a1956c4..32cf4b7 100644 --- a/inc/lift/share.hpp +++ b/inc/lift/share.hpp @@ -39,7 +39,7 @@ class share /** * @param opts The specific items to share between requests. */ - share(options opts); + explicit share(options opts); ~share(); share(const share&) = delete; From 8af1cbf206bf1513fa034f5ada2e91d653fd9619 Mon Sep 17 00:00:00 2001 From: jbaldwin Date: Sun, 22 Nov 2020 18:55:37 -0700 Subject: [PATCH 6/6] share std::enable_shared_from_this --- inc/lift/share.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/inc/lift/share.hpp b/inc/lift/share.hpp index 32cf4b7..b30b6e4 100644 --- a/inc/lift/share.hpp +++ b/inc/lift/share.hpp @@ -10,7 +10,7 @@ namespace lift { class executor; -class share +class share : public std::enable_shared_from_this { friend executor; @@ -47,6 +47,8 @@ class share auto operator=(const share&) noexcept -> share& = delete; auto operator=(share&&) noexcept -> share& = delete; + static auto make_shared(options opts) -> std::shared_ptr { return std::make_shared(std::move(opts)); } + private: CURLSH* m_curl_share_ptr{curl_share_init()};