|
|
@@ -796,9 +796,6 @@ struct Request {
|
|
|
ContentReceiverWithProgress content_receiver;
|
|
|
DownloadProgress download_progress;
|
|
|
UploadProgress upload_progress;
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- const void *ssl = nullptr; // tls_session_t (void*) - TLS session handle
|
|
|
-#endif
|
|
|
|
|
|
bool has_header(const std::string &key) const;
|
|
|
std::string get_header_value(const std::string &key, const char *def = "",
|
|
|
@@ -826,6 +823,10 @@ struct Request {
|
|
|
size_t authorization_count_ = 0;
|
|
|
std::chrono::time_point<std::chrono::steady_clock> start_time_ =
|
|
|
(std::chrono::steady_clock::time_point::min)();
|
|
|
+
|
|
|
+#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+ const void *ssl = nullptr; // tls_session_t (void*) - TLS session handle
|
|
|
+#endif
|
|
|
};
|
|
|
|
|
|
struct Response {
|
|
|
@@ -1397,17 +1398,6 @@ public:
|
|
|
Headers &&request_headers = Headers{})
|
|
|
: res_(std::move(res)), err_(err),
|
|
|
request_headers_(std::move(request_headers)) {}
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- Result(std::unique_ptr<Response> &&res, Error err, Headers &&request_headers,
|
|
|
- int ssl_error)
|
|
|
- : res_(std::move(res)), err_(err),
|
|
|
- request_headers_(std::move(request_headers)), ssl_error_(ssl_error) {}
|
|
|
- Result(std::unique_ptr<Response> &&res, Error err, Headers &&request_headers,
|
|
|
- int ssl_error, unsigned long ssl_backend_error)
|
|
|
- : res_(std::move(res)), err_(err),
|
|
|
- request_headers_(std::move(request_headers)), ssl_error_(ssl_error),
|
|
|
- ssl_backend_error_(ssl_backend_error) {}
|
|
|
-#endif
|
|
|
// Response
|
|
|
operator bool() const { return res_ != nullptr; }
|
|
|
bool operator==(std::nullptr_t) const { return res_ == nullptr; }
|
|
|
@@ -1422,18 +1412,6 @@ public:
|
|
|
// Error
|
|
|
Error error() const { return err_; }
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- // SSL Error (backend-specific error code from handshake)
|
|
|
- int ssl_error() const { return ssl_error_; }
|
|
|
- // Backend-specific error code (OpenSSL: ERR_get_error(), Mbed TLS: mbedtls
|
|
|
- // error code)
|
|
|
- unsigned long ssl_backend_error() const { return ssl_backend_error_; }
|
|
|
-#endif
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
- // OpenSSL Error (alias for ssl_backend_error for backward compatibility)
|
|
|
- unsigned long ssl_openssl_error() const { return ssl_backend_error_; }
|
|
|
-#endif
|
|
|
-
|
|
|
// Request Headers
|
|
|
bool has_request_header(const std::string &key) const;
|
|
|
std::string get_request_header_value(const std::string &key,
|
|
|
@@ -1447,56 +1425,83 @@ private:
|
|
|
std::unique_ptr<Response> res_;
|
|
|
Error err_ = Error::Unknown;
|
|
|
Headers request_headers_;
|
|
|
+
|
|
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+public:
|
|
|
+ Result(std::unique_ptr<Response> &&res, Error err, Headers &&request_headers,
|
|
|
+ int ssl_error)
|
|
|
+ : res_(std::move(res)), err_(err),
|
|
|
+ request_headers_(std::move(request_headers)), ssl_error_(ssl_error) {}
|
|
|
+ Result(std::unique_ptr<Response> &&res, Error err, Headers &&request_headers,
|
|
|
+ int ssl_error, unsigned long ssl_backend_error)
|
|
|
+ : res_(std::move(res)), err_(err),
|
|
|
+ request_headers_(std::move(request_headers)), ssl_error_(ssl_error),
|
|
|
+ ssl_backend_error_(ssl_backend_error) {}
|
|
|
+
|
|
|
+ // SSL Error (backend-specific error code from handshake)
|
|
|
+ int ssl_error() const { return ssl_error_; }
|
|
|
+
|
|
|
+ // Backend-specific error code (OpenSSL: ERR_get_error(), Mbed TLS: mbedtls
|
|
|
+ // error code)
|
|
|
+ unsigned long ssl_backend_error() const { return ssl_backend_error_; }
|
|
|
+
|
|
|
+private:
|
|
|
int ssl_error_ = 0;
|
|
|
unsigned long ssl_backend_error_ = 0;
|
|
|
#endif
|
|
|
+
|
|
|
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
+public:
|
|
|
+ // OpenSSL Error (alias for ssl_backend_error for backward compatibility)
|
|
|
+ unsigned long ssl_openssl_error() const { return ssl_backend_error_; }
|
|
|
+#endif
|
|
|
};
|
|
|
|
|
|
struct ClientConnection {
|
|
|
socket_t sock = INVALID_SOCKET;
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- // Use void* directly since tls::tls_session_t is not yet defined here
|
|
|
- void *session = nullptr;
|
|
|
-#endif
|
|
|
|
|
|
bool is_open() const { return sock != INVALID_SOCKET; }
|
|
|
|
|
|
ClientConnection() = default;
|
|
|
|
|
|
- // Destructor defined after tls namespace is available (see implementation
|
|
|
- // section)
|
|
|
~ClientConnection();
|
|
|
|
|
|
ClientConnection(const ClientConnection &) = delete;
|
|
|
ClientConnection &operator=(const ClientConnection &) = delete;
|
|
|
|
|
|
+#ifndef CPPHTTPLIB_SSL_ENABLED
|
|
|
+ ClientConnection(ClientConnection &&other) noexcept : sock(other.sock) {
|
|
|
+ other.sock = INVALID_SOCKET;
|
|
|
+ }
|
|
|
+
|
|
|
+ ClientConnection &operator=(ClientConnection &&other) noexcept {
|
|
|
+ if (this != &other) {
|
|
|
+ sock = other.sock;
|
|
|
+ other.sock = INVALID_SOCKET;
|
|
|
+ }
|
|
|
+ return *this;
|
|
|
+ }
|
|
|
+#else
|
|
|
ClientConnection(ClientConnection &&other) noexcept
|
|
|
- : sock(other.sock)
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- ,
|
|
|
- session(other.session)
|
|
|
-#endif
|
|
|
- {
|
|
|
+ : sock(other.sock), session(other.session) {
|
|
|
other.sock = INVALID_SOCKET;
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
other.session = nullptr;
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
ClientConnection &operator=(ClientConnection &&other) noexcept {
|
|
|
if (this != &other) {
|
|
|
sock = other.sock;
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- session = other.session;
|
|
|
-#endif
|
|
|
other.sock = INVALID_SOCKET;
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+
|
|
|
+ session = other.session;
|
|
|
other.session = nullptr;
|
|
|
-#endif
|
|
|
}
|
|
|
return *this;
|
|
|
}
|
|
|
+
|
|
|
+ // Use void* directly since tls::tls_session_t is not yet defined here
|
|
|
+ void *session = nullptr;
|
|
|
+#endif
|
|
|
};
|
|
|
|
|
|
namespace detail {
|
|
|
@@ -1721,10 +1726,6 @@ public:
|
|
|
|
|
|
void set_basic_auth(const std::string &username, const std::string &password);
|
|
|
void set_bearer_token_auth(const std::string &token);
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- void set_digest_auth(const std::string &username,
|
|
|
- const std::string &password);
|
|
|
-#endif
|
|
|
|
|
|
void set_keep_alive(bool on);
|
|
|
void set_follow_location(bool on);
|
|
|
@@ -1741,24 +1742,6 @@ public:
|
|
|
void set_proxy_basic_auth(const std::string &username,
|
|
|
const std::string &password);
|
|
|
void set_proxy_bearer_token_auth(const std::string &token);
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- void set_proxy_digest_auth(const std::string &username,
|
|
|
- const std::string &password);
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- void set_ca_cert_path(const std::string &ca_cert_file_path,
|
|
|
- const std::string &ca_cert_dir_path = std::string());
|
|
|
- void enable_server_certificate_verification(bool enabled);
|
|
|
- void enable_server_hostname_verification(bool enabled);
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
- void set_ca_cert_store(X509_STORE *ca_cert_store);
|
|
|
- X509_STORE *create_ca_cert_store(const char *ca_cert, std::size_t size) const;
|
|
|
- void set_server_certificate_verifier(
|
|
|
- std::function<SSLVerifierResponse(SSL *ssl)> verifier);
|
|
|
-#endif
|
|
|
|
|
|
void set_logger(Logger logger);
|
|
|
void set_error_logger(ErrorLogger error_logger);
|
|
|
@@ -1766,14 +1749,16 @@ public:
|
|
|
protected:
|
|
|
struct Socket {
|
|
|
socket_t sock = INVALID_SOCKET;
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- // Use void* directly since tls::tls_session_t is not yet defined here
|
|
|
- void *ssl = nullptr;
|
|
|
-#endif
|
|
|
+
|
|
|
// For Mbed TLS compatibility: start_time for request timeout tracking
|
|
|
std::chrono::time_point<std::chrono::steady_clock> start_time_;
|
|
|
|
|
|
bool is_open() const { return sock != INVALID_SOCKET; }
|
|
|
+
|
|
|
+#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+ // Use void* directly since tls::tls_session_t is not yet defined here
|
|
|
+ void *ssl = nullptr;
|
|
|
+#endif
|
|
|
};
|
|
|
|
|
|
virtual bool create_and_connect_socket(Socket &socket, Error &error);
|
|
|
@@ -1840,10 +1825,6 @@ protected:
|
|
|
std::string basic_auth_username_;
|
|
|
std::string basic_auth_password_;
|
|
|
std::string bearer_token_auth_token_;
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- std::string digest_auth_username_;
|
|
|
- std::string digest_auth_password_;
|
|
|
-#endif
|
|
|
|
|
|
bool keep_alive_ = false;
|
|
|
bool follow_location_ = false;
|
|
|
@@ -1866,36 +1847,11 @@ protected:
|
|
|
std::string proxy_basic_auth_username_;
|
|
|
std::string proxy_basic_auth_password_;
|
|
|
std::string proxy_bearer_token_auth_token_;
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- std::string proxy_digest_auth_username_;
|
|
|
- std::string proxy_digest_auth_password_;
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- std::string ca_cert_file_path_;
|
|
|
- std::string ca_cert_dir_path_;
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- bool server_certificate_verification_ = true;
|
|
|
- bool server_hostname_verification_ = true;
|
|
|
- std::string ca_cert_pem_; // Store CA cert PEM for redirect transfer
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
- X509_STORE *ca_cert_store_ = nullptr;
|
|
|
- std::function<SSLVerifierResponse(SSL *ssl)> server_certificate_verifier_;
|
|
|
-#endif
|
|
|
|
|
|
mutable std::mutex logger_mutex_;
|
|
|
Logger logger_;
|
|
|
ErrorLogger error_logger_;
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- int last_ssl_error_ = 0;
|
|
|
- unsigned long last_backend_error_ = 0;
|
|
|
-#endif
|
|
|
-
|
|
|
private:
|
|
|
bool send_(Request &req, Response &res, Error &error);
|
|
|
Result send_(Request &&req);
|
|
|
@@ -1940,6 +1896,43 @@ private:
|
|
|
virtual bool is_ssl() const;
|
|
|
|
|
|
void transfer_socket_ownership_to_handle(StreamHandle &handle);
|
|
|
+
|
|
|
+#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+public:
|
|
|
+ void set_digest_auth(const std::string &username,
|
|
|
+ const std::string &password);
|
|
|
+ void set_proxy_digest_auth(const std::string &username,
|
|
|
+ const std::string &password);
|
|
|
+ void set_ca_cert_path(const std::string &ca_cert_file_path,
|
|
|
+ const std::string &ca_cert_dir_path = std::string());
|
|
|
+ void enable_server_certificate_verification(bool enabled);
|
|
|
+ void enable_server_hostname_verification(bool enabled);
|
|
|
+
|
|
|
+protected:
|
|
|
+ std::string digest_auth_username_;
|
|
|
+ std::string digest_auth_password_;
|
|
|
+ std::string proxy_digest_auth_username_;
|
|
|
+ std::string proxy_digest_auth_password_;
|
|
|
+ std::string ca_cert_file_path_;
|
|
|
+ std::string ca_cert_dir_path_;
|
|
|
+ bool server_certificate_verification_ = true;
|
|
|
+ bool server_hostname_verification_ = true;
|
|
|
+ std::string ca_cert_pem_; // Store CA cert PEM for redirect transfer
|
|
|
+ int last_ssl_error_ = 0;
|
|
|
+ unsigned long last_backend_error_ = 0;
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
+public:
|
|
|
+ void set_ca_cert_store(X509_STORE *ca_cert_store);
|
|
|
+ X509_STORE *create_ca_cert_store(const char *ca_cert, std::size_t size) const;
|
|
|
+ void set_server_certificate_verifier(
|
|
|
+ std::function<SSLVerifierResponse(SSL *ssl)> verifier);
|
|
|
+
|
|
|
+protected:
|
|
|
+ X509_STORE *ca_cert_store_ = nullptr;
|
|
|
+ std::function<SSLVerifierResponse(SSL *ssl)> server_certificate_verifier_;
|
|
|
+#endif
|
|
|
};
|
|
|
|
|
|
class Client {
|
|
|
@@ -2109,10 +2102,6 @@ public:
|
|
|
|
|
|
void set_basic_auth(const std::string &username, const std::string &password);
|
|
|
void set_bearer_token_auth(const std::string &token);
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- void set_digest_auth(const std::string &username,
|
|
|
- const std::string &password);
|
|
|
-#endif
|
|
|
|
|
|
void set_keep_alive(bool on);
|
|
|
void set_follow_location(bool on);
|
|
|
@@ -2130,26 +2119,20 @@ public:
|
|
|
void set_proxy_basic_auth(const std::string &username,
|
|
|
const std::string &password);
|
|
|
void set_proxy_bearer_token_auth(const std::string &token);
|
|
|
+ void set_logger(Logger logger);
|
|
|
+ void set_error_logger(ErrorLogger error_logger);
|
|
|
+
|
|
|
+private:
|
|
|
+ std::unique_ptr<ClientImpl> cli_;
|
|
|
+
|
|
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+public:
|
|
|
+ void set_digest_auth(const std::string &username,
|
|
|
+ const std::string &password);
|
|
|
void set_proxy_digest_auth(const std::string &username,
|
|
|
const std::string &password);
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
void enable_server_certificate_verification(bool enabled);
|
|
|
void enable_server_hostname_verification(bool enabled);
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
- void set_server_certificate_verifier(
|
|
|
- std::function<SSLVerifierResponse(SSL *ssl)> verifier);
|
|
|
-#endif
|
|
|
-
|
|
|
- void set_logger(Logger logger);
|
|
|
- void set_error_logger(ErrorLogger error_logger);
|
|
|
-
|
|
|
- // SSL
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
void set_ca_cert_path(const std::string &ca_cert_file_path,
|
|
|
const std::string &ca_cert_dir_path = std::string());
|
|
|
|
|
|
@@ -2161,33 +2144,30 @@ public:
|
|
|
// Callback receives session and peer certificate, returns true to accept
|
|
|
using TlsVerifyCallback = std::function<bool(void *session, void *peer_cert)>;
|
|
|
void set_server_certificate_verifier(TlsVerifyCallback verifier);
|
|
|
-#endif
|
|
|
|
|
|
// Backend-agnostic TLS context accessor
|
|
|
void *tls_context() const;
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
- long get_openssl_verify_result() const;
|
|
|
+private:
|
|
|
+ bool is_ssl_ = false;
|
|
|
+#endif
|
|
|
|
|
|
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
+public:
|
|
|
SSL_CTX *ssl_context() const;
|
|
|
+
|
|
|
+ void set_server_certificate_verifier(
|
|
|
+ std::function<SSLVerifierResponse(SSL *ssl)> verifier);
|
|
|
+
|
|
|
+ long get_openssl_verify_result() const;
|
|
|
#endif
|
|
|
|
|
|
#ifdef CPPHTTPLIB_MBEDTLS_SUPPORT
|
|
|
+public:
|
|
|
mbedtls_ssl_config *ssl_config() const;
|
|
|
#endif
|
|
|
-
|
|
|
-private:
|
|
|
- std::unique_ptr<ClientImpl> cli_;
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- bool is_ssl_ = false;
|
|
|
-#endif
|
|
|
};
|
|
|
|
|
|
-/*
|
|
|
- * SSL/TLS Server and Client Classes
|
|
|
- */
|
|
|
-
|
|
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
class SSLServer : public Server {
|
|
|
public:
|
|
|
@@ -2214,22 +2194,6 @@ public:
|
|
|
// for mbedTLS)
|
|
|
explicit SSLServer(const std::function<bool(void *ctx)> &setup_callback);
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
- SSLServer(X509 *cert, EVP_PKEY *private_key,
|
|
|
- X509_STORE *client_ca_cert_store = nullptr);
|
|
|
-
|
|
|
- // OpenSSL-specific callback constructor for full API access
|
|
|
- SSLServer(
|
|
|
- const std::function<bool(SSL_CTX &ssl_ctx)> &setup_ssl_ctx_callback);
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_MBEDTLS_SUPPORT
|
|
|
- // mbedTLS-specific callback constructor for full API access
|
|
|
- // Provides direct access to mbedtls_ssl_config for advanced configuration
|
|
|
- SSLServer(
|
|
|
- const std::function<bool(mbedtls_ssl_config &conf)> &setup_callback);
|
|
|
-#endif
|
|
|
-
|
|
|
~SSLServer() override;
|
|
|
|
|
|
bool is_valid() const override;
|
|
|
@@ -2242,31 +2206,41 @@ public:
|
|
|
// Backend-agnostic TLS context accessor
|
|
|
void *tls_context() const { return ctx_; }
|
|
|
|
|
|
+ int ssl_last_error() const { return last_ssl_error_; }
|
|
|
+
|
|
|
+private:
|
|
|
+ bool process_and_close_socket(socket_t sock) override;
|
|
|
+
|
|
|
+ // Use void* for tls_ctx_t to support all backends
|
|
|
+ void *ctx_ = nullptr;
|
|
|
+ std::mutex ctx_mutex_;
|
|
|
+
|
|
|
+ int last_ssl_error_ = 0;
|
|
|
+
|
|
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
+public:
|
|
|
+ SSLServer(X509 *cert, EVP_PKEY *private_key,
|
|
|
+ X509_STORE *client_ca_cert_store = nullptr);
|
|
|
+
|
|
|
+ SSLServer(
|
|
|
+ const std::function<bool(SSL_CTX &ssl_ctx)> &setup_ssl_ctx_callback);
|
|
|
+
|
|
|
SSL_CTX *ssl_context() const;
|
|
|
|
|
|
void update_certs(X509 *cert, EVP_PKEY *private_key,
|
|
|
X509_STORE *client_ca_cert_store = nullptr);
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_MBEDTLS_SUPPORT
|
|
|
- mbedtls_ssl_config *ssl_config() const;
|
|
|
-#endif
|
|
|
-
|
|
|
- int ssl_last_error() const { return last_ssl_error_; }
|
|
|
|
|
|
private:
|
|
|
- bool process_and_close_socket(socket_t sock) override;
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
STACK_OF(X509_NAME) * extract_ca_names_from_x509_store(X509_STORE *store);
|
|
|
#endif
|
|
|
|
|
|
- // Use void* for tls_ctx_t to support all backends
|
|
|
- void *ctx_ = nullptr;
|
|
|
- std::mutex ctx_mutex_;
|
|
|
+#ifdef CPPHTTPLIB_MBEDTLS_SUPPORT
|
|
|
+public:
|
|
|
+ SSLServer(
|
|
|
+ const std::function<bool(mbedtls_ssl_config &conf)> &setup_callback);
|
|
|
|
|
|
- int last_ssl_error_ = 0;
|
|
|
+ mbedtls_ssl_config *ssl_config() const;
|
|
|
+#endif
|
|
|
};
|
|
|
|
|
|
class SSLClient final : public ClientImpl {
|
|
|
@@ -2290,12 +2264,6 @@ public:
|
|
|
};
|
|
|
explicit SSLClient(const std::string &host, int port, const PemMemory &pem);
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
- explicit SSLClient(const std::string &host, int port, X509 *client_cert,
|
|
|
- EVP_PKEY *client_key,
|
|
|
- const std::string &private_key_password = std::string());
|
|
|
-#endif
|
|
|
-
|
|
|
~SSLClient() override;
|
|
|
|
|
|
bool is_valid() const override;
|
|
|
@@ -2312,16 +2280,6 @@ public:
|
|
|
// Backend-agnostic TLS context accessor
|
|
|
void *tls_context() const { return ctx_; }
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
- long get_openssl_verify_result() const;
|
|
|
-
|
|
|
- SSL_CTX *ssl_context() const;
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_MBEDTLS_SUPPORT
|
|
|
- mbedtls_ssl_config *ssl_config() const;
|
|
|
-#endif
|
|
|
-
|
|
|
private:
|
|
|
bool create_and_connect_socket(Socket &socket, Error &error) override;
|
|
|
bool ensure_socket_connection(Socket &socket, Error &error) override;
|
|
|
@@ -2342,11 +2300,6 @@ private:
|
|
|
|
|
|
bool load_certs();
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
- bool verify_host(X509 *server_cert) const;
|
|
|
- bool verify_host_with_subject_alt_name(X509 *server_cert) const;
|
|
|
- bool verify_host_with_common_name(X509 *server_cert) const;
|
|
|
-#endif
|
|
|
bool check_host_name(const char *pattern, size_t pattern_len) const;
|
|
|
|
|
|
// Use void* directly since tls::tls_ctx_t is not yet defined here
|
|
|
@@ -2359,13 +2312,30 @@ private:
|
|
|
long verify_result_ = 0;
|
|
|
|
|
|
friend class ClientImpl;
|
|
|
+
|
|
|
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
+public:
|
|
|
+ explicit SSLClient(const std::string &host, int port, X509 *client_cert,
|
|
|
+ EVP_PKEY *client_key,
|
|
|
+ const std::string &private_key_password = std::string());
|
|
|
+
|
|
|
+ long get_openssl_verify_result() const;
|
|
|
+
|
|
|
+ SSL_CTX *ssl_context() const;
|
|
|
+
|
|
|
+private:
|
|
|
+ bool verify_host(X509 *server_cert) const;
|
|
|
+ bool verify_host_with_subject_alt_name(X509 *server_cert) const;
|
|
|
+ bool verify_host_with_common_name(X509 *server_cert) const;
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef CPPHTTPLIB_MBEDTLS_SUPPORT
|
|
|
+public:
|
|
|
+ mbedtls_ssl_config *ssl_config() const;
|
|
|
+#endif
|
|
|
};
|
|
|
#endif // CPPHTTPLIB_SSL_ENABLED
|
|
|
|
|
|
-/*
|
|
|
- * Implementation of template methods.
|
|
|
- */
|
|
|
-
|
|
|
namespace detail {
|
|
|
|
|
|
template <typename T, typename U>
|
|
|
@@ -2915,8 +2885,8 @@ bool is_field_value(const std::string &s);
|
|
|
* TLS Abstraction Layer Declarations
|
|
|
*/
|
|
|
|
|
|
-// Crypto abstraction layer
|
|
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+// Crypto abstraction layer
|
|
|
namespace crypto {
|
|
|
|
|
|
// Hash algorithm enumeration
|
|
|
@@ -2934,10 +2904,8 @@ bool hash_raw(HashAlgorithm algo, const void *data, size_t len,
|
|
|
size_t hash_size(HashAlgorithm algo);
|
|
|
|
|
|
} // namespace crypto
|
|
|
-#endif // CPPHTTPLIB_SSL_ENABLED
|
|
|
|
|
|
// TLS abstraction layer
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
namespace tls {
|
|
|
|
|
|
// Error codes for TLS operations (backend-independent)
|
|
|
@@ -3103,12 +3071,11 @@ uint64_t tls_get_error();
|
|
|
std::string tls_error_string(uint64_t code);
|
|
|
|
|
|
} // namespace tls
|
|
|
-#endif // CPPHTTPLIB_SSL_ENABLED
|
|
|
|
|
|
// Utility function for SSL implementation
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
bool is_ip_address(const std::string &host);
|
|
|
-#endif
|
|
|
+
|
|
|
+#endif // CPPHTTPLIB_SSL_ENABLED
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
|
@@ -10250,10 +10217,6 @@ inline void ClientImpl::copy_settings(const ClientImpl &rhs) {
|
|
|
basic_auth_username_ = rhs.basic_auth_username_;
|
|
|
basic_auth_password_ = rhs.basic_auth_password_;
|
|
|
bearer_token_auth_token_ = rhs.bearer_token_auth_token_;
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
- digest_auth_username_ = rhs.digest_auth_username_;
|
|
|
- digest_auth_password_ = rhs.digest_auth_password_;
|
|
|
-#endif
|
|
|
keep_alive_ = rhs.keep_alive_;
|
|
|
follow_location_ = rhs.follow_location_;
|
|
|
path_encode_ = rhs.path_encode_;
|
|
|
@@ -10269,7 +10232,12 @@ inline void ClientImpl::copy_settings(const ClientImpl &rhs) {
|
|
|
proxy_basic_auth_username_ = rhs.proxy_basic_auth_username_;
|
|
|
proxy_basic_auth_password_ = rhs.proxy_basic_auth_password_;
|
|
|
proxy_bearer_token_auth_token_ = rhs.proxy_bearer_token_auth_token_;
|
|
|
+ logger_ = rhs.logger_;
|
|
|
+ error_logger_ = rhs.error_logger_;
|
|
|
+
|
|
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+ digest_auth_username_ = rhs.digest_auth_username_;
|
|
|
+ digest_auth_password_ = rhs.digest_auth_password_;
|
|
|
proxy_digest_auth_username_ = rhs.proxy_digest_auth_username_;
|
|
|
proxy_digest_auth_password_ = rhs.proxy_digest_auth_password_;
|
|
|
ca_cert_file_path_ = rhs.ca_cert_file_path_;
|
|
|
@@ -10277,12 +10245,11 @@ inline void ClientImpl::copy_settings(const ClientImpl &rhs) {
|
|
|
server_certificate_verification_ = rhs.server_certificate_verification_;
|
|
|
server_hostname_verification_ = rhs.server_hostname_verification_;
|
|
|
#endif
|
|
|
+
|
|
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
ca_cert_store_ = rhs.ca_cert_store_;
|
|
|
server_certificate_verifier_ = rhs.server_certificate_verifier_;
|
|
|
#endif
|
|
|
- logger_ = rhs.logger_;
|
|
|
- error_logger_ = rhs.error_logger_;
|
|
|
}
|
|
|
|
|
|
inline socket_t ClientImpl::create_client_socket(Error &error) const {
|
|
|
@@ -10361,6 +10328,7 @@ inline void ClientImpl::close_socket(Socket &socket) {
|
|
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
assert(socket.ssl == nullptr);
|
|
|
#endif
|
|
|
+
|
|
|
if (socket.sock == INVALID_SOCKET) { return; }
|
|
|
detail::close_socket(socket.sock);
|
|
|
socket.sock = INVALID_SOCKET;
|
|
|
@@ -12573,14 +12541,6 @@ inline void ClientImpl::set_bearer_token_auth(const std::string &token) {
|
|
|
bearer_token_auth_token_ = token;
|
|
|
}
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
-inline void ClientImpl::set_digest_auth(const std::string &username,
|
|
|
- const std::string &password) {
|
|
|
- digest_auth_username_ = username;
|
|
|
- digest_auth_password_ = password;
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
inline void ClientImpl::set_keep_alive(bool on) { keep_alive_ = on; }
|
|
|
|
|
|
inline void ClientImpl::set_follow_location(bool on) { follow_location_ = on; }
|
|
|
@@ -12637,19 +12597,31 @@ inline void ClientImpl::set_proxy_bearer_token_auth(const std::string &token) {
|
|
|
}
|
|
|
|
|
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+inline void ClientImpl::set_digest_auth(const std::string &username,
|
|
|
+ const std::string &password) {
|
|
|
+ digest_auth_username_ = username;
|
|
|
+ digest_auth_password_ = password;
|
|
|
+}
|
|
|
+
|
|
|
inline void ClientImpl::set_ca_cert_path(const std::string &ca_cert_file_path,
|
|
|
const std::string &ca_cert_dir_path) {
|
|
|
ca_cert_file_path_ = ca_cert_file_path;
|
|
|
ca_cert_dir_path_ = ca_cert_dir_path;
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
inline void ClientImpl::set_proxy_digest_auth(const std::string &username,
|
|
|
const std::string &password) {
|
|
|
proxy_digest_auth_username_ = username;
|
|
|
proxy_digest_auth_password_ = password;
|
|
|
}
|
|
|
+
|
|
|
+inline void ClientImpl::enable_server_certificate_verification(bool enabled) {
|
|
|
+ server_certificate_verification_ = enabled;
|
|
|
+}
|
|
|
+
|
|
|
+inline void ClientImpl::enable_server_hostname_verification(bool enabled) {
|
|
|
+ server_hostname_verification_ = enabled;
|
|
|
+}
|
|
|
#endif
|
|
|
|
|
|
// ClientImpl::set_ca_cert_store is defined after TLS namespace (uses helpers)
|
|
|
@@ -12677,19 +12649,7 @@ inline X509_STORE *ClientImpl::create_ca_cert_store(const char *ca_cert,
|
|
|
sk_X509_INFO_pop_free(inf, X509_INFO_free);
|
|
|
return cts;
|
|
|
}
|
|
|
-#endif // CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
-inline void ClientImpl::enable_server_certificate_verification(bool enabled) {
|
|
|
- server_certificate_verification_ = enabled;
|
|
|
-}
|
|
|
-
|
|
|
-inline void ClientImpl::enable_server_hostname_verification(bool enabled) {
|
|
|
- server_hostname_verification_ = enabled;
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
inline void ClientImpl::set_server_certificate_verifier(
|
|
|
std::function<SSLVerifierResponse(SSL *ssl)> verifier) {
|
|
|
server_certificate_verifier_ = verifier;
|
|
|
@@ -12773,14 +12733,7 @@ inline std::string hash(HashAlgorithm algo, const std::string &data) {
|
|
|
}
|
|
|
|
|
|
} // namespace crypto
|
|
|
-} // namespace detail
|
|
|
-#endif // CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
|
|
|
-/*
|
|
|
- * OpenSSL TLS Abstraction Layer Implementation
|
|
|
- */
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
-namespace detail {
|
|
|
namespace tls {
|
|
|
|
|
|
// OpenSSL-specific helpers for converting native types to PEM
|
|
|
@@ -13865,10 +13818,6 @@ inline void ClientImpl::set_ca_cert_store(X509_STORE *ca_cert_store) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * OpenSSL-specific SSLServer/SSLClient Implementation
|
|
|
- */
|
|
|
-
|
|
|
inline bool SSLClient::check_host_name(const char *pattern,
|
|
|
size_t pattern_len) const {
|
|
|
if (host_.size() == pattern_len && host_ == pattern) { return true; }
|
|
|
@@ -14402,9 +14351,6 @@ inline std::string hash(HashAlgorithm algo, const std::string &data) {
|
|
|
|
|
|
} // namespace crypto
|
|
|
|
|
|
-/*
|
|
|
- * Mbed TLS TLS Abstraction Layer Implementation
|
|
|
- */
|
|
|
namespace tls {
|
|
|
|
|
|
// Mbed TLS context wrapper (holds config, entropy, DRBG, CA chain, own
|
|
|
@@ -15788,10 +15734,6 @@ inline std::string tls_verify_error_string(long error_code) {
|
|
|
} // namespace tls
|
|
|
} // namespace detail
|
|
|
|
|
|
-/*
|
|
|
- * Mbed TLS-specific SSLServer/SSLClient Implementation
|
|
|
- */
|
|
|
-
|
|
|
inline SSLClient::SSLClient(const std::string &host)
|
|
|
: SSLClient(host, 443, std::string(), std::string()) {}
|
|
|
|
|
|
@@ -16017,8 +15959,6 @@ inline mbedtls_ssl_config *SSLClient::ssl_config() const {
|
|
|
* SSL/TLS Common Implementation
|
|
|
*/
|
|
|
|
|
|
-// ClientConnection destructor (defined here because tls namespace
|
|
|
-// is now available)
|
|
|
inline ClientConnection::~ClientConnection() {
|
|
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
if (session) {
|
|
|
@@ -16027,6 +15967,7 @@ inline ClientConnection::~ClientConnection() {
|
|
|
session = nullptr;
|
|
|
}
|
|
|
#endif
|
|
|
+
|
|
|
if (sock != INVALID_SOCKET) {
|
|
|
detail::close_socket(sock);
|
|
|
sock = INVALID_SOCKET;
|
|
|
@@ -16207,7 +16148,6 @@ inline time_t SSLSocketStream::duration() const {
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
// SSL HTTP server implementation (common for OpenSSL and Mbed TLS)
|
|
|
inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path,
|
|
|
const char *client_ca_cert_file_path,
|
|
|
@@ -16515,8 +16455,6 @@ inline bool SSLServer::update_client_ca_pem(const char *ca_pem) {
|
|
|
}
|
|
|
#endif // CPPHTTPLIB_SSL_ENABLED
|
|
|
|
|
|
-#endif // CPPHTTPLIB_SSL_ENABLED
|
|
|
-
|
|
|
// Universal client implementation
|
|
|
inline Client::Client(const std::string &scheme_host_port)
|
|
|
: Client(scheme_host_port, std::string(), std::string()) {}
|
|
|
@@ -17137,12 +17075,6 @@ inline void Client::set_basic_auth(const std::string &username,
|
|
|
inline void Client::set_bearer_token_auth(const std::string &token) {
|
|
|
cli_->set_bearer_token_auth(token);
|
|
|
}
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
-inline void Client::set_digest_auth(const std::string &username,
|
|
|
- const std::string &password) {
|
|
|
- cli_->set_digest_auth(username, password);
|
|
|
-}
|
|
|
-#endif
|
|
|
|
|
|
inline void Client::set_keep_alive(bool on) { cli_->set_keep_alive(on); }
|
|
|
inline void Client::set_follow_location(bool on) {
|
|
|
@@ -17174,7 +17106,21 @@ inline void Client::set_proxy_basic_auth(const std::string &username,
|
|
|
inline void Client::set_proxy_bearer_token_auth(const std::string &token) {
|
|
|
cli_->set_proxy_bearer_token_auth(token);
|
|
|
}
|
|
|
+
|
|
|
+inline void Client::set_logger(Logger logger) {
|
|
|
+ cli_->set_logger(std::move(logger));
|
|
|
+}
|
|
|
+
|
|
|
+inline void Client::set_error_logger(ErrorLogger error_logger) {
|
|
|
+ cli_->set_error_logger(std::move(error_logger));
|
|
|
+}
|
|
|
+
|
|
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
+inline void Client::set_digest_auth(const std::string &username,
|
|
|
+ const std::string &password) {
|
|
|
+ cli_->set_digest_auth(username, password);
|
|
|
+}
|
|
|
+
|
|
|
inline void Client::set_proxy_digest_auth(const std::string &username,
|
|
|
const std::string &password) {
|
|
|
cli_->set_proxy_digest_auth(username, password);
|
|
|
@@ -17187,31 +17133,12 @@ inline void Client::enable_server_certificate_verification(bool enabled) {
|
|
|
inline void Client::enable_server_hostname_verification(bool enabled) {
|
|
|
cli_->enable_server_hostname_verification(enabled);
|
|
|
}
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
-inline void Client::set_server_certificate_verifier(
|
|
|
- std::function<SSLVerifierResponse(SSL *ssl)> verifier) {
|
|
|
- cli_->set_server_certificate_verifier(verifier);
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-inline void Client::set_logger(Logger logger) {
|
|
|
- cli_->set_logger(std::move(logger));
|
|
|
-}
|
|
|
-
|
|
|
-inline void Client::set_error_logger(ErrorLogger error_logger) {
|
|
|
- cli_->set_error_logger(std::move(error_logger));
|
|
|
-}
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
inline void Client::set_ca_cert_path(const std::string &ca_cert_file_path,
|
|
|
const std::string &ca_cert_dir_path) {
|
|
|
cli_->set_ca_cert_path(ca_cert_file_path, ca_cert_dir_path);
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
-#ifdef CPPHTTPLIB_SSL_ENABLED
|
|
|
inline void Client::set_ca_cert_store(void *ca_cert_store) {
|
|
|
if (is_ssl_) {
|
|
|
static_cast<SSLClient &>(*cli_).set_ca_cert_store(ca_cert_store);
|
|
|
@@ -17236,28 +17163,33 @@ inline void *Client::tls_context() const {
|
|
|
if (is_ssl_) { return static_cast<SSLClient &>(*cli_).tls_context(); }
|
|
|
return nullptr;
|
|
|
}
|
|
|
-#endif
|
|
|
+#endif // CPPHTTPLIB_SSL_ENABLED
|
|
|
|
|
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
+inline SSL_CTX *Client::ssl_context() const {
|
|
|
+ if (is_ssl_) { return static_cast<SSLClient &>(*cli_).ssl_context(); }
|
|
|
+ return nullptr;
|
|
|
+}
|
|
|
+
|
|
|
+inline void Client::set_server_certificate_verifier(
|
|
|
+ std::function<SSLVerifierResponse(SSL *ssl)> verifier) {
|
|
|
+ cli_->set_server_certificate_verifier(verifier);
|
|
|
+}
|
|
|
+
|
|
|
inline long Client::get_openssl_verify_result() const {
|
|
|
if (is_ssl_) {
|
|
|
return static_cast<SSLClient &>(*cli_).get_openssl_verify_result();
|
|
|
}
|
|
|
return -1; // NOTE: -1 doesn't match any of X509_V_ERR_???
|
|
|
}
|
|
|
-
|
|
|
-inline SSL_CTX *Client::ssl_context() const {
|
|
|
- if (is_ssl_) { return static_cast<SSLClient &>(*cli_).ssl_context(); }
|
|
|
- return nullptr;
|
|
|
-}
|
|
|
-#endif
|
|
|
+#endif // CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
|
|
|
#ifdef CPPHTTPLIB_MBEDTLS_SUPPORT
|
|
|
inline mbedtls_ssl_config *Client::ssl_config() const {
|
|
|
if (is_ssl_) { return static_cast<SSLClient &>(*cli_).ssl_config(); }
|
|
|
return nullptr;
|
|
|
}
|
|
|
-#endif
|
|
|
+#endif // CPPHTTPLIB_MBEDTLS_SUPPORT
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|