Abstract TLS API support (Resolve #2309) (#2342)

Abstract TLS API support (OpenSSL and MbedTLS backends)
This commit is contained in:
yhirose
2026-02-01 23:48:03 -05:00
committed by GitHub
parent dc6faf5c17
commit 6be32a540d
11 changed files with 5535 additions and 2052 deletions
+61 -17
View File
@@ -1,38 +1,44 @@
CXX = clang++
CXXFLAGS = -g -std=c++11 -I. -Wall -Wextra -Wtype-limits -Wconversion -Wshadow $(EXTRA_CXXFLAGS) -DCPPHTTPLIB_USE_NON_BLOCKING_GETADDRINFO # -fno-exceptions -DCPPHTTPLIB_NO_EXCEPTIONS -fsanitize=address
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
ifneq ($(OS), Windows_NT)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Darwin)
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
OPENSSL_SUPPORT += -DCPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN -framework Security
MBEDTLS_DIR ?= $(shell brew --prefix mbedtls@3)
MBEDTLS_SUPPORT = -DCPPHTTPLIB_MBEDTLS_SUPPORT -I$(MBEDTLS_DIR)/include -L$(MBEDTLS_DIR)/lib -lmbedtls -lmbedx509 -lmbedcrypto
MBEDTLS_SUPPORT += -DCPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN -framework Security
else
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -lssl -lcrypto
MBEDTLS_SUPPORT = -DCPPHTTPLIB_MBEDTLS_SUPPORT -lmbedtls -lmbedx509 -lmbedcrypto
endif
endif
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
BROTLI_DIR = $(PREFIX)/opt/brotli
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
ZSTD_DIR = $(PREFIX)/opt/zstd
ZSTD_SUPPORT = -DCPPHTTPLIB_ZSTD_SUPPORT -I$(ZSTD_DIR)/include -L$(ZSTD_DIR)/lib -lzstd
LIBS = -lpthread -lcurl
ifneq ($(OS), Windows_NT)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Darwin)
LIBS += -framework CoreFoundation -framework CFNetwork
endif
ifneq ($(UNAME_S), Darwin)
LIBS += -lanl
# macOS: use Homebrew paths for brotli and zstd
BROTLI_DIR = $(PREFIX)/opt/brotli
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
ZSTD_DIR = $(PREFIX)/opt/zstd
ZSTD_SUPPORT = -DCPPHTTPLIB_ZSTD_SUPPORT -I$(ZSTD_DIR)/include -L$(ZSTD_DIR)/lib -lzstd
LIBS = -lpthread -lcurl -framework CoreFoundation -framework CFNetwork
else
# Linux: use system paths
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -lbrotlicommon -lbrotlienc -lbrotlidec
ZSTD_SUPPORT = -DCPPHTTPLIB_ZSTD_SUPPORT -lzstd
LIBS = -lpthread -lcurl -lanl
endif
endif
TEST_ARGS = gtest/src/gtest-all.cc gtest/src/gtest_main.cc -Igtest -Igtest/include $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) $(ZSTD_SUPPORT) $(LIBS)
TEST_ARGS_MBEDTLS = gtest/src/gtest-all.cc gtest/src/gtest_main.cc -Igtest -Igtest/include $(MBEDTLS_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) $(ZSTD_SUPPORT) $(LIBS)
TEST_ARGS_NO_TLS = gtest/src/gtest-all.cc gtest/src/gtest_main.cc -Igtest -Igtest/include $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) $(ZSTD_SUPPORT) $(LIBS)
# By default, use standalone_fuzz_target_runner.
# This runner does no fuzzing, but simply executes the inputs
@@ -69,6 +75,25 @@ proxy : test_proxy
cd proxy && docker compose down; \
exit $$exit_code
proxy_mbedtls : test_proxy_mbedtls
@echo "Starting proxy server..."
cd proxy && \
docker compose up -d
@echo "Waiting for proxy to be ready..."
@until nc -z localhost 3128 && nc -z localhost 3129; do sleep 1; done
@echo "Proxy servers are ready, waiting additional 5 seconds for full startup..."
@sleep 5
@echo "Checking proxy server status..."
@cd proxy && docker compose ps
@echo "Checking proxy server logs..."
@cd proxy && docker compose logs --tail=20
@echo "Running proxy tests (Mbed TLS)..."
./test_proxy_mbedtls; \
exit_code=$$?; \
echo "Stopping proxy server..."; \
cd proxy && docker compose down; \
exit $$exit_code
test : test.cc include_httplib.cc ../httplib.h Makefile cert.pem
$(CXX) -o $@ -I.. $(CXXFLAGS) test.cc include_httplib.cc $(TEST_ARGS)
@file $@
@@ -78,6 +103,22 @@ test : test.cc include_httplib.cc ../httplib.h Makefile cert.pem
test_split : test.cc ../httplib.h httplib.cc Makefile cert.pem
$(CXX) -o $@ $(CXXFLAGS) test.cc httplib.cc $(TEST_ARGS)
# Mbed TLS backend targets
test_mbedtls : test.cc include_httplib.cc ../httplib.h Makefile cert.pem
$(CXX) -o $@ -I.. $(CXXFLAGS) test.cc include_httplib.cc $(TEST_ARGS_MBEDTLS)
@file $@
test_split_mbedtls : test.cc ../httplib.h httplib.cc Makefile cert.pem
$(CXX) -o $@ $(CXXFLAGS) test.cc httplib.cc $(TEST_ARGS_MBEDTLS)
# No TLS
test_no_tls : test.cc include_httplib.cc ../httplib.h Makefile
$(CXX) -o $@ -I.. $(CXXFLAGS) test.cc include_httplib.cc $(TEST_ARGS_NO_TLS)
@file $@
test_split_no_tls : test.cc ../httplib.h httplib.cc Makefile
$(CXX) -o $@ $(CXXFLAGS) test.cc httplib.cc $(TEST_ARGS_NO_TLS)
check_abi:
@./check-shared-library-abi-compatibility.sh
@@ -106,6 +147,9 @@ style_check: $(STYLE_CHECK_FILES)
test_proxy : test_proxy.cc ../httplib.h Makefile cert.pem
$(CXX) -o $@ -I.. $(CXXFLAGS) test_proxy.cc $(TEST_ARGS)
test_proxy_mbedtls : test_proxy.cc ../httplib.h Makefile cert.pem
$(CXX) -o $@ -I.. $(CXXFLAGS) test_proxy.cc $(TEST_ARGS_MBEDTLS)
# Runs server_fuzzer.cc based on value of $(LIB_FUZZING_ENGINE).
# Usage: make fuzz_test LIB_FUZZING_ENGINE=/path/to/libFuzzer
fuzz_test: server_fuzzer
@@ -128,5 +172,5 @@ cert.pem:
./gen-certs.sh
clean:
rm -rf test test_split test_proxy server_fuzzer *.pem *.0 *.o *.1 *.srl httplib.h httplib.cc _build* *.dSYM
rm -rf test test_split test_mbedtls test_split_mbedtls test_no_tls, test_split_no_tls test_proxy test_proxy_mbedtls server_fuzzer *.pem *.0 *.o *.1 *.srl httplib.h httplib.cc _build* *.dSYM
+1 -1
View File
@@ -14,5 +14,5 @@ openssl genrsa 2048 > client.key.pem
openssl req -new -batch -config test.conf -key client.key.pem | openssl x509 -days 370 -req -CA rootCA.cert.pem -CAkey rootCA.key.pem -CAcreateserial > client.cert.pem
openssl genrsa -passout pass:test123! 2048 > key_encrypted.pem
openssl req -new -batch -config test.conf -key key_encrypted.pem | openssl x509 -days 3650 -req -signkey key_encrypted.pem > cert_encrypted.pem
openssl genrsa -aes256 -passout pass:test012! 2048 > client_encrypted.key.pem
openssl genrsa 2048 | openssl pkcs8 -topk8 -v1 PBE-SHA1-3DES -passout pass:test012! -out client_encrypted.key.pem
openssl req -new -batch -config test.conf -key client_encrypted.key.pem -passin pass:test012! | openssl x509 -days 370 -req -CA rootCA.cert.pem -CAkey rootCA.key.pem -CAcreateserial > client_encrypted.cert.pem
+944 -389
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -26,7 +26,7 @@ TEST(ProxyTest, NoSSLBasic) {
ProxyTest(cli, true);
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef CPPHTTPLIB_SSL_ENABLED
TEST(ProxyTest, SSLBasic) {
SSLClient cli("nghttp2.org");
ProxyTest(cli, true);
@@ -51,7 +51,7 @@ void RedirectProxyText(T &cli, const char *path, bool basic) {
if (basic) {
cli.set_proxy_basic_auth("hello", "world");
} else {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef CPPHTTPLIB_SSL_ENABLED
cli.set_proxy_digest_auth("hello", "world");
#endif
}
@@ -67,7 +67,7 @@ TEST(RedirectTest, HTTPBinNoSSLBasic) {
RedirectProxyText(cli, "/httpbin/redirect/2", true);
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef CPPHTTPLIB_SSL_ENABLED
TEST(RedirectTest, HTTPBinNoSSLDigest) {
Client cli("nghttp2.org");
RedirectProxyText(cli, "/httpbin/redirect/2", false);
@@ -84,7 +84,7 @@ TEST(RedirectTest, HTTPBinSSLDigest) {
}
#endif
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef CPPHTTPLIB_SSL_ENABLED
TEST(RedirectTest, YouTubeNoSSLBasic) {
Client cli("youtube.com");
RedirectProxyText(cli, "/", true);
@@ -157,7 +157,7 @@ TEST(BaseAuthTest, NoSSL) {
BaseAuthTestFromHTTPWatch(cli);
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef CPPHTTPLIB_SSL_ENABLED
TEST(BaseAuthTest, SSL) {
SSLClient cli("httpcan.org");
BaseAuthTestFromHTTPWatch(cli);
@@ -166,7 +166,7 @@ TEST(BaseAuthTest, SSL) {
// ----------------------------------------------------------------------------
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef CPPHTTPLIB_SSL_ENABLED
template <typename T> void DigestAuthTestFromHTTPWatch(T &cli) {
cli.set_proxy("localhost", 3129);
cli.set_proxy_digest_auth("hello", "world");
@@ -230,13 +230,13 @@ template <typename T> void KeepAliveTest(T &cli, bool basic) {
if (basic) {
cli.set_proxy_basic_auth("hello", "world");
} else {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef CPPHTTPLIB_SSL_ENABLED
cli.set_proxy_digest_auth("hello", "world");
#endif
}
cli.set_follow_location(true);
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef CPPHTTPLIB_SSL_ENABLED
cli.set_digest_auth("hello", "world");
#endif
@@ -274,7 +274,7 @@ template <typename T> void KeepAliveTest(T &cli, bool basic) {
}
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef CPPHTTPLIB_SSL_ENABLED
TEST(KeepAliveTest, NoSSLWithBasic) {
Client cli("nghttp2.org");
KeepAliveTest(cli, true);