From 05f9f83240a388239c088f067a1e3e6af2a7bf51 Mon Sep 17 00:00:00 2001 From: Pavel P Date: Fri, 17 May 2024 05:56:06 +0500 Subject: [PATCH 1/6] Avoid unreferenced formal parameter warning in get_range_offset_and_length (#1838) Release builds result in the following warning because `content_length` param was used only inside asserts: 1> cpp-httplib\httplib.h(4933,45): warning C4100: 'content_length': unreferenced formal parameter --- httplib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httplib.h b/httplib.h index c7449cd..ba6e666 100644 --- a/httplib.h +++ b/httplib.h @@ -4935,7 +4935,7 @@ get_range_offset_and_length(Range r, size_t content_length) { assert(0 <= r.first && r.first < static_cast(content_length)); assert(r.first <= r.second && r.second < static_cast(content_length)); - + (void)(content_length); return std::make_pair(r.first, static_cast(r.second - r.first) + 1); } From 25b1e0d906e33ae328c5bdf89e586b1508ee4c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Chlup?= <30288319+jajik@users.noreply.github.com> Date: Sun, 26 May 2024 14:24:29 +0200 Subject: [PATCH 2/6] Tweak CI & fix macOS prefix (#1843) * Use brew prefix or given one * Polish CI workflow file --- .github/workflows/test.yaml | 42 +++++++++++++++++++------------------ test/Makefile | 3 +-- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 22fd72e..531fd4d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -3,39 +3,41 @@ name: test on: [push, pull_request] jobs: - build: - runs-on: ${{ matrix.os }} + ubuntu: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v4 + - name: install brotli + run: sudo apt-get update && sudo apt-get install -y libbrotli-dev + - name: build and run tests + run: cd test && make -j4 + - name: run fuzz test target + run: cd test && make fuzz_test - strategy: - matrix: - os: [macOS-latest, ubuntu-latest, windows-latest] + macos: + runs-on: macos-latest + steps: + - name: checkout + uses: actions/checkout@v4 + - name: build and run tests + run: | + cd test && make -j2 + windows: + runs-on: windows-latest steps: - name: prepare git for checkout on windows - if: matrix.os == 'windows-latest' run: | git config --global core.autocrlf false git config --global core.eol lf - name: checkout uses: actions/checkout@v4 - - name: install brotli library on ubuntu - if: matrix.os == 'ubuntu-latest' - run: sudo apt update && sudo apt-get install -y libbrotli-dev - - name: install brotli library on macOS - if: matrix.os == 'macOS-latest' - run: brew install brotli - - name: make - if: matrix.os != 'windows-latest' - run: cd test && make -j2 - - name: check fuzz test target - if: matrix.os == 'ubuntu-latest' - run: cd test && make fuzz_test - name: setup msbuild on windows - if: matrix.os == 'windows-latest' uses: microsoft/setup-msbuild@v2 - name: make-windows - if: matrix.os == 'windows-latest' run: | cd test msbuild.exe test.sln /verbosity:minimal /t:Build "/p:Configuration=Release;Platform=x64" x64\Release\test.exe + diff --git a/test/Makefile b/test/Makefile index c4dc4f1..5468488 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,8 +1,7 @@ CXX = clang++ CXXFLAGS = -g -std=c++11 -I. -Wall -Wextra -Wtype-limits -Wconversion -Wshadow # -fno-exceptions -DCPPHTTPLIB_NO_EXCEPTIONS -fsanitize=address -PREFIX = /usr/local -#PREFIX = $(shell brew --prefix) +PREFIX ?= $(shell brew --prefix) OPENSSL_DIR = $(PREFIX)/opt/openssl@3 OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -L$(OPENSSL_DIR)/lib -lssl -lcrypto From 98cc1ec344da3250e7dc8135853d0a5bef52d788 Mon Sep 17 00:00:00 2001 From: Sean Quinn Date: Sun, 26 May 2024 05:57:07 -0700 Subject: [PATCH 3/6] Allow hex for ip6 literal addr, fix #1800 (#1830) * Allow hex for ip6 literal addr, fix #1800 * Add UT for ipv6 + Universal client implementation * add /n at EOF --- httplib.h | 4 +++- test/test.cc | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/httplib.h b/httplib.h index ba6e666..a7a5613 100644 --- a/httplib.h +++ b/httplib.h @@ -9213,7 +9213,7 @@ inline Client::Client(const std::string &scheme_host_port, const std::string &client_cert_path, const std::string &client_key_path) { const static std::regex re( - R"((?:([a-z]+):\/\/)?(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)"); + R"((?:([a-z]+):\/\/)?(?:\[([a-fA-F\d:]+)\]|([^:/?#]+))(?::(\d+))?)"); std::smatch m; if (std::regex_match(scheme_host_port, m, re)) { @@ -9250,6 +9250,8 @@ inline Client::Client(const std::string &scheme_host_port, client_key_path); } } else { + // NOTE: Update TEST(UniversalClientImplTest, Ipv6LiteralAddress) + // if port param below changes. cli_ = detail::make_unique(scheme_host_port, 80, client_cert_path, client_key_path); } diff --git a/test/test.cc b/test/test.cc index dce82ab..aab9db0 100644 --- a/test/test.cc +++ b/test/test.cc @@ -7373,3 +7373,18 @@ TEST(PathParamsTest, SequenceOfParams) { EXPECT_EQ(request.path_params, expected_params); } + +TEST(UniversalClientImplTest, Ipv6LiteralAddress) { + // If ipv6 regex working, regex match codepath is taken. + // else port will default to 80 in Client impl + int clientImplMagicPort = 80; + int port = 4321; + // above ports must be different to avoid false negative + EXPECT_NE(clientImplMagicPort, port); + + std::string ipV6TestURL = "http://[ff06::c3]"; + + Client cli(ipV6TestURL + ":" + std::to_string(port), CLIENT_CERT_FILE, + CLIENT_PRIVATE_KEY_FILE); + EXPECT_EQ(cli.port(), port); +} From d44031615d7ef548c3d78a820035848cb5990288 Mon Sep 17 00:00:00 2001 From: Rainer Schielke <56628927+RainerSchielke@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:37:40 +0200 Subject: [PATCH 4/6] New function SSLServer::update_certs. Allows to update certificates while server is running (#1827) * New function SSLServer::update_certs. Allows to update certificates while server is running * New function SSLServer::update_certs. Added unit test --------- Co-authored-by: CEU\schielke --- httplib.h | 16 +++++++++++++++ test/test.cc | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/httplib.h b/httplib.h index a7a5613..69a34d6 100644 --- a/httplib.h +++ b/httplib.h @@ -1819,6 +1819,9 @@ public: bool is_valid() const override; SSL_CTX *ssl_context() const; + + void update_certs (X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store = nullptr); private: bool process_and_close_socket(socket_t sock) override; @@ -8753,6 +8756,19 @@ inline bool SSLServer::is_valid() const { return ctx_; } inline SSL_CTX *SSLServer::ssl_context() const { return ctx_; } +inline void SSLServer::update_certs (X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store) { + + std::lock_guard guard(ctx_mutex_); + + SSL_CTX_use_certificate (ctx_, cert); + SSL_CTX_use_PrivateKey (ctx_, private_key); + + if (client_ca_cert_store != nullptr) { + SSL_CTX_set_cert_store (ctx_, client_ca_cert_store); + } +} + inline bool SSLServer::process_and_close_socket(socket_t sock) { auto ssl = detail::ssl_new( sock, ctx_, ctx_mutex_, diff --git a/test/test.cc b/test/test.cc index aab9db0..7fe39ad 100644 --- a/test/test.cc +++ b/test/test.cc @@ -1747,6 +1747,64 @@ TEST(BindServerTest, BindAndListenSeparatelySSLEncryptedKey) { } #endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +X509* readCertificate (const std::string& strFileName) { + std::ifstream inStream (strFileName); + std::string strCertPEM ((std::istreambuf_iterator(inStream)), std::istreambuf_iterator()); + + if (strCertPEM.empty ()) return (nullptr); + + BIO* pbCert = BIO_new (BIO_s_mem ()); + BIO_write (pbCert, strCertPEM.c_str (), (int)strCertPEM.size ()); + X509* pCert = PEM_read_bio_X509 (pbCert, NULL, 0, NULL); + BIO_free (pbCert); + + return (pCert); +} + +EVP_PKEY* readPrivateKey (const std::string& strFileName) { + std::ifstream inStream (strFileName); + std::string strPrivateKeyPEM ((std::istreambuf_iterator(inStream)), std::istreambuf_iterator()); + + if (strPrivateKeyPEM.empty ()) return (nullptr); + + BIO* pbPrivKey = BIO_new (BIO_s_mem ()); + BIO_write (pbPrivKey, strPrivateKeyPEM.c_str (), (int) strPrivateKeyPEM.size ()); + EVP_PKEY* pPrivateKey = PEM_read_bio_PrivateKey (pbPrivKey, NULL, NULL, NULL); + BIO_free (pbPrivKey); + + return (pPrivateKey); +} + +TEST(BindServerTest, UpdateCerts) { + SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE, CLIENT_CA_CERT_FILE); + int port = svr.bind_to_any_port("0.0.0.0"); + ASSERT_TRUE(svr.is_valid()); + ASSERT_TRUE(port > 0); + + X509* cert = readCertificate (SERVER_CERT_FILE); + X509* ca_cert = readCertificate (CLIENT_CA_CERT_FILE); + EVP_PKEY* key = readPrivateKey (SERVER_PRIVATE_KEY_FILE); + + ASSERT_TRUE(cert != nullptr); + ASSERT_TRUE(ca_cert != nullptr); + ASSERT_TRUE(key != nullptr); + + X509_STORE* cert_store = X509_STORE_new (); + + X509_STORE_add_cert (cert_store, ca_cert); + + svr.update_certs (cert, key, cert_store); + + ASSERT_TRUE(svr.is_valid()); + svr.stop(); + + X509_free (cert); + X509_free (ca_cert); + EVP_PKEY_free (key); +} +#endif + TEST(ErrorHandlerTest, ContentLength) { Server svr; From 67fd7e3d0950eaee85ddbcfe51a236a80b38fb04 Mon Sep 17 00:00:00 2001 From: Jiwoo Park Date: Tue, 11 Jun 2024 02:18:19 +0900 Subject: [PATCH 5/6] Change library name to cpp-httplib (#1854) --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96d755a..e27481b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,6 +194,7 @@ if(HTTPLIB_COMPILE) PROPERTIES VERSION ${${PROJECT_NAME}_VERSION} SOVERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}" + OUTPUT_NAME cpp-httplib ) else() # This is for header-only. From 8438df4a953da398fc794387618a3c9676b2ba7e Mon Sep 17 00:00:00 2001 From: yhirose Date: Tue, 11 Jun 2024 18:20:22 -0400 Subject: [PATCH 6/6] Release v0.16.0 --- httplib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httplib.h b/httplib.h index 69a34d6..062f66b 100644 --- a/httplib.h +++ b/httplib.h @@ -8,7 +8,7 @@ #ifndef CPPHTTPLIB_HTTPLIB_H #define CPPHTTPLIB_HTTPLIB_H -#define CPPHTTPLIB_VERSION "0.15.3" +#define CPPHTTPLIB_VERSION "0.16.0" /* * Configuration