Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ find_package(OpenSSL REQUIRED)
add_compile_definitions(OPENSSL_BACKEND_USED)
endif()

if (SSL_BACKEND_USED STREQUAL "OpenSSL" OR SSL_BACKEND_USED STREQUAL "MbedTLS")
# CURLOPT_SSL_CTX_FUNCTION works for libcurl powered by OpenSSL, wolfSSL, mbedTLS or BearSSL.
# If libcurl was built against another SSL library this functionality is absent.
add_compile_definitions(SSL_CTX_CALLBACK_ENABLED)
endif ()

# Curl configuration
if(CPR_USE_SYSTEM_CURL)
if(CPR_ENABLE_SSL)
Expand Down
11 changes: 11 additions & 0 deletions cpr/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,14 @@ void Session::SetDebugCallback(const DebugCallback& debug) {
curl_easy_setopt(curl_->handle, CURLOPT_VERBOSE, 1L);
}

#ifdef SSL_CTX_CALLBACK_ENABLED
void Session::SetSslCtxCallback(const SslCtxCallback& ssl_ctx) {
curl_easy_setopt(curl_->handle, CURLOPT_SSL_CTX_FUNCTION, cpr::util::sslCtxUserFunction);
cbs_->ssl_ctxcb_ = ssl_ctx;
curl_easy_setopt(curl_->handle, CURLOPT_SSL_CTX_DATA, &cbs_->ssl_ctxcb_);
}
#endif // SSL_CTX_CALLBACK_ENABLED

void Session::SetUrl(const Url& url) {
url_ = url;
}
Expand Down Expand Up @@ -963,6 +971,9 @@ void Session::SetOption(const HeaderCallback& header) { SetHeaderCallback(header
void Session::SetOption(const WriteCallback& write) { SetWriteCallback(write); }
void Session::SetOption(const ProgressCallback& progress) { SetProgressCallback(progress); }
void Session::SetOption(const DebugCallback& debug) { SetDebugCallback(debug); }
#ifdef SSL_CTX_CALLBACK_ENABLED
void Session::SetOption(const SslCtxCallback& ssl_ctx){ SetSslCtxCallback(ssl_ctx); }
#endif // SSL_CTX_CALLBACK_ENABLED
void Session::SetOption(const Url& url) { SetUrl(url); }
void Session::SetOption(const Parameters& parameters) { SetParameters(parameters); }
void Session::SetOption(Parameters&& parameters) { SetParameters(std::move(parameters)); }
Expand Down
4 changes: 4 additions & 0 deletions cpr/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ int debugUserFunction(CURL* /*handle*/, curl_infotype type, char* data, size_t s
return 0;
}

CURLcode sslCtxUserFunction(CURL* /*handle*/, void* ssl_ctx, const SslCtxCallback* callback) {
return (*callback)(ssl_ctx);
}

/**
* Creates a temporary CurlHolder object and uses it to escape the given string.
* If you plan to use this methode on a regular basis think about creating a CurlHolder
Expand Down
16 changes: 16 additions & 0 deletions include/cpr/callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,22 @@ class CancellationCallback {
std::optional<std::reference_wrapper<ProgressCallback>> user_cb;
};

/**
* Functor class for certificate functions that will be used just before the initialization of an SSL connection.
*/
class SslCtxCallback {
public:
SslCtxCallback() = default;
explicit SslCtxCallback(std::function<CURLcode(void* ssl_ctx, intptr_t userdata)> p_callback, intptr_t p_userdata = 0) : userdata(p_userdata), callback(std::move(p_callback)) {}

CURLcode operator()(void* ssl_ctx) const {
return callback(ssl_ctx, userdata);
}

private:
intptr_t userdata{};
std::function<CURLcode(void* ssl_ctx, intptr_t userdata)> callback;
};

} // namespace cpr

Expand Down
7 changes: 7 additions & 0 deletions include/cpr/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ class Session : public std::enable_shared_from_this<Session> {
void SetWriteCallback(const WriteCallback& write);
void SetProgressCallback(const ProgressCallback& progress);
void SetDebugCallback(const DebugCallback& debug);
#ifdef SSL_CTX_CALLBACK_ENABLED
void SetSslCtxCallback(const SslCtxCallback& ssl_ctx);
#endif // SSL_CTX_CALLBACK_ENABLED
void SetVerbose(const Verbose& verbose);
void SetInterface(const Interface& iface);
void SetLocalPort(const LocalPort& local_port);
Expand Down Expand Up @@ -145,6 +148,9 @@ class Session : public std::enable_shared_from_this<Session> {
void SetOption(const WriteCallback& write);
void SetOption(const ProgressCallback& progress);
void SetOption(const DebugCallback& debug);
#ifdef SSL_CTX_CALLBACK_ENABLED
void SetOption(const SslCtxCallback& ssl_ctx);
#endif
void SetOption(const LowSpeed& low_speed);
void SetOption(const VerifySsl& verify);
void SetOption(const Verbose& verbose);
Expand Down Expand Up @@ -254,6 +260,7 @@ class Session : public std::enable_shared_from_this<Session> {
ProgressCallback progresscb_;
DebugCallback debugcb_;
CancellationCallback cancellationcb_;
SslCtxCallback ssl_ctxcb_;
};

std::unique_ptr<Callbacks> cbs_{std::make_unique<Callbacks>()};
Expand Down
1 change: 1 addition & 0 deletions include/cpr/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ int progressUserFunction(const T* progress, cpr_pf_arg_t dltotal, cpr_pf_arg_t d
return (*progress)(dltotal, dlnow, ultotal, ulnow) ? 0 : cancel_retval;
}
int debugUserFunction(CURL* handle, curl_infotype type, char* data, size_t size, const DebugCallback* debug);
CURLcode sslCtxUserFunction(CURL* handle, void* ssl_ctx, const SslCtxCallback* callback);
std::vector<std::string> split(const std::string& to_split, char delimiter);
std::string urlEncode(const std::string& s);
std::string urlDecode(const std::string& s);
Expand Down