Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
46 changes: 18 additions & 28 deletions sdk/core/azure-core/src/http/curl/curl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1300,7 +1300,9 @@ std::unique_ptr<CurlNetworkConnection> CurlConnectionPool::ExtractOrCreateCurlCo
// Creating a new connection is thread safe. No need to lock mutex here.
// No available connection for the pool for the required host. Create one
Log::Write(Logger::Level::Verbose, LogMsgPrefix + "Spawn new connection.");
CURL* newHandle = curl_easy_init();

auto newHandle = std::unique_ptr<CURL, CURL_deleter>(curl_easy_init());

if (!newHandle)
{
throw Azure::Core::Http::TransportException(
Expand All @@ -1310,25 +1312,22 @@ std::unique_ptr<CurlNetworkConnection> CurlConnectionPool::ExtractOrCreateCurlCo
CURLcode result;

// Libcurl setup before open connection (url, connect_only, timeout)
if (!SetLibcurlOption(newHandle, CURLOPT_URL, request.GetUrl().GetAbsoluteUrl().data(), &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_URL, request.GetUrl().GetAbsoluteUrl().data(), &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName + ". "
+ std::string(curl_easy_strerror(result)));
}

if (port != 0 && !SetLibcurlOption(newHandle, CURLOPT_PORT, port, &result))
if (port != 0 && !SetLibcurlOption(newHandle.get(), CURLOPT_PORT, port, &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName + ". "
+ std::string(curl_easy_strerror(result)));
}

if (!SetLibcurlOption(newHandle, CURLOPT_CONNECT_ONLY, 1L, &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_CONNECT_ONLY, 1L, &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName + ". "
+ std::string(curl_easy_strerror(result)));
Expand All @@ -1337,19 +1336,18 @@ std::unique_ptr<CurlNetworkConnection> CurlConnectionPool::ExtractOrCreateCurlCo
// Set timeout to 24h. Libcurl will fail uploading on windows if timeout is:
// timeout >= 25 days. Fails as soon as trying to upload any data
// 25 days < timeout > 1 days. Fail on huge uploads ( > 1GB)
if (!SetLibcurlOption(newHandle, CURLOPT_TIMEOUT, 60L * 60L * 24L, &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_TIMEOUT, 60L * 60L * 24L, &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName + ". "
+ std::string(curl_easy_strerror(result)));
}

if (options.ConnectionTimeout != Azure::Core::Http::_detail::DefaultConnectionTimeout)
{
if (!SetLibcurlOption(newHandle, CURLOPT_CONNECTTIMEOUT_MS, options.ConnectionTimeout, &result))
if (!SetLibcurlOption(
newHandle.get(), CURLOPT_CONNECTTIMEOUT_MS, options.ConnectionTimeout, &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName
+ ". Fail setting connect timeout to: "
Expand All @@ -1363,9 +1361,8 @@ std::unique_ptr<CurlNetworkConnection> CurlConnectionPool::ExtractOrCreateCurlCo
*/
if (options.Proxy)
{
if (!SetLibcurlOption(newHandle, CURLOPT_PROXY, options.Proxy->c_str(), &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_PROXY, options.Proxy->c_str(), &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName
+ ". Failed to set proxy to:" + options.Proxy.Value() + ". "
Expand All @@ -1375,9 +1372,8 @@ std::unique_ptr<CurlNetworkConnection> CurlConnectionPool::ExtractOrCreateCurlCo

if (!options.CAInfo.empty())
{
if (!SetLibcurlOption(newHandle, CURLOPT_CAINFO, options.CAInfo.c_str(), &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_CAINFO, options.CAInfo.c_str(), &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName
+ ". Failed to set CA cert to:" + options.CAInfo + ". "
Expand All @@ -1391,9 +1387,8 @@ std::unique_ptr<CurlNetworkConnection> CurlConnectionPool::ExtractOrCreateCurlCo
sslOption |= CURLSSLOPT_NO_REVOKE;
}

if (!SetLibcurlOption(newHandle, CURLOPT_SSL_OPTIONS, sslOption, &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_SSL_OPTIONS, sslOption, &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName
+ ". Failed to set ssl options to long bitmask:" + std::to_string(sslOption) + ". "
Expand All @@ -1402,9 +1397,8 @@ std::unique_ptr<CurlNetworkConnection> CurlConnectionPool::ExtractOrCreateCurlCo

if (!options.SslVerifyPeer)
{
if (!SetLibcurlOption(newHandle, CURLOPT_SSL_VERIFYPEER, 0L, &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_SSL_VERIFYPEER, 0L, &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName
+ ". Failed to disable ssl verify peer. " + std::string(curl_easy_strerror(result)));
Expand All @@ -1413,9 +1407,8 @@ std::unique_ptr<CurlNetworkConnection> CurlConnectionPool::ExtractOrCreateCurlCo

if (options.NoSignal)
{
if (!SetLibcurlOption(newHandle, CURLOPT_NOSIGNAL, 1L, &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_NOSIGNAL, 1L, &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName
+ ". Failed to set NOSIGNAL option for libcurl. "
Expand All @@ -1426,33 +1419,30 @@ std::unique_ptr<CurlNetworkConnection> CurlConnectionPool::ExtractOrCreateCurlCo
// curl-transport adapter supports only HTTP/1.1
// https://github.com/Azure/azure-sdk-for-cpp/issues/2848
// The libcurl uses HTTP/2 by default, if it can be negotiated with a server on handshake.
if (!SetLibcurlOption(newHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1, &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1, &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName
+ ". Failed to set libcurl HTTP/1.1" + ". " + std::string(curl_easy_strerror(result)));
}

// Make libcurl to support only TLS v1.2 or later
if (!SetLibcurlOption(newHandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2, &result))
if (!SetLibcurlOption(newHandle.get(), CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2, &result))
{
curl_easy_cleanup(newHandle);
throw Azure::Core::Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName
+ ". Failed enforcing TLS v1.2 or greater. " + std::string(curl_easy_strerror(result)));
}

auto performResult = curl_easy_perform(newHandle);
auto performResult = curl_easy_perform(newHandle.get());
if (performResult != CURLE_OK)
{
curl_easy_cleanup(newHandle);
throw Http::TransportException(
_detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName + ". "
+ std::string(curl_easy_strerror(performResult)));
}

return std::make_unique<CurlConnection>(newHandle, connectionKey);
Comment thread
gearama marked this conversation as resolved.
return std::make_unique<CurlConnection>(newHandle.release(), connectionKey);
}

// Move the connection back to the connection pool. Push it to the front so it becomes the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,18 @@ namespace Azure { namespace Core { namespace Http { namespace _detail {
std::thread m_cleanThread;
};

/**
* @brief std::default_delete for the CURL * type , used for std::unique_ptr
*
*/
class CURL_deleter {
public:
void operator()(CURL* handle) noexcept
{
if (handle != nullptr)
{
curl_easy_cleanup(handle);
}
}
};
}}}} // namespace Azure::Core::Http::_detail
6 changes: 0 additions & 6 deletions sdk/core/azure-core/src/http/curl/curl_connection_private.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,6 @@ namespace Azure { namespace Core { namespace Http {
}
}

/**
* @brief Gets the connection handle
*
*/
CURL* GetHandle() { return m_handle; }

/**
* @brief Destructor.
* @details Cleans up CURL (invokes `curl_easy_cleanup()`).
Expand Down