diff --git a/CMakeLists.txt b/CMakeLists.txt index d681500..4e1fc29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,3 +60,5 @@ install( EXPORT "${DUCKDB_EXPORT_SET}" LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ARCHIVE DESTINATION "${INSTALL_LIB_DIR}") + +add_subdirectory(test-ssl) \ No newline at end of file diff --git a/test-ssl/CMakeLists.txt b/test-ssl/CMakeLists.txt new file mode 100644 index 0000000..610bca4 --- /dev/null +++ b/test-ssl/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.5...3.31.5) + +find_package(OpenSSL REQUIRED) + +project("Test ssl") +set(CMAKE_CXX_STANDARD 11) + +add_definitions(-DNO_DUCKDB_RE2 -DCMAKE_BUILD_TYPE=Debug) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0") + +include_directories( + ${PROJECT_SOURCE_DIR}/../third_party/httplib + ${PROJECT_SOURCE_DIR}/../duckdb/src/include) + +add_executable("test_ssl" "test_ssl.cc") + +target_link_libraries("test_ssl" OpenSSL::SSL OpenSSL::Crypto) + +install(TARGETS "test_ssl") + +# cmake -S . -G Ninja -B build && cmake --build build \ No newline at end of file diff --git a/test-ssl/test_ssl.cc b/test-ssl/test_ssl.cc new file mode 100644 index 0000000..39a44bd --- /dev/null +++ b/test-ssl/test_ssl.cc @@ -0,0 +1,16 @@ +#define CPPHTTPLIB_OPENSSL_SUPPORT +#include "httplib.hpp" + +using namespace duckdb_httplib_openssl; + +int main() { + Client client("https://ui.duckdb.org"); + auto res = client.Get("/"); + if (res) { + std::cout << "Status: " << res->status << std::endl; + std::cout << "Body: " << res->body.substr(0, 42) << "... (" << res->body.size() << ")" << std::endl; + } else { + std::cout << "Error: " << res.error() << std::endl; + } + return 0; +} \ No newline at end of file diff --git a/third_party/httplib/httplib.hpp b/third_party/httplib/httplib.hpp index f12a80d..f3e928d 100644 --- a/third_party/httplib/httplib.hpp +++ b/third_party/httplib/httplib.hpp @@ -248,8 +248,78 @@ using socket_t = int; #include #include #include + +#ifdef NO_DUCKDB_RE2 +namespace duckdb_re2 { +enum class RegexOptions : uint8_t { NONE, CASE_INSENSITIVE }; +class Regex { +public: + explicit Regex(const std::string &pattern, RegexOptions options = RegexOptions::NONE): re(pattern) {} + explicit Regex(const char *pattern, RegexOptions options = RegexOptions::NONE) : Regex(std::string(pattern)) { + } + // const duckdb_re2::RE2 &GetRegex() const { + // return *regex; + // } + std::regex re; +}; +struct GroupMatch { + std::string text; + uint32_t position; + + const std::string &str() const { // NOLINT + return text; + } + operator std::string() const { // NOLINT: allow implicit cast + return text; + } +}; + +struct Match { + + GroupMatch GetGroup(uint64_t index) { + return {str(index), static_cast(position(index))}; + } + + std::string str(uint64_t index) { // NOLINT + return m.str(index); + } + + uint64_t position(uint64_t index) { // NOLINT + return m.position(index); + } + + uint64_t length(uint64_t index) { // NOLINT + throw std::runtime_error("uint64_t length(uint64_t index) - NA"); + } + + GroupMatch operator[](uint64_t i) { + return GetGroup(i); + } + std::cmatch m; +}; + +bool RegexSearch(const std::string &input, Match &match, const Regex ®ex) { + throw std::runtime_error("bool RegexSearch(const std::string &input, Match &match, const Regex ®ex) - NA"); +} + +bool RegexMatch(const std::string &input, Match &match, const Regex ®ex) { + return std::regex_match(input.c_str(), match.m, regex.re); +} + +bool RegexMatch(const char *start, const char *end, Match &match, const Regex ®ex) { + throw std::runtime_error("bool RegexMatch(const char *start, const char *end, Match &match, const Regex ®ex) - NA"); +} + +bool RegexMatch(const std::string &input, const Regex ®ex) { + std::cmatch m; + return std::regex_match(input.c_str(), m, regex.re); +} +} + +#else #include "duckdb/common/re2_regex.hpp" #include "duckdb/common/random_engine.hpp" +#endif #ifdef CPPHTTPLIB_OPENSSL_SUPPORT #ifdef _WIN32 @@ -4643,6 +4713,9 @@ inline std::string to_lower(const char *beg, const char *end) { } inline std::string make_multipart_data_boundary() { +#ifdef NO_DUCKDB_RE2 + throw std::runtime_error("NA"); +#else static const char data[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -4653,6 +4726,7 @@ inline std::string make_multipart_data_boundary() { } return result; +#endif } inline bool is_multipart_boundary_chars_valid(const std::string &boundary) { @@ -5109,6 +5183,7 @@ inline bool parse_www_authenticate(const Response &res, if (type == "Basic") { return false; } else if (type == "Digest") { +#ifndef NO_DUCKDB_RE2 s = s.substr(pos + 1); auto matches = duckdb_re2::RegexFindAll(s, re); for (auto &m : matches) { @@ -5122,6 +5197,9 @@ inline bool parse_www_authenticate(const Response &res, auth[key] = val; } return true; +#else + throw std::runtime_error("parse_www_authenticate- NA"); +#endif } } } @@ -8166,6 +8244,10 @@ inline SSL *ssl_new(socket_t sock, SSL_CTX *ctx, std::mutex &ctx_mutex, } if (ssl) { +#ifdef NO_DUCKDB_RE2 + SSL_set_msg_callback(ssl, SSL_trace); + SSL_set_msg_callback_arg(ssl, BIO_new_fp(stdout, 0)); +#endif set_nonblocking(sock, true); auto bio = BIO_new_socket(static_cast(sock), BIO_NOCLOSE); BIO_set_nbio(bio, 1);