std::unique_ptr curl_easy::create()

in src/Linux/curl_easy.cpp [73:122]


std::unique_ptr<curl_easy> curl_easy::create(const std::string& url, const std::string* const p_body, unsigned long dwflag)
{
    std::unique_ptr<curl_easy> easy(new curl_easy);

    easy->handle = curl_easy_init();
    if (easy->handle == nullptr)
    {
        // CURL does not document what null actually means other than "it's
        // bad". Assuming OOM.
        throw std::bad_alloc();
    }

    easy->set_opt_or_throw(CURLOPT_URL, url.c_str());
    easy->set_opt_or_throw(CURLOPT_WRITEFUNCTION, &write_callback);
    easy->set_opt_or_throw(CURLOPT_WRITEDATA, easy.get());
    easy->set_opt_or_throw(CURLOPT_HEADERFUNCTION, &header_callback);
    easy->set_opt_or_throw(CURLOPT_HEADERDATA, easy.get());
    easy->set_opt_or_throw(CURLOPT_FAILONERROR, 1L);
    easy->set_opt_or_throw(CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);

    if (p_body != nullptr && !p_body->empty())
    {
        easy->set_opt_or_throw(CURLOPT_CUSTOMREQUEST, "GET");
        easy->set_opt_or_throw(CURLOPT_COPYPOSTFIELDS, p_body->c_str());
    }

#if !defined(__LINUX__)
    // The version of LibCURL we were built with was built with OpenSSL, not WinSSL. As a result, we need to
    // inform LibCURL where to find the trusted list of root CAs. We assume it is in a file named "curl-ca-bundle.crt"
    // in the directory which holds the dcap provider DLL.
    extern HINSTANCE moduleHandle;
    char fileNameBuffer[MAX_PATH];
    if (GetModuleFileNameA(moduleHandle, fileNameBuffer, _countof(fileNameBuffer)) == 0)
    {
        throw std::exception("Unable to retrieve module name.");
    }
    if (!PathRemoveFileSpecA(fileNameBuffer))
    {
        throw std::exception("Unable to remove filename from buffer.");
    }
    if (FAILED(StringCchCatA(fileNameBuffer, _countof(fileNameBuffer), "\\curl-ca-bundle.crt")))
    {
        throw std::exception("Unable to append CA bundle name");
    }

    easy->set_opt_or_throw(CURLOPT_CAINFO, fileNameBuffer);
#endif

    return easy;
}