From 4285d33992bfa05d0313843973341caab552388c Mon Sep 17 00:00:00 2001 From: yhirose Date: Tue, 26 Aug 2025 21:42:13 -0400 Subject: [PATCH 1/5] Fix #2223 (#2224) * Fix #2223 * Fix build error --- httplib.h | 21 ++++++++++++++++----- test/test.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/httplib.h b/httplib.h index 703c171a34..371db9a618 100644 --- a/httplib.h +++ b/httplib.h @@ -10429,6 +10429,13 @@ inline void ClientImpl::set_error_logger(ErrorLogger error_logger) { #ifdef CPPHTTPLIB_OPENSSL_SUPPORT namespace detail { +inline bool is_ip_address(const std::string &host) { + struct in_addr addr4; + struct in6_addr addr6; + return inet_pton(AF_INET, host.c_str(), &addr4) == 1 || + inet_pton(AF_INET6, host.c_str(), &addr6) == 1; +} + template inline SSL *ssl_new(socket_t sock, SSL_CTX *ctx, std::mutex &ctx_mutex, U SSL_connect_or_accept, V setup) { @@ -11087,14 +11094,18 @@ inline bool SSLClient::initialize_ssl(Socket &socket, Error &error) { return true; }, [&](SSL *ssl2) { + // Set SNI only if host is not IP address + if (!detail::is_ip_address(host_)) { #if defined(OPENSSL_IS_BORINGSSL) - SSL_set_tlsext_host_name(ssl2, host_.c_str()); + SSL_set_tlsext_host_name(ssl2, host_.c_str()); #else - // NOTE: Direct call instead of using the OpenSSL macro to suppress - // -Wold-style-cast warning - SSL_ctrl(ssl2, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, - static_cast(const_cast(host_.c_str()))); + // NOTE: Direct call instead of using the OpenSSL macro to suppress + // -Wold-style-cast warning + SSL_ctrl(ssl2, SSL_CTRL_SET_TLSEXT_HOSTNAME, + TLSEXT_NAMETYPE_host_name, + static_cast(const_cast(host_.c_str()))); #endif + } return true; }); diff --git a/test/test.cc b/test/test.cc index 867b093e9f..23dd0fb418 100644 --- a/test/test.cc +++ b/test/test.cc @@ -7366,6 +7366,48 @@ TEST(KeepAliveTest, SSLClientReconnectionPost) { ASSERT_TRUE(result); EXPECT_EQ(200, result->status); } + +TEST(SNI_AutoDetectionTest, SNI_Logic) { + { + SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE); + ASSERT_TRUE(svr.is_valid()); + + svr.Get("/sni", [&](const Request &req, Response &res) { + std::string expected; + if (req.ssl) { + if (const char *sni = + SSL_get_servername(req.ssl, TLSEXT_NAMETYPE_host_name)) { + expected = sni; + } + } + EXPECT_EQ(expected, req.get_param_value("expected")); + res.set_content("ok", "text/plain"); + }); + + auto listen_thread = std::thread([&svr] { svr.listen(HOST, PORT); }); + auto se = detail::scope_exit([&] { + svr.stop(); + listen_thread.join(); + ASSERT_FALSE(svr.is_running()); + }); + + svr.wait_until_ready(); + + { + SSLClient cli("localhost", PORT); + cli.enable_server_certificate_verification(false); + auto res = cli.Get("/sni?expected=localhost"); + ASSERT_TRUE(res); + } + + { + SSLClient cli("::1", PORT); + cli.enable_server_certificate_verification(false); + auto res = cli.Get("/sni?expected="); + ASSERT_TRUE(res); + } + } +} #endif TEST(ClientProblemDetectionTest, ContentProvider) { From f4cc542d4b5149ab78bac2e889e564c7550f2244 Mon Sep 17 00:00:00 2001 From: yhirose Date: Tue, 26 Aug 2025 22:17:54 -0400 Subject: [PATCH 2/5] Fix Dockerfile problem with CMD --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 67aa028b7e..3495b42f24 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,4 +10,4 @@ COPY docker/html/index.html /html/index.html EXPOSE 80 ENTRYPOINT ["/server"] -CMD ["0.0.0.0", "80", "/", "/html"] +CMD ["--host", "0.0.0.0", "--port", "80", "--mount", "/:./html"] From b20b5fdd1f5355c27a3cac42e2c4ea0e4729616d Mon Sep 17 00:00:00 2001 From: yhirose Date: Tue, 26 Aug 2025 23:18:59 -0400 Subject: [PATCH 3/5] Add 'release-docker' workflow --- .github/workflows/release-docker.yml | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/release-docker.yml diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml new file mode 100644 index 0000000000..1038bf847c --- /dev/null +++ b/.github/workflows/release-docker.yml @@ -0,0 +1,35 @@ +name: Release Docker Image + +on: + release: + types: [published] + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract version tag without 'v' + id: set_tag + run: echo "tag=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: true + tags: | + yhirose4dockerhub/cpp-httplib-server:latest + yhirose4dockerhub/cpp-httplib-server:${{ steps.set_tag.outputs.tag }} From 54e75dc8ef4dd92cda46c5d83222ea01bfabf8a2 Mon Sep 17 00:00:00 2001 From: yhirose Date: Tue, 26 Aug 2025 23:34:18 -0400 Subject: [PATCH 4/5] Add manual run --- .github/workflows/release-docker.yml | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml index 1038bf847c..80a5c07cdc 100644 --- a/.github/workflows/release-docker.yml +++ b/.github/workflows/release-docker.yml @@ -1,8 +1,12 @@ + + + name: Release Docker Image on: release: types: [published] + workflow_dispatch: jobs: build-and-push: @@ -10,6 +14,23 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history and tags + + - name: Extract tag (manual) + if: github.event_name == 'workflow_dispatch' + id: set_tag_manual + run: | + # Checkout the latest tag and set output + git fetch --tags + LATEST_TAG=$(git describe --tags --abbrev=0) + git checkout $LATEST_TAG + echo "tag=${LATEST_TAG#v}" >> $GITHUB_OUTPUT + + - name: Extract tag (release) + if: github.event_name == 'release' + id: set_tag_release + run: echo "tag=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -20,16 +41,13 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Extract version tag without 'v' - id: set_tag - run: echo "tag=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT - - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile push: true + # Use extracted tag without leading 'v' tags: | yhirose4dockerhub/cpp-httplib-server:latest - yhirose4dockerhub/cpp-httplib-server:${{ steps.set_tag.outputs.tag }} + yhirose4dockerhub/cpp-httplib-server:${{ steps.set_tag_manual.outputs.tag || steps.set_tag_release.outputs.tag }} From eb11032797f18b21d4a24abacd6c5df655e99dbb Mon Sep 17 00:00:00 2001 From: yhirose Date: Wed, 27 Aug 2025 00:31:14 -0400 Subject: [PATCH 5/5] Fix platform problem --- .github/workflows/release-docker.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml index 80a5c07cdc..179ab82fae 100644 --- a/.github/workflows/release-docker.yml +++ b/.github/workflows/release-docker.yml @@ -1,6 +1,3 @@ - - - name: Release Docker Image on: @@ -47,6 +44,7 @@ jobs: context: . file: ./Dockerfile push: true + platforms: linux/amd64,linux/arm64 # Build for both amd64 and arm64 # Use extracted tag without leading 'v' tags: | yhirose4dockerhub/cpp-httplib-server:latest