diff --git a/maxutils/maxbase/include/maxbase/http.hh b/maxutils/maxbase/include/maxbase/http.hh index 1eb69c3d6..f8f031869 100644 --- a/maxutils/maxbase/include/maxbase/http.hh +++ b/maxutils/maxbase/include/maxbase/http.hh @@ -24,6 +24,37 @@ namespace maxbase namespace http { +/** + * Initialize the http library. + * + * @return True if successful, false otherwise. + */ +bool init(); + +/** + * Finalize the http library. + */ +void finish(); + +/** + * RAII class for initializing the http functionality. + */ +class Init +{ +public: + Init() + { + if (!mxb::http::init()) + { + throw std::runtime_error("Could not initialize mxb::http."); + } + } + ~Init() + { + mxb::http::finish(); + } +}; + enum { DEFAULT_CONNECT_TIMEOUT = 10, // @see https://curl.haxx.se/libcurl/c/CURLOPT_CONNECTTIMEOUT.html diff --git a/maxutils/maxbase/src/http.cc b/maxutils/maxbase/src/http.cc index 96871758d..b27dfdfa4 100644 --- a/maxutils/maxbase/src/http.cc +++ b/maxutils/maxbase/src/http.cc @@ -33,6 +33,14 @@ using std::vector; namespace { +static struct THIS_UNIT +{ + int nInits; +} this_unit = +{ + 0 +}; + using namespace mxb; using namespace mxb::http; @@ -421,6 +429,38 @@ namespace maxbase namespace http { +bool init() +{ + bool rv = true; + + if (this_unit.nInits == 0) + { + CURLcode code = curl_global_init(CURL_GLOBAL_ALL); + + if (code == CURLE_OK) + { + this_unit.nInits = 1; + } + else + { + MXB_ERROR("Failed to initialize CURL library: %s", curl_easy_strerror(code)); + rv = false; + } + } + + return rv; +} + +void finish() +{ + mxb_assert(this_unit.nInits > 0); + + if (--this_unit.nInits == 0) + { + curl_global_cleanup(); + } +} + Async::Imp::~Imp() { } diff --git a/maxutils/maxbase/src/test/test_http.cc b/maxutils/maxbase/src/test/test_http.cc index 3b0110ae3..7795075a3 100644 --- a/maxutils/maxbase/src/test/test_http.cc +++ b/maxutils/maxbase/src/test/test_http.cc @@ -160,6 +160,8 @@ int main() long start; long stop; + mxb::http::Init init; + start = time_since_epoch_ms(); rv += test_http(); stop = time_since_epoch_ms();