Compare commits

..

51 Commits

Author SHA1 Message Date
yhirose cbca63f091 Release v0.14.3 2023-12-21 19:55:25 -05:00
yhirose b4748a226c Fix #1738 2023-12-21 13:33:52 -05:00
Ilya Andreev 5b943d9bb8 Use StatusCode in tests and examples (#1743)
* Use StatusCode in tests and examples

* Use StatusCode in README
2023-12-20 17:28:57 -05:00
Ilya Andreev c86f69a105 Use StatusCode in httplib code (#1742) 2023-12-19 22:17:24 -05:00
Ilya Andreev d39fda0657 Add StatusCode enum (#1739)
* Add StatusCode enum

* Remove changes on RFC 9110

* Add number suffixes to StatusCode constants

* Remove docs for StatusCode constants
2023-12-19 17:57:30 -05:00
Ilya Andreev 37f8dc4382 Change some of status messages based on RFC 9110 (#1740) 2023-12-19 09:22:58 -05:00
yhirose 3a8adda381 Fix #1737 2023-12-17 22:04:36 -05:00
yhirose 8aa38aecaf Fix #1665 2023-12-17 22:03:02 -05:00
yhirose f1dec77f46 Code format 2023-12-17 22:00:33 -05:00
yhirose cddaedaff8 Fix #1736 2023-12-15 19:29:54 -05:00
Renato Foot Guimarães Costallat cefb5a8822 Update README.md (#1731)
Fix "With Progress Callback" code example
2023-12-07 23:21:59 -05:00
davidalo e426a38c3e Fix: Query parameter including query delimiter ('?') not being parsed properly (#1713)
* Fix: Query parameter including query delimiter ('?') not being parsed properly

* Add details::split function with and without m argument to allow split parameters with/without counter

* Revert changes in SplitTest.ParseQueryString
2023-12-07 14:28:41 -05:00
yhirose f14accb7b6 Release v0.14.2 2023-12-04 22:31:12 -05:00
yhirose c5c704cb3b Fix #1724 2023-12-04 21:34:55 -05:00
Jean-Francois Simoneau 115a786581 Fix readability warnings (#1722)
* Fix readability warnings

Did not fix readbility-qualified-auto, will do a separate pull request

* Revert changes where meaning is lost

* Revert some style changes
2023-11-24 09:55:04 -05:00
Jean-Francois Simoneau 5ef4cfd263 Fix bugprone warnings (#1721) 2023-11-20 22:14:00 -05:00
Jean-Francois Simoneau 03fecb2f78 Fix modernize warnings (#1720) 2023-11-20 22:10:04 -05:00
Jean-Francois Simoneau 7fc8682a0a Fix performance-noexcept-move-constructor (#1715) 2023-11-20 13:13:59 -05:00
Jiwoo Park f1431311a4 Minor fixes on test cases (#1709)
* Fix data race

* Replace sleep_for() to wait_until_ready()
2023-11-11 21:28:50 -05:00
Jiwoo Park 1d14e051a5 Remove cryptui on Windows (#1710) 2023-11-11 21:26:57 -05:00
Jiwoo Park 97ae6733ed Run fuzz test in CTest (#1707) 2023-11-09 19:35:15 -05:00
Jiwoo Park 1d6b22b5f0 Fix C6001 (#1701) 2023-10-30 07:13:40 -04:00
yhirose 1a49076b5b Removed unnecessary exception 2023-10-29 19:36:40 -04:00
Jiwoo Park d0e4cb3f07 Include missing stdint.h on fuzz test (#1700)
* Include missing stdint.h

* Remove std:: from uint8_t
2023-10-29 19:26:06 -04:00
yhirose e2813d9d4d Code cleanup. (Removed unnecessary .c_str() calls) 2023-10-23 16:43:12 -04:00
Andrea Pappacoda 20a7f088ce build(meson): copy 1MB.txt test file (#1695)
Since tests are run in the build directory, the 1MB.txt file has to be
copied there.
2023-10-20 17:58:06 -04:00
yhirose f63ba7d013 Fix #1685 2023-10-03 09:59:27 -04:00
yhirose 0a629d7391 Release v0.14.1 2023-09-30 22:26:23 -04:00
PabloMK7 a609330e4c Add optional user defined header writer (#1683)
* Add optional user defined header writer

* Fix errors and add test
2023-09-30 22:13:14 -04:00
Jiwoo Park c029597a5a Update the remote address of www.httpwatch.com (#1664) 2023-09-13 10:33:33 -04:00
yhirose 30b7732565 Release v0.14.0 2023-08-22 20:19:07 -04:00
yhirose 6650632e7f Fix #1638 2023-08-22 19:36:10 -04:00
Sven Panne afe627e7af Avoid a -Warray-bounds false positive in GCC 13. (#1639)
The exact circumstances when this false positive is triggered are quite
tricky to reproduce, but it happened reproducibly with g++ 13.1 and 13.2 in
a close-source SW I'm working on.  The fix even improves performance by a
very tiny bit: There is no need to copy the std::smatch, having a const
reference is enough.

Just as a side note: -Warray-bounds seems to cause trouble in other
projects, too, so e.g. the Linux kernel has disabled since June 2022.
2023-08-14 10:26:54 -04:00
Duncan Ogilvie 67f6ff7fa9 Fix CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR (#1634) 2023-08-03 17:01:40 -04:00
yhirose c7ed1796a7 Release v0.13.3 2023-07-31 21:28:33 -04:00
yhirose 44c62d838e Use memory mapped file for static file server (#1632)
* Use memory mapped file for static file server

* Fix build error
2023-07-31 07:43:50 -04:00
yhirose 6bb580cda8 Fix #1559 2023-07-31 00:27:26 -04:00
yhirose 00a8cb8e5d Code cleanup 2023-07-31 00:22:22 -04:00
yhirose 2e34a39673 Added StaticFileRanges test 2023-07-31 00:22:22 -04:00
yhirose 01b90829bc Removed unnecessary CRLF at the end of multipart ranges data 2023-07-31 00:22:22 -04:00
yhirose e699bd0730 Release v0.13.2 2023-07-29 12:26:19 -04:00
Akın ELDEN 961a9379d5 Fix #1590 (#1630)
* ClientImpl: Connection=close header control moved from process_request to send_

* Connection=close header control moved from send_ to handle_request

* SSLClient::connect_with_proxy error handling improved

* to_string definition added for Error::ProxyConnection

* Comment improvement

---------

Co-authored-by: akinelden <akin.elden@gmail.com>
2023-07-29 12:09:25 -04:00
yhirose ec87b04aff Fix #1619 2023-07-29 00:53:57 -04:00
yhirose aabf752a51 Fix #1519 2023-07-28 23:37:45 -04:00
yhirose afb0674ccb Fix #1624 2023-07-21 20:36:01 -04:00
bdenhollander ee625232a4 Fix successful decompress reported as Error::Read (#1612)
* Fix successful decompress reported as Error::Read

Streams less than 4096 bytes are sometimes reported as failed reads because stream_.avail_in is not reduced to 0. The next iteration of the loop finds `prev_avail_in == strm_.avail_in` and return false. `ret = inflate(...)` returns Z_STREAM_END on the first iteration of the loop indicating that inflate is finished. This fix prevents the second iteration of the loop from failing.

* Fix successful decompress reported as Error::Read

- Add unit tests for raw deflate that illustrates the decompression failure when there are extra trailing bytes
2023-07-11 18:35:27 -04:00
Andrea Pappacoda 52d8dd41f1 build(meson): use C++14 with GTest >= 1.13.0 (#1618)
GoogleTest, starting with vesion 1.13.0, requires C++14 to build. This
patch enables C++14 if GoogleTest 1.13.0 or newer is detected when
compiling the tests with Meson, making it possible to use new GTest
versions.

You can find GoogleTest's release notes at
<https://github.com/google/googletest/releases/tag/v1.13.0>.
2023-07-11 18:32:41 -04:00
Alexandre Bouvier be07d2d7a9 cmake: fix comment (#1616) 2023-07-08 13:24:36 -04:00
yhirose 0f1b62c2b3 Release v0.13.1 2023-07-08 07:41:24 -04:00
yhirose c30906a541 Code cleanup 2023-07-07 19:43:37 -04:00
bgs99 3533503323 Fix explicit constructor warning (#1614) 2023-07-07 13:17:19 -04:00
13 changed files with 9546 additions and 716 deletions
+2 -3
View File
@@ -219,7 +219,6 @@ target_link_libraries(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
# Needed for Windows libs on Mingw, as the pragma comment(lib, "xyz") aren't triggered.
$<$<PLATFORM_ID:Windows>:ws2_32>
$<$<PLATFORM_ID:Windows>:crypt32>
$<$<PLATFORM_ID:Windows>:cryptui>
# Needed for API from MacOS Security framework
"$<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>,$<BOOL:${HTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN}>>:-framework CoreFoundation -framework Security>"
# Can't put multiple targets in a single generator expression or it bugs out.
@@ -256,13 +255,13 @@ configure_package_config_file("${PROJECT_NAME}Config.cmake.in"
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
# then anything >= 0.5.4 and < 0.6 is accepted
COMPATIBILITY SameMinorVersion
)
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
# then anything >= 0.5.4 and < 0.6 is accepted
COMPATIBILITY SameMinorVersion
# Tells Cmake that it's a header-only lib
# Mildly useful for end-users :)
+8 -6
View File
@@ -235,7 +235,7 @@ svr.set_exception_handler([](const auto& req, auto& res, std::exception_ptr ep)
snprintf(buf, sizeof(buf), fmt, "Unknown Exception");
}
res.set_content(buf, "text/html");
res.status = 500;
res.status = StatusCode::InternalServerError_500;
});
```
@@ -385,14 +385,14 @@ By default, the server sends a `100 Continue` response for an `Expect: 100-conti
```cpp
// Send a '417 Expectation Failed' response.
svr.set_expect_100_continue_handler([](const Request &req, Response &res) {
return 417;
return StatusCode::ExpectationFailed_417;
});
```
```cpp
// Send a final status without reading the message body.
svr.set_expect_100_continue_handler([](const Request &req, Response &res) {
return res.status = 401;
return res.status = StatusCode::Unauthorized_401;
});
```
@@ -417,6 +417,8 @@ svr.set_idle_interval(0, 100000); // 100 milliseconds
svr.set_payload_max_length(1024 * 1024 * 512); // 512MB
```
NOTE: When the request body content type is 'www-form-urlencoded', the actual payload length shouldn't exceed `CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH`.
### Server-Sent Events
Please see [Server example](https://github.com/yhirose/cpp-httplib/blob/master/example/ssesvr.cc) and [Client example](https://github.com/yhirose/cpp-httplib/blob/master/example/ssecli.cc).
@@ -471,7 +473,7 @@ int main(void)
httplib::Client cli("localhost", 1234);
if (auto res = cli.Get("/hi")) {
if (res->status == 200) {
if (res->status == StatusCode::OK_200) {
std::cout << res->body << std::endl;
}
} else {
@@ -621,7 +623,7 @@ std::string body;
auto res = cli.Get(
"/stream", Headers(),
[&](const Response &response) {
EXPECT_EQ(200, response.status);
EXPECT_EQ(StatusCode::OK_200, response.status);
return true; // return 'false' if you want to cancel the request.
},
[&](const char *data, size_t data_length) {
@@ -662,7 +664,7 @@ auto res = cli.Post(
### With Progress Callback
```cpp
httplib::Client client(url, port);
httplib::Client cli(url, port);
// prints: 0 / 000 bytes => 50% complete
auto res = cli.Get("/", [](uint64_t len, uint64_t total) {
+1 -1
View File
@@ -26,7 +26,7 @@ int main(void) {
for (int i = 0; i < 3; i++) {
StopWatch sw(to_string(i).c_str());
auto res = cli.Post("/post", body, "application/octet-stream");
assert(res->status == 200);
assert(res->status == httplib::StatusCode::OK_200);
}
return 0;
+640 -320
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -102,3 +102,5 @@ if(HTTPLIB_IS_USING_OPENSSL)
COMMAND_ERROR_IS_FATAL ANY
)
endif()
add_subdirectory(fuzzing)
+10
View File
@@ -0,0 +1,10 @@
file(GLOB HTTPLIB_CORPUS corpus/*)
add_executable(httplib-test-fuzz
server_fuzzer.cc
standalone_fuzz_target_runner.cpp
)
target_link_libraries(httplib-test-fuzz PRIVATE httplib)
add_test(
NAME httplib-test-fuzz
COMMAND httplib-test-fuzz ${HTTPLIB_CORPUS}
)
+2 -1
View File
@@ -1,5 +1,6 @@
#include <cstdint>
#include <httplib.h>
#include <memory>
class FuzzedStream : public httplib::Stream {
public:
@@ -5,9 +5,9 @@
// on the test corpus or on a single file,
// e.g. the one that comes from a bug report.
#include <cassert>
#include <iostream>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <vector>
// Forward declare the "fuzz target" interface.
@@ -21,7 +21,7 @@ int main(int argc, char **argv) {
std::ifstream in(argv[i]);
in.seekg(0, in.end);
size_t length = static_cast<size_t>(in.tellg());
in.seekg (0, in.beg);
in.seekg(0, in.beg);
std::cout << "Reading " << length << " bytes from " << argv[i] << std::endl;
// Allocate exactly length bytes so that we reliably catch buffer overflows.
std::vector<char> bytes(length);
+8 -1
View File
@@ -86,6 +86,12 @@ subdir(join_paths('www', 'dir'))
subdir(join_paths('www2', 'dir'))
subdir(join_paths('www3', 'dir'))
# GoogleTest 1.13.0 requires C++14
test_options = []
if gtest_dep.version().version_compare('>=1.13.0')
test_options += 'cpp_std=c++14'
endif
test(
'main',
executable(
@@ -94,7 +100,8 @@ test(
dependencies: [
cpp_httplib_dep,
gtest_dep
]
],
override_options: test_options
),
depends: [
key_pem,
+662 -366
View File
File diff suppressed because it is too large Load Diff
+15 -15
View File
@@ -10,7 +10,7 @@ void ProxyTest(T& cli, bool basic) {
cli.set_proxy("localhost", basic ? 3128 : 3129);
auto res = cli.Get("/httpbin/get");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(407, res->status);
EXPECT_EQ(StatusCode::ProxyAuthenticationRequired_407, res->status);
}
TEST(ProxyTest, NoSSLBasic) {
@@ -51,7 +51,7 @@ void RedirectProxyText(T& cli, const char *path, bool basic) {
auto res = cli.Get(path);
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(200, res->status);
EXPECT_EQ(StatusCode::OK_200, res->status);
}
TEST(RedirectTest, HTTPBinNoSSLBasic) {
@@ -108,7 +108,7 @@ void BaseAuthTestFromHTTPWatch(T& cli) {
{
auto res = cli.Get("/basic-auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
}
{
@@ -117,7 +117,7 @@ void BaseAuthTestFromHTTPWatch(T& cli) {
{make_basic_authentication_header("hello", "world")});
ASSERT_TRUE(res != nullptr);
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res->body);
EXPECT_EQ(200, res->status);
EXPECT_EQ(StatusCode::OK_200, res->status);
}
{
@@ -125,21 +125,21 @@ void BaseAuthTestFromHTTPWatch(T& cli) {
auto res = cli.Get("/basic-auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res->body);
EXPECT_EQ(200, res->status);
EXPECT_EQ(StatusCode::OK_200, res->status);
}
{
cli.set_basic_auth("hello", "bad");
auto res = cli.Get("/basic-auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
}
{
cli.set_basic_auth("bad", "world");
auto res = cli.Get("/basic-auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
}
}
@@ -166,7 +166,7 @@ void DigestAuthTestFromHTTPWatch(T& cli) {
{
auto res = cli.Get("/digest-auth/auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
}
{
@@ -182,14 +182,14 @@ void DigestAuthTestFromHTTPWatch(T& cli) {
auto res = cli.Get(path.c_str());
ASSERT_TRUE(res != nullptr);
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res->body);
EXPECT_EQ(200, res->status);
EXPECT_EQ(StatusCode::OK_200, res->status);
}
cli.set_digest_auth("hello", "bad");
for (auto path : paths) {
auto res = cli.Get(path.c_str());
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
}
// NOTE: Until httpbin.org fixes issue #46, the following test is commented
@@ -198,7 +198,7 @@ void DigestAuthTestFromHTTPWatch(T& cli) {
// for (auto path : paths) {
// auto res = cli.Get(path.c_str());
// ASSERT_TRUE(res != nullptr);
// EXPECT_EQ(401, res->status);
// EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
// }
}
}
@@ -234,11 +234,11 @@ void KeepAliveTest(T& cli, bool basic) {
{
auto res = cli.Get("/httpbin/get");
EXPECT_EQ(200, res->status);
EXPECT_EQ(StatusCode::OK_200, res->status);
}
{
auto res = cli.Get("/httpbin/redirect/2");
EXPECT_EQ(200, res->status);
EXPECT_EQ(StatusCode::OK_200, res->status);
}
{
@@ -252,7 +252,7 @@ void KeepAliveTest(T& cli, bool basic) {
for (auto path: paths) {
auto res = cli.Get(path.c_str());
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res->body);
EXPECT_EQ(200, res->status);
EXPECT_EQ(StatusCode::OK_200, res->status);
}
}
@@ -260,7 +260,7 @@ void KeepAliveTest(T& cli, bool basic) {
int count = 10;
while (count--) {
auto res = cli.Get("/httpbin/get");
EXPECT_EQ(200, res->status);
EXPECT_EQ(StatusCode::OK_200, res->status);
}
}
}
+8192
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -5,3 +5,4 @@
configure_file(input: 'index.html', output: 'index.html', copy: true)
configure_file(input: 'test.abcde', output: 'test.abcde', copy: true)
configure_file(input: 'test.html', output: 'test.html', copy: true)
configure_file(input: '1MB.txt', output: '1MB.txt', copy: true)