diff --git a/CMakeLists.txt b/CMakeLists.txt index e6107e1..e236972 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,14 @@ cmake_minimum_required(VERSION 3.18) +project(whaleroute VERSION 1.0.0 DESCRIPTION "C++17 request routing library") -if(NOT DEFINED WHALEROUTE_SUBPROJECT) - if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) - set(WHALEROUTE_SUBPROJECT OFF) - else() - set(WHALEROUTE_SUBPROJECT ON) - endif() +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(WHALEROUTE_SUBPROJECT OFF) +else() + set(WHALEROUTE_SUBPROJECT ON) endif() -project(whaleroute VERSION 1.0.0 DESCRIPTION "C++17 request routing library") - add_library(whaleroute INTERFACE) +add_library(whaleroute::whaleroute ALIAS whaleroute) target_compile_features(whaleroute INTERFACE cxx_std_17) target_include_directories( @@ -26,7 +24,35 @@ if (ENABLE_TESTS AND NOT WHALEROUTE_SUBPROJECT) add_subdirectory(tests) endif() -include(GNUInstallDirs) -if(NOT WHALEROUTE_SUBPROJECT) +option(INSTALL_WHALEROUTE "Install whaleroute library unconditionally" OFF) +if (NOT WHALEROUTE_SUBPROJECT OR INSTALL_WHALEROUTE) + include(GNUInstallDirs) install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/whaleroute DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + + set(WHALEROUTE_PACK_PATH ${CMAKE_INSTALL_LIBDIR}/cmake/whaleroute) + + install(TARGETS whaleroute + EXPORT whaleroute-targets + ) + install(EXPORT whaleroute-targets + FILE whalerouteTargets.cmake + NAMESPACE whaleroute:: + DESTINATION ${WHALEROUTE_PACK_PATH} + ) + + include(CMakePackageConfigHelpers) + write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/whalerouteConfigVersion.cmake + COMPATIBILITY SameMajorVersion + ARCH_INDEPENDENT + ) + configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/cmake/whalerouteConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/whalerouteConfig.cmake + INSTALL_DESTINATION ${WHALEROUTE_PACK_PATH} + ) + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/whalerouteConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/whalerouteConfigVersion.cmake + DESTINATION ${WHALEROUTE_PACK_PATH} + ) endif() diff --git a/README.md b/README.md index f23209b..36afc4f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,21 @@ **whaleroute** - is a C++17 header-only library for request routing. It's designed for binding handlers to HTTP requests, but it can easily be used with other protocols, as the library is implemented as a generic class template. If your incoming data processing function has a signature like `void(const Request&, Response&)` and you need to perform different actions based on a string value from the request object, **whaleroute** can be a big help. -### Usage + +* [Usage](#implementing-the-router) + * [Implementing the router](#implementing-the-router) + * [Registering the request type](#registering-the-request-type) + * [Registering the request processing class](#registering-the-request-processing-class) + * [Registering the response value setter](#registering-the-response-value-setter) + * [Using regular expressions](#using-regular-expressions) + * [Trailing slash matching](#trailing-slash-matching) + * [Processing unmatched requests](#processing-unmatched-requests) + * [Authorization](#authorization) + * [Using RequestProcessorQueue](#using-requestprocessorqueue) +* [Installation](#installation) +* [Running tests](#running-tests) +* [License](#license) + #### Implementing the router Let's say that our Request and Response classes look like this: ```c++ @@ -209,6 +223,10 @@ Router's `route` method can take a standard regular expression instead of a stri router.route(std::regex{"/.*"}, demo::Request::Method::GET).set("HTTP/1.1 200 OK\r\n\r\n"); ``` +#### Trailing slash matching +By default **whaleroute** treats trailing slashes in requests and routes paths as optional, e.g. `/path` and `/path/` are considered equal. +You can change this by using a `whaleroute::RequestRouter`'s method `setTrailingSlashMode` with a value `whaleroute::TrailingSlashMode::Strict`. + #### Processing unmatched requests Using the `route` method without arguments registers a processor for requests that don't match any existing routes. It's an alternative of a `processUnmatchedRequest` virtual method, it won't be called if you use a `route()` instead. ```c++ @@ -272,6 +290,15 @@ Now we can set up the router with authorization settings: Now any request to the URI starting with `/vip/` will get a 401 response status. +#### Using RequestProcessorQueue +If you check how `whaleroute::RequestRouter`'s processing method `process` is implemented, you'll see that it just creates a `whale::RequestProcessorQueue` object and forwards processing request by calling its `launch` method: +```c++ + auto queue = makeRequestProcessorQueue(request, response); + queue.launch(); +``` +`whaleroute::RequestProcessorQueue` is a sequence of all matched route processors, that can be launched and stopped by calling its `launch()` and `stop()` methods. +It's available in the public interface, so you can create and use `RequestProcessorQueue` directly, without using `RequestRouter::process` method. It can be really helpful if you use **whaleroute** in asynchronous environment - this way route processing can be postponed by stopping the queue and resumed in request handler's callback on a captured copy of the queue. +Otherwise, you can disregard this information and just use `RequestRouter::process` method. ### Installation Download and link the library from your project's CMakeLists.txt: @@ -284,10 +311,12 @@ FetchContent_Declare(whaleroute GIT_REPOSITORY "https://github.com/kamchatka-volcano/whaleroute.git" GIT_TAG "origin/master" ) +#uncomment if you need to install whaleroot with your target +#set(INSTALL_WHALEROOT ON) FetchContent_MakeAvailable(whaleroute) add_executable(${PROJECT_NAME}) -target_link_libraries(${PROJECT_NAME} PRIVATE whaleroute) +target_link_libraries(${PROJECT_NAME} PRIVATE whaleroute::whaleroute) ``` For the system-wide installation use these commands: @@ -299,6 +328,12 @@ cmake --build build cmake --install build ``` +Afterwards, you can use find_package() command to make installed library available inside your project: +``` +find_package(whaleroute 1.0.0 REQUIRED) +target_link_libraries(${PROJECT_NAME} PRIVATE whaleroute::whaleroute) +``` + ### Running tests ``` cd whaleroute diff --git a/cmake/whalerouteConfig.cmake.in b/cmake/whalerouteConfig.cmake.in new file mode 100644 index 0000000..9ef6be5 --- /dev/null +++ b/cmake/whalerouteConfig.cmake.in @@ -0,0 +1,3 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/whalerouteTargets.cmake")