Skip to content

Commit 7c4b8ca

Browse files
authored
fix(common): better defaults for curl initialization (#9798)
By default, initialize libcurl with locking and signal handlers that work for most applications. In particular, leaving the default handler for `SIGPIPE` usually results in the application crashes when a socket is closed.
1 parent b1cdd05 commit 7c4b8ca

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

google/cloud/internal/curl_wrappers.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,16 @@ std::string DebugOutData(char const* data, std::size_t size) {
298298
" data=", CleanupDebugData(data, size), "\n");
299299
}
300300

301+
Options CurlInitializeOptions(Options options) {
302+
return google::cloud::internal::MergeOptions(
303+
std::move(options), Options{}
304+
.set<EnableCurlSigpipeHandlerOption>(true)
305+
.set<EnableCurlSslLockingOption>(true));
306+
}
307+
301308
void CurlInitializeOnce(Options const& options) {
302309
static CurlInitializer curl_initializer;
303-
static bool const kInitialized = [&options]() {
310+
static bool const kInitialized = [](Options const& options) {
304311
// The Google Cloud Storage C++ client library depends on libcurl, which
305312
// can use different SSL libraries. Depending on the SSL implementation,
306313
// we need to take action to be thread-safe. More details can be found here:
@@ -324,7 +331,7 @@ void CurlInitializeOnce(Options const& options) {
324331
//
325332
InitializeSigPipeHandler(options.get<EnableCurlSigpipeHandlerOption>());
326333
return true;
327-
}();
334+
}(CurlInitializeOptions(options));
328335
static_cast<void>(kInitialized);
329336
}
330337

google/cloud/internal/curl_wrappers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ using CurlShare = std::unique_ptr<CURLSH, decltype(&curl_share_cleanup)>;
6161
/// Returns true if the SSL locking callbacks are installed.
6262
bool SslLockingCallbacksInstalled();
6363

64+
/// Return the default global options
65+
Options CurlInitializeOptions(Options options);
66+
6467
/// Initializes (if needed) the SSL locking callbacks.
6568
void CurlInitializeOnce(Options const& options);
6669

google/cloud/internal/curl_wrappers_test.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
#include "google/cloud/internal/curl_wrappers.h"
16+
#include "google/cloud/internal/curl_options.h"
1617
#include <gmock/gmock.h>
1718

1819
namespace google {
@@ -128,6 +129,22 @@ header2: value2
128129
}
129130
}
130131

132+
TEST(CurlWrappers, CurlInitializeOptions) {
133+
auto defaults = CurlInitializeOptions({});
134+
EXPECT_TRUE(defaults.get<EnableCurlSslLockingOption>());
135+
EXPECT_TRUE(defaults.get<EnableCurlSigpipeHandlerOption>());
136+
137+
auto override1 =
138+
CurlInitializeOptions(Options{}.set<EnableCurlSslLockingOption>(false));
139+
EXPECT_FALSE(override1.get<EnableCurlSslLockingOption>());
140+
EXPECT_TRUE(override1.get<EnableCurlSigpipeHandlerOption>());
141+
142+
auto override2 = CurlInitializeOptions(
143+
Options{}.set<EnableCurlSigpipeHandlerOption>(false));
144+
EXPECT_TRUE(override2.get<EnableCurlSslLockingOption>());
145+
EXPECT_FALSE(override2.get<EnableCurlSigpipeHandlerOption>());
146+
}
147+
131148
} // namespace
132149
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
133150
} // namespace rest_internal

0 commit comments

Comments
 (0)