mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0654e5dab4 | ||
|
|
62e036f253 | ||
|
|
f0adfb2e0c | ||
|
|
139c816c16 | ||
|
|
9505a76491 | ||
|
|
29fd136afd | ||
|
|
f5598237b2 | ||
|
|
01058659ab |
No files matched your search
+160
@@ -0,0 +1,160 @@
|
|||||||
|
#[[
|
||||||
|
Build options:
|
||||||
|
* HTTPLIB_USE_OPENSSL_IF_AVAILABLE (default on)
|
||||||
|
* HTTPLIB_USE_ZLIB_IF_AVAILABLE (default on)
|
||||||
|
* HTTPLIB_REQUIRE_OPENSSL (default off)
|
||||||
|
* HTTPLIB_REQUIRE_ZLIB (default off)
|
||||||
|
|
||||||
|
After installation with Cmake, a find_package(httplib) is available.
|
||||||
|
This creates a httplib::httplib target (if found).
|
||||||
|
It can be linked like so:
|
||||||
|
|
||||||
|
target_link_libraries(your_exe httplib::httplib)
|
||||||
|
|
||||||
|
The following will build & install for later use.
|
||||||
|
|
||||||
|
Linux/macOS:
|
||||||
|
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||||
|
sudo cmake --build . --target install
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
runas /user:Administrator "cmake --build . --config Release --target install"
|
||||||
|
|
||||||
|
These three variables are available after you run find_package(httplib)
|
||||||
|
* HTTPLIB_HEADER_PATH - this is the full path to the installed header.
|
||||||
|
* HTTPLIB_IS_USING_OPENSSL - a bool for if OpenSSL support is enabled.
|
||||||
|
* HTTPLIB_IS_USING_ZLIB - a bool for if ZLIB support is enabled.
|
||||||
|
|
||||||
|
Want to use precompiled headers (Cmake feature since v3.16)?
|
||||||
|
It's as simple as doing the following (before linking):
|
||||||
|
|
||||||
|
target_precompile_headers(httplib::httplib INTERFACE "${HTTPLIB_HEADER_PATH}")
|
||||||
|
]]
|
||||||
|
cmake_minimum_required(VERSION 3.7.0 FATAL_ERROR)
|
||||||
|
project(httplib LANGUAGES CXX)
|
||||||
|
|
||||||
|
# Change as needed to set an OpenSSL minimum version.
|
||||||
|
# This is used in the installed Cmake config file.
|
||||||
|
set(_HTTPLIB_OPENSSL_MIN_VER "1.1.1")
|
||||||
|
|
||||||
|
# Allow for a build to require OpenSSL to pass, instead of just being optional
|
||||||
|
option(HTTPLIB_REQUIRE_OPENSSL "Requires OpenSSL to be found & linked, or fails build." OFF)
|
||||||
|
option(HTTPLIB_REQUIRE_ZLIB "Requires ZLIB to be found & linked, or fails build." OFF)
|
||||||
|
# Allow for a build to casually enable OpenSSL/ZLIB support, but silenty continue if not found.
|
||||||
|
# Make these options so their automatic use can be specifically disabled (as needed)
|
||||||
|
option(HTTPLIB_USE_OPENSSL_IF_AVAILABLE "Uses OpenSSL (if available) to enable HTTPS support." ON)
|
||||||
|
option(HTTPLIB_USE_ZLIB_IF_AVAILABLE "Uses ZLIB (if available) to enable compression support." ON)
|
||||||
|
|
||||||
|
# TODO: implement the option of option to correctly split, building, and export with the split.py script.
|
||||||
|
# option(HTTPLIB_SPLIT "Uses a Python script to split the header into a header & source file." OFF)
|
||||||
|
|
||||||
|
# Threads needed for <thread> on some systems, and for <pthread.h> on Linux
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
if(HTTPLIB_REQUIRE_OPENSSL)
|
||||||
|
find_package(OpenSSL ${_HTTPLIB_OPENSSL_MIN_VER} REQUIRED)
|
||||||
|
elseif(HTTPLIB_USE_OPENSSL_IF_AVAILABLE)
|
||||||
|
# Look quietly since it's optional are optional
|
||||||
|
find_package(OpenSSL ${_HTTPLIB_OPENSSL_MIN_VER} QUIET)
|
||||||
|
endif()
|
||||||
|
if(HTTPLIB_REQUIRE_ZLIB)
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
elseif(HTTPLIB_USE_ZLIB_IF_AVAILABLE)
|
||||||
|
find_package(ZLIB QUIET)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Used for default, common dirs that the end-user can change (if needed)
|
||||||
|
# like CMAKE_INSTALL_INCLUDEDIR or CMAKE_INSTALL_DATADIR
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME} INTERFACE)
|
||||||
|
# Lets you address the target with httplib::httplib
|
||||||
|
# Only useful if building in-tree, versus using it from an installation.
|
||||||
|
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
||||||
|
|
||||||
|
# Might be missing some, but this list is somewhat comprehensive
|
||||||
|
target_compile_features(${PROJECT_NAME} INTERFACE
|
||||||
|
cxx_std_11
|
||||||
|
cxx_nullptr
|
||||||
|
cxx_noexcept
|
||||||
|
cxx_lambdas
|
||||||
|
cxx_override
|
||||||
|
cxx_defaulted_functions
|
||||||
|
cxx_attribute_deprecated
|
||||||
|
cxx_auto_type
|
||||||
|
cxx_decltype
|
||||||
|
cxx_deleted_functions
|
||||||
|
cxx_range_for
|
||||||
|
cxx_sizeof_member
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME} INTERFACE
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||||
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||||
|
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME} INTERFACE
|
||||||
|
# Always require threads
|
||||||
|
Threads::Threads
|
||||||
|
# Only link zlib & openssl if they're found
|
||||||
|
$<$<BOOL:${ZLIB_FOUND}>:ZLIB::ZLIB>
|
||||||
|
$<$<BOOL:${OPENSSL_FOUND}>:OpenSSL::SSL OpenSSL::Crypto>
|
||||||
|
)
|
||||||
|
|
||||||
|
# Auto-define the optional support if those packages were found
|
||||||
|
target_compile_definitions(${PROJECT_NAME} INTERFACE
|
||||||
|
$<$<BOOL:${ZLIB_FOUND}>:CPPHTTPLIB_ZLIB_SUPPORT>
|
||||||
|
$<$<BOOL:${OPENSSL_FOUND}>:CPPHTTPLIB_OPENSSL_SUPPORT>
|
||||||
|
)
|
||||||
|
|
||||||
|
# Cmake's find_package search path is different based on the system
|
||||||
|
# See https://cmake.org/cmake/help/latest/command/find_package.html for the list
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
|
set(_TARGET_INSTALL_CMAKEDIR "${CMAKE_INSTALL_PREFIX}/cmake/${PROJECT_NAME}")
|
||||||
|
else()
|
||||||
|
# On Non-Windows, it should be /usr/lib/cmake/<name>/<name>Config.cmake
|
||||||
|
# NOTE: This may or may not work for macOS...
|
||||||
|
set(_TARGET_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
# Configures the meta-file httplibConfig.cmake.in to replace variables with paths/values/etc.
|
||||||
|
configure_package_config_file("${PROJECT_NAME}Config.cmake.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||||
|
INSTALL_DESTINATION "${_TARGET_INSTALL_CMAKEDIR}"
|
||||||
|
# Passes the includedir install path
|
||||||
|
PATH_VARS CMAKE_INSTALL_FULL_INCLUDEDIR
|
||||||
|
# There aren't any components, so don't use the macro
|
||||||
|
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||||
|
)
|
||||||
|
|
||||||
|
# Creates the export httplibTargets.cmake
|
||||||
|
# This is strictly what holds compilation requirements
|
||||||
|
# and linkage information (doesn't find deps though).
|
||||||
|
install(TARGETS ${PROJECT_NAME}
|
||||||
|
EXPORT httplibTargets
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES httplib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||||
|
DESTINATION ${_TARGET_INSTALL_CMAKEDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
# NOTE: This path changes depending on if it's on Windows or Linux
|
||||||
|
install(EXPORT httplibTargets
|
||||||
|
# Puts the targets into the httplib namespace
|
||||||
|
# So this makes httplib::httplib linkable after doing find_package(httplib)
|
||||||
|
NAMESPACE ${PROJECT_NAME}::
|
||||||
|
DESTINATION ${_TARGET_INSTALL_CMAKEDIR}
|
||||||
|
)
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Generates a macro to auto-configure everything
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
|
||||||
|
# We add find_dependency calls here to not make the end-user have to call them.
|
||||||
|
find_dependency(Threads REQUIRED)
|
||||||
|
if(@HTTPLIB_REQUIRE_OPENSSL@)
|
||||||
|
find_dependency(OpenSSL @_HTTPLIB_OPENSSL_MIN_VER@ REQUIRED)
|
||||||
|
# Lets you check if these options were correctly enabled for your install
|
||||||
|
set(HTTPLIB_IS_USING_OPENSSL TRUE)
|
||||||
|
elseif(@HTTPLIB_USE_OPENSSL_IF_AVAILABLE@)
|
||||||
|
# Look quietly since it's optional
|
||||||
|
find_dependency(OpenSSL @_HTTPLIB_OPENSSL_MIN_VER@ QUIET)
|
||||||
|
# Lets you check if these options were correctly enabled for your install
|
||||||
|
set(HTTPLIB_IS_USING_OPENSSL @OPENSSL_FOUND@)
|
||||||
|
else()
|
||||||
|
set(HTTPLIB_IS_USING_OPENSSL FALSE)
|
||||||
|
endif()
|
||||||
|
if(@HTTPLIB_REQUIRE_ZLIB@)
|
||||||
|
find_dependency(ZLIB REQUIRED)
|
||||||
|
# Lets you check if these options were correctly enabled for your install
|
||||||
|
set(HTTPLIB_IS_USING_ZLIB TRUE)
|
||||||
|
elseif(@HTTPLIB_USE_ZLIB_IF_AVAILABLE@)
|
||||||
|
# Look quietly since it's optional
|
||||||
|
find_dependency(ZLIB QUIET)
|
||||||
|
# Lets you check if these options were correctly enabled for your install
|
||||||
|
set(HTTPLIB_IS_USING_ZLIB @ZLIB_FOUND@)
|
||||||
|
else()
|
||||||
|
set(HTTPLIB_IS_USING_ZLIB FALSE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Lets the end-user find the header path if needed
|
||||||
|
# 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")
|
||||||
+49
-17
@@ -334,7 +334,7 @@ TEST(RangeTest, FromHTTPBin) {
|
|||||||
httplib::Headers headers;
|
httplib::Headers headers;
|
||||||
auto res = cli.Get("/range/32", headers);
|
auto res = cli.Get("/range/32", headers);
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(res->body, "abcdefghijklmnopqrstuvwxyzabcdef");
|
EXPECT_EQ("abcdefghijklmnopqrstuvwxyzabcdef", res->body);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +342,7 @@ TEST(RangeTest, FromHTTPBin) {
|
|||||||
httplib::Headers headers = {httplib::make_range_header({{1, -1}})};
|
httplib::Headers headers = {httplib::make_range_header({{1, -1}})};
|
||||||
auto res = cli.Get("/range/32", headers);
|
auto res = cli.Get("/range/32", headers);
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(res->body, "bcdefghijklmnopqrstuvwxyzabcdef");
|
EXPECT_EQ("bcdefghijklmnopqrstuvwxyzabcdef", res->body);
|
||||||
EXPECT_EQ(206, res->status);
|
EXPECT_EQ(206, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +350,7 @@ TEST(RangeTest, FromHTTPBin) {
|
|||||||
httplib::Headers headers = {httplib::make_range_header({{1, 10}})};
|
httplib::Headers headers = {httplib::make_range_header({{1, 10}})};
|
||||||
auto res = cli.Get("/range/32", headers);
|
auto res = cli.Get("/range/32", headers);
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(res->body, "bcdefghijk");
|
EXPECT_EQ("bcdefghijk", res->body);
|
||||||
EXPECT_EQ(206, res->status);
|
EXPECT_EQ(206, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +358,7 @@ TEST(RangeTest, FromHTTPBin) {
|
|||||||
httplib::Headers headers = {httplib::make_range_header({{0, 31}})};
|
httplib::Headers headers = {httplib::make_range_header({{0, 31}})};
|
||||||
auto res = cli.Get("/range/32", headers);
|
auto res = cli.Get("/range/32", headers);
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(res->body, "abcdefghijklmnopqrstuvwxyzabcdef");
|
EXPECT_EQ("abcdefghijklmnopqrstuvwxyzabcdef", res->body);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +366,7 @@ TEST(RangeTest, FromHTTPBin) {
|
|||||||
httplib::Headers headers = {httplib::make_range_header({{0, -1}})};
|
httplib::Headers headers = {httplib::make_range_header({{0, -1}})};
|
||||||
auto res = cli.Get("/range/32", headers);
|
auto res = cli.Get("/range/32", headers);
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(res->body, "abcdefghijklmnopqrstuvwxyzabcdef");
|
EXPECT_EQ("abcdefghijklmnopqrstuvwxyzabcdef", res->body);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +440,7 @@ TEST(CancelTest, NoCancel) {
|
|||||||
|
|
||||||
auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return true; });
|
auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return true; });
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(res->body, "abcdefghijklmnopqrstuvwxyzabcdef");
|
EXPECT_EQ("abcdefghijklmnopqrstuvwxyzabcdef", res->body);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,8 +501,8 @@ TEST(BaseAuthTest, FromHTTPWatch) {
|
|||||||
cli.Get("/basic-auth/hello/world",
|
cli.Get("/basic-auth/hello/world",
|
||||||
{httplib::make_basic_authentication_header("hello", "world")});
|
{httplib::make_basic_authentication_header("hello", "world")});
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(res->body,
|
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n",
|
||||||
"{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n");
|
res->body);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,8 +510,8 @@ TEST(BaseAuthTest, FromHTTPWatch) {
|
|||||||
cli.set_basic_auth("hello", "world");
|
cli.set_basic_auth("hello", "world");
|
||||||
auto res = cli.Get("/basic-auth/hello/world");
|
auto res = cli.Get("/basic-auth/hello/world");
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(res->body,
|
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n",
|
||||||
"{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n");
|
res->body);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,8 +554,8 @@ TEST(DigestAuthTest, FromHTTPWatch) {
|
|||||||
for (auto path : paths) {
|
for (auto path : paths) {
|
||||||
auto res = cli.Get(path.c_str());
|
auto res = cli.Get(path.c_str());
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(res->body,
|
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n",
|
||||||
"{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n");
|
res->body);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,7 +689,7 @@ TEST(RedirectToDifferentPort, Redirect) {
|
|||||||
auto res = cli.Get("/1");
|
auto res = cli.Get("/1");
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
EXPECT_EQ(res->body, "Hello World!");
|
EXPECT_EQ("Hello World!", res->body);
|
||||||
|
|
||||||
svr8080.stop();
|
svr8080.stop();
|
||||||
svr8081.stop();
|
svr8081.stop();
|
||||||
@@ -718,7 +718,7 @@ TEST(Server, BindDualStack) {
|
|||||||
auto res = cli.Get("/1");
|
auto res = cli.Get("/1");
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
EXPECT_EQ(res->body, "Hello World!");
|
EXPECT_EQ("Hello World!", res->body);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Client cli("::1", PORT);
|
Client cli("::1", PORT);
|
||||||
@@ -726,7 +726,7 @@ TEST(Server, BindDualStack) {
|
|||||||
auto res = cli.Get("/1");
|
auto res = cli.Get("/1");
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(200, res->status);
|
EXPECT_EQ(200, res->status);
|
||||||
EXPECT_EQ(res->body, "Hello World!");
|
EXPECT_EQ("Hello World!", res->body);
|
||||||
}
|
}
|
||||||
svr.stop();
|
svr.stop();
|
||||||
thread.join();
|
thread.join();
|
||||||
@@ -807,6 +807,11 @@ protected:
|
|||||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||||
res.set_content("slow", "text/plain");
|
res.set_content("slow", "text/plain");
|
||||||
})
|
})
|
||||||
|
.Post("/slowpost",
|
||||||
|
[&](const Request & /*req*/, Response &res) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||||
|
res.set_content("slow", "text/plain");
|
||||||
|
})
|
||||||
.Get("/remote_addr",
|
.Get("/remote_addr",
|
||||||
[&](const Request &req, Response &res) {
|
[&](const Request &req, Response &res) {
|
||||||
auto remote_addr = req.headers.find("REMOTE_ADDR")->second;
|
auto remote_addr = req.headers.find("REMOTE_ADDR")->second;
|
||||||
@@ -1885,6 +1890,33 @@ TEST_F(ServerTest, SlowRequest) {
|
|||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ServerTest, SlowPost) {
|
||||||
|
char buffer[64 * 1024];
|
||||||
|
memset(buffer, 0x42, sizeof(buffer));
|
||||||
|
|
||||||
|
auto res = cli_.Post(
|
||||||
|
"/slowpost", 64 * 1024 * 1024,
|
||||||
|
[&](size_t /*offset*/, size_t /*length*/, DataSink &sink) {
|
||||||
|
sink.write(buffer, sizeof(buffer));
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"text/plain");
|
||||||
|
|
||||||
|
ASSERT_TRUE(res != nullptr);
|
||||||
|
EXPECT_EQ(200, res->status);
|
||||||
|
|
||||||
|
cli_.set_write_timeout(0, 0);
|
||||||
|
res = cli_.Post(
|
||||||
|
"/slowpost", 64 * 1024 * 1024,
|
||||||
|
[&](size_t /*offset*/, size_t /*length*/, DataSink &sink) {
|
||||||
|
sink.write(buffer, sizeof(buffer));
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"text/plain");
|
||||||
|
|
||||||
|
ASSERT_FALSE(res != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ServerTest, Put) {
|
TEST_F(ServerTest, Put) {
|
||||||
auto res = cli_.Put("/put", "PUT", "text/plain");
|
auto res = cli_.Put("/put", "PUT", "text/plain");
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
@@ -2253,7 +2285,7 @@ static bool send_request(time_t read_timeout_sec, const std::string &req,
|
|||||||
if (client_sock == INVALID_SOCKET) { return false; }
|
if (client_sock == INVALID_SOCKET) { return false; }
|
||||||
|
|
||||||
return detail::process_and_close_socket(
|
return detail::process_and_close_socket(
|
||||||
true, client_sock, 1, read_timeout_sec, 0,
|
true, client_sock, 1, read_timeout_sec, 0, 0, 0,
|
||||||
[&](Stream &strm, bool /*last_connection*/, bool &
|
[&](Stream &strm, bool /*last_connection*/, bool &
|
||||||
/*connection_close*/) -> bool {
|
/*connection_close*/) -> bool {
|
||||||
if (req.size() !=
|
if (req.size() !=
|
||||||
@@ -2438,7 +2470,7 @@ TEST(ServerStopTest, StopServerWithChunkedTransmission) {
|
|||||||
svr.Get("/events", [](const Request & /*req*/, Response &res) {
|
svr.Get("/events", [](const Request & /*req*/, Response &res) {
|
||||||
res.set_header("Content-Type", "text/event-stream");
|
res.set_header("Content-Type", "text/event-stream");
|
||||||
res.set_header("Cache-Control", "no-cache");
|
res.set_header("Cache-Control", "no-cache");
|
||||||
res.set_chunked_content_provider([](size_t offset, const DataSink &sink) {
|
res.set_chunked_content_provider([](size_t offset, DataSink &sink) {
|
||||||
char buffer[27];
|
char buffer[27];
|
||||||
auto size = static_cast<size_t>(sprintf(buffer, "data:%ld\n\n", offset));
|
auto size = static_cast<size_t>(sprintf(buffer, "data:%ld\n\n", offset));
|
||||||
sink.write(buffer, size);
|
sink.write(buffer, size);
|
||||||
|
|||||||
+10
-8
@@ -185,15 +185,17 @@ void DigestAuthTestFromHTTPWatch(Client& cli) {
|
|||||||
for (auto path : paths) {
|
for (auto path : paths) {
|
||||||
auto res = cli.Get(path.c_str());
|
auto res = cli.Get(path.c_str());
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
EXPECT_EQ(400, res->status);
|
EXPECT_EQ(401, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.set_digest_auth("bad", "world");
|
// NOTE: Until httpbin.org fixes issue #46, the following test is commented
|
||||||
for (auto path : paths) {
|
// out. Plese see https://httpbin.org/digest-auth/auth/hello/world
|
||||||
auto res = cli.Get(path.c_str());
|
// cli.set_digest_auth("bad", "world");
|
||||||
ASSERT_TRUE(res != nullptr);
|
// for (auto path : paths) {
|
||||||
EXPECT_EQ(400, res->status);
|
// auto res = cli.Get(path.c_str());
|
||||||
}
|
// ASSERT_TRUE(res != nullptr);
|
||||||
|
// EXPECT_EQ(401, res->status);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +268,7 @@ void KeepAliveTest(Client& cli, bool basic) {
|
|||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
int count = paths.size();
|
int count = static_cast<int>(paths.size());
|
||||||
while (count--) {
|
while (count--) {
|
||||||
auto &res = responses[i++];
|
auto &res = responses[i++];
|
||||||
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res.body);
|
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res.body);
|
||||||
|
|||||||
Reference in new issue
Block a user