mirror of
https://github.com/yhirose/cpp-httplib
synced 2026-06-08 18:30:49 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3dfb4ecac2 | |||
| 144114f316 | |||
| 0cc108d45e | |||
| 0743d78c9b | |||
| e022b8b80b | |||
| 34282c79a9 | |||
| f80b6bd980 | |||
| 5af7222217 | |||
| ec00fe5d5b | |||
| 24bdb736f0 | |||
| d0dc200633 | |||
| 919a51091f | |||
| 05e8b22989 | |||
| 00dcd6b004 | |||
| a42c6b99d3 | |||
| 812cb5bc3d | |||
| aea60feb85 | |||
| b3a4045300 | |||
| 5fcd8f7795 | |||
| d9fe3fa020 |
+47
-4
@@ -32,11 +32,15 @@
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
These three variables are available after you run find_package(httplib)
|
||||
* HTTPLIB_HEADER_PATH - this is the full path to the installed header.
|
||||
These variables are available after you run find_package(httplib)
|
||||
* HTTPLIB_HEADER_PATH - this is the full path to the installed header (e.g. /usr/include/httplib.h).
|
||||
* HTTPLIB_IS_USING_OPENSSL - a bool for if OpenSSL support is enabled.
|
||||
* HTTPLIB_IS_USING_ZLIB - a bool for if ZLIB support is enabled.
|
||||
* HTTPLIB_IS_COMPILED - a bool for if the library is header-only or compiled.
|
||||
* HTTPLIB_IS_COMPILED - a bool for if the library is compiled, or otherwise header-only.
|
||||
* HTTPLIB_INCLUDE_DIR - the root path to httplib's header (e.g. /usr/include).
|
||||
* HTTPLIB_LIBRARY - the full path to the library if compiled (e.g. /usr/lib/libhttplib.so).
|
||||
* HTTPLIB_VERSION - the project's version string.
|
||||
* HTTPLIB_FOUND - a bool for if the target was found.
|
||||
|
||||
Want to use precompiled headers (Cmake feature since v3.16)?
|
||||
It's as simple as doing the following (before linking):
|
||||
@@ -48,7 +52,28 @@
|
||||
FindPython3 requires Cmake v3.12
|
||||
]]
|
||||
cmake_minimum_required(VERSION 3.12.0 FATAL_ERROR)
|
||||
project(httplib LANGUAGES CXX)
|
||||
|
||||
# Gets the latest tag as a string like "v0.6.6"
|
||||
# Can silently fail if git isn't on the system
|
||||
execute_process(COMMAND git describe --tags --abbrev=0
|
||||
OUTPUT_VARIABLE _raw_version_string
|
||||
ERROR_VARIABLE _git_tag_error
|
||||
)
|
||||
|
||||
# execute_process can fail silenty, so check for an error
|
||||
# if there was an error, just use the user agent as a version
|
||||
if(_git_tag_error)
|
||||
message(WARNING "cpp-httplib failed to find the latest git tag, falling back to using user agent as the version.")
|
||||
# Get the user agent and use it as a version
|
||||
# This gets the string with the user agent from the header.
|
||||
# This is so the maintainer doesn't actually need to update this manually.
|
||||
file(STRINGS httplib.h _raw_version_string REGEX "User\-Agent.*cpp\-httplib/([0-9]+\.?)+")
|
||||
endif()
|
||||
# Needed since git tags have "v" prefixing them.
|
||||
# Also used if the fallback to user agent string is being used.
|
||||
string(REGEX MATCH "([0-9]+\\.?)+" _httplib_version "${_raw_version_string}")
|
||||
|
||||
project(httplib VERSION ${_httplib_version} LANGUAGES CXX)
|
||||
|
||||
# Change as needed to set an OpenSSL minimum version.
|
||||
# This is used in the installed Cmake config file.
|
||||
@@ -205,6 +230,23 @@ configure_package_config_file("${PROJECT_NAME}Config.cmake.in"
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||
)
|
||||
|
||||
if(HTTPLIB_COMPILE)
|
||||
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
|
||||
# Example: if you find_package(httplib 0.5.4)
|
||||
# then anything >= 0.5 and <= 1.0 is accepted
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
else()
|
||||
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
|
||||
# Example: if you find_package(httplib 0.5.4)
|
||||
# then anything >= 0.5 and <= 1.0 is accepted
|
||||
COMPATIBILITY SameMajorVersion
|
||||
# Tells Cmake that it's a header-only lib
|
||||
# Mildly useful for end-users :)
|
||||
ARCH_INDEPENDENT
|
||||
)
|
||||
endif()
|
||||
|
||||
# Creates the export httplibTargets.cmake
|
||||
# This is strictly what holds compilation requirements
|
||||
# and linkage information (doesn't find deps though).
|
||||
@@ -218,6 +260,7 @@ install(FILES "${_httplib_build_includedir}/httplib.h" DESTINATION ${CMAKE_INSTA
|
||||
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||
DESTINATION ${_TARGET_INSTALL_CMAKEDIR}
|
||||
)
|
||||
|
||||
|
||||
+34
-1
@@ -6,6 +6,7 @@
|
||||
set(HTTPLIB_IS_USING_OPENSSL @HTTPLIB_IS_USING_OPENSSL@)
|
||||
set(HTTPLIB_IS_USING_ZLIB @HTTPLIB_IS_USING_ZLIB@)
|
||||
set(HTTPLIB_IS_COMPILED @HTTPLIB_COMPILE@)
|
||||
set(HTTPLIB_VERSION @PROJECT_VERSION@)
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
@@ -25,9 +26,41 @@ if(@HTTPLIB_IS_USING_ZLIB@)
|
||||
find_dependency(ZLIB REQUIRED)
|
||||
endif()
|
||||
|
||||
# Lets the end-user find the header path if needed
|
||||
# Mildly useful for end-users
|
||||
# Not really recommended to be used though
|
||||
set_and_check(HTTPLIB_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@")
|
||||
# Lets the end-user find the header path with the header appended
|
||||
# This is helpful if you're using Cmake's pre-compiled header feature
|
||||
set_and_check(HTTPLIB_HEADER_PATH "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/httplib.h")
|
||||
|
||||
# Brings in the target library
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/httplibTargets.cmake")
|
||||
|
||||
# Ouputs a "found httplib /usr/include/httplib.h" message when using find_package(httplib)
|
||||
include(FindPackageMessage)
|
||||
if(TARGET httplib::httplib)
|
||||
set(HTTPLIB_FOUND TRUE)
|
||||
|
||||
# Since the compiled version has a lib, show that in the message
|
||||
if(@HTTPLIB_COMPILE@)
|
||||
# The list of configurations is most likely just 1 unless they installed a debug & release
|
||||
get_target_property(_httplib_configs httplib::httplib "IMPORTED_CONFIGURATIONS")
|
||||
# Need to loop since the "IMPORTED_LOCATION" property isn't want we want.
|
||||
# Instead, we need to find the IMPORTED_LOCATION_RELEASE or IMPORTED_LOCATION_DEBUG which has the lib path.
|
||||
foreach(_httplib_conf "${_httplib_configs}")
|
||||
# Grab the path to the lib and sets it to HTTPLIB_LIBRARY
|
||||
get_target_property(HTTPLIB_LIBRARY httplib::httplib "IMPORTED_LOCATION_${_httplib_conf}")
|
||||
# Check if we found it
|
||||
if(HTTPLIB_LIBRARY)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
unset(_httplib_configs)
|
||||
unset(_httplib_conf)
|
||||
|
||||
find_package_message(httplib "Found httplib: ${HTTPLIB_LIBRARY} (found version \"${HTTPLIB_VERSION}\")" "[${HTTPLIB_LIBRARY}][${HTTPLIB_HEADER_PATH}]")
|
||||
else()
|
||||
find_package_message(httplib "Found httplib: ${HTTPLIB_HEADER_PATH} (found version \"${HTTPLIB_VERSION}\")" "[${HTTPLIB_HEADER_PATH}]")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
+25
-10
@@ -1766,14 +1766,24 @@ TEST_F(ServerTest, GetStreamedEndless) {
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, ClientStop) {
|
||||
thread t = thread([&]() {
|
||||
auto res = cli_.Get("/streamed-cancel",
|
||||
[&](const char *, uint64_t) { return true; });
|
||||
ASSERT_TRUE(res == nullptr);
|
||||
});
|
||||
std::vector<std::thread> threads;
|
||||
for (auto i = 0; i < 3; i++) {
|
||||
threads.emplace_back(thread([&]() {
|
||||
auto res = cli_.Get("/streamed-cancel",
|
||||
[&](const char *, uint64_t) { return true; });
|
||||
ASSERT_TRUE(res == nullptr);
|
||||
}));
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
cli_.stop();
|
||||
t.join();
|
||||
|
||||
while (cli_.is_socket_open()) {
|
||||
cli_.stop();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
for (auto &t : threads) {
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, GetWithRange1) {
|
||||
@@ -2294,12 +2304,13 @@ TEST_F(ServerTest, MultipartFormDataGzip) {
|
||||
// Sends a raw request to a server listening at HOST:PORT.
|
||||
static bool send_request(time_t read_timeout_sec, const std::string &req,
|
||||
std::string *resp = nullptr) {
|
||||
auto client_sock = detail::create_client_socket(HOST, PORT, /*timeout_sec=*/5, 0,
|
||||
std::string());
|
||||
auto client_sock =
|
||||
detail::create_client_socket(HOST, PORT, nullptr,
|
||||
/*timeout_sec=*/5, 0, std::string());
|
||||
|
||||
if (client_sock == INVALID_SOCKET) { return false; }
|
||||
|
||||
return detail::process_and_close_socket(
|
||||
auto ret = detail::process_socket(
|
||||
true, client_sock, 1, read_timeout_sec, 0, 0, 0,
|
||||
[&](Stream &strm, bool /*last_connection*/, bool &
|
||||
/*connection_close*/) -> bool {
|
||||
@@ -2316,6 +2327,10 @@ static bool send_request(time_t read_timeout_sec, const std::string &req,
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
detail::close_socket(client_sock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
TEST(ServerRequestParsingTest, TrimWhitespaceFromHeaderValues) {
|
||||
|
||||
Reference in New Issue
Block a user