You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
6.6 KiB
198 lines
6.6 KiB
// Copyright 2014 The Chromium OS Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include <brillo/http/curl_api.h>
|
|
|
|
#include <base/logging.h>
|
|
|
|
namespace brillo {
|
|
namespace http {
|
|
|
|
namespace {
|
|
|
|
static_assert(CURLOPTTYPE_LONG == 0 &&
|
|
CURLOPTTYPE_OBJECTPOINT == 10000 &&
|
|
CURLOPTTYPE_FUNCTIONPOINT == 20000 &&
|
|
CURLOPTTYPE_OFF_T == 30000,
|
|
"CURL option types are expected to be multiples of 10000");
|
|
|
|
inline bool VerifyOptionType(CURLoption option, int expected_type) {
|
|
int option_type = (static_cast<int>(option) / 10000) * 10000;
|
|
return (option_type == expected_type);
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
CurlApi::CurlApi() {
|
|
curl_global_init(CURL_GLOBAL_ALL);
|
|
}
|
|
|
|
CurlApi::~CurlApi() {
|
|
curl_global_cleanup();
|
|
}
|
|
|
|
CURL* CurlApi::EasyInit() {
|
|
return curl_easy_init();
|
|
}
|
|
|
|
void CurlApi::EasyCleanup(CURL* curl) {
|
|
curl_easy_cleanup(curl);
|
|
}
|
|
|
|
CURLcode CurlApi::EasySetOptInt(CURL* curl, CURLoption option, int value) {
|
|
CHECK(VerifyOptionType(option, CURLOPTTYPE_LONG))
|
|
<< "Only options that expect a LONG data type must be specified here";
|
|
// CURL actually uses "long" type, so have to make sure we feed it what it
|
|
// expects.
|
|
// NOLINTNEXTLINE(runtime/int)
|
|
return curl_easy_setopt(curl, option, static_cast<long>(value));
|
|
}
|
|
|
|
CURLcode CurlApi::EasySetOptStr(CURL* curl,
|
|
CURLoption option,
|
|
const std::string& value) {
|
|
CHECK(VerifyOptionType(option, CURLOPTTYPE_OBJECTPOINT))
|
|
<< "Only options that expect a STRING data type must be specified here";
|
|
return curl_easy_setopt(curl, option, value.c_str());
|
|
}
|
|
|
|
CURLcode CurlApi::EasySetOptPtr(CURL* curl, CURLoption option, void* value) {
|
|
CHECK(VerifyOptionType(option, CURLOPTTYPE_OBJECTPOINT))
|
|
<< "Only options that expect a pointer data type must be specified here";
|
|
return curl_easy_setopt(curl, option, value);
|
|
}
|
|
|
|
CURLcode CurlApi::EasySetOptCallback(CURL* curl,
|
|
CURLoption option,
|
|
intptr_t address) {
|
|
CHECK(VerifyOptionType(option, CURLOPTTYPE_FUNCTIONPOINT))
|
|
<< "Only options that expect a function pointers must be specified here";
|
|
return curl_easy_setopt(curl, option, address);
|
|
}
|
|
|
|
CURLcode CurlApi::EasySetOptOffT(CURL* curl,
|
|
CURLoption option,
|
|
curl_off_t value) {
|
|
CHECK(VerifyOptionType(option, CURLOPTTYPE_OFF_T))
|
|
<< "Only options that expect a large data size must be specified here";
|
|
return curl_easy_setopt(curl, option, value);
|
|
}
|
|
|
|
CURLcode CurlApi::EasyPerform(CURL* curl) {
|
|
return curl_easy_perform(curl);
|
|
}
|
|
|
|
CURLcode CurlApi::EasyGetInfoInt(CURL* curl, CURLINFO info, int* value) const {
|
|
CHECK_EQ(CURLINFO_LONG, info & CURLINFO_TYPEMASK) << "Wrong option type";
|
|
long data = 0; // NOLINT(runtime/int) - curl expects a long here.
|
|
CURLcode code = curl_easy_getinfo(curl, info, &data);
|
|
if (code == CURLE_OK)
|
|
*value = static_cast<int>(data);
|
|
return code;
|
|
}
|
|
|
|
CURLcode CurlApi::EasyGetInfoDbl(CURL* curl,
|
|
CURLINFO info,
|
|
double* value) const {
|
|
CHECK_EQ(CURLINFO_DOUBLE, info & CURLINFO_TYPEMASK) << "Wrong option type";
|
|
return curl_easy_getinfo(curl, info, value);
|
|
}
|
|
|
|
CURLcode CurlApi::EasyGetInfoStr(CURL* curl,
|
|
CURLINFO info,
|
|
std::string* value) const {
|
|
CHECK_EQ(CURLINFO_STRING, info & CURLINFO_TYPEMASK) << "Wrong option type";
|
|
char* data = nullptr;
|
|
CURLcode code = curl_easy_getinfo(curl, info, &data);
|
|
if (code == CURLE_OK)
|
|
*value = data;
|
|
return code;
|
|
}
|
|
|
|
CURLcode CurlApi::EasyGetInfoPtr(CURL* curl,
|
|
CURLINFO info,
|
|
void** value) const {
|
|
// CURL uses "string" type for generic pointer info. Go figure.
|
|
CHECK_EQ(CURLINFO_STRING, info & CURLINFO_TYPEMASK) << "Wrong option type";
|
|
return curl_easy_getinfo(curl, info, value);
|
|
}
|
|
|
|
std::string CurlApi::EasyStrError(CURLcode code) const {
|
|
return curl_easy_strerror(code);
|
|
}
|
|
|
|
CURLM* CurlApi::MultiInit() {
|
|
return curl_multi_init();
|
|
}
|
|
|
|
CURLMcode CurlApi::MultiCleanup(CURLM* multi_handle) {
|
|
return curl_multi_cleanup(multi_handle);
|
|
}
|
|
|
|
CURLMsg* CurlApi::MultiInfoRead(CURLM* multi_handle, int* msgs_in_queue) {
|
|
return curl_multi_info_read(multi_handle, msgs_in_queue);
|
|
}
|
|
|
|
CURLMcode CurlApi::MultiAddHandle(CURLM* multi_handle, CURL* curl_handle) {
|
|
return curl_multi_add_handle(multi_handle, curl_handle);
|
|
}
|
|
|
|
CURLMcode CurlApi::MultiRemoveHandle(CURLM* multi_handle, CURL* curl_handle) {
|
|
return curl_multi_remove_handle(multi_handle, curl_handle);
|
|
}
|
|
|
|
CURLMcode CurlApi::MultiSetSocketCallback(CURLM* multi_handle,
|
|
curl_socket_callback socket_callback,
|
|
void* userp) {
|
|
CURLMcode code =
|
|
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETFUNCTION, socket_callback);
|
|
if (code != CURLM_OK)
|
|
return code;
|
|
return curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, userp);
|
|
}
|
|
|
|
CURLMcode CurlApi::MultiSetTimerCallback(
|
|
CURLM* multi_handle,
|
|
curl_multi_timer_callback timer_callback,
|
|
void* userp) {
|
|
CURLMcode code =
|
|
curl_multi_setopt(multi_handle, CURLMOPT_TIMERFUNCTION, timer_callback);
|
|
if (code != CURLM_OK)
|
|
return code;
|
|
return curl_multi_setopt(multi_handle, CURLMOPT_TIMERDATA, userp);
|
|
}
|
|
|
|
CURLMcode CurlApi::MultiAssign(CURLM* multi_handle,
|
|
curl_socket_t sockfd,
|
|
void* sockp) {
|
|
return curl_multi_assign(multi_handle, sockfd, sockp);
|
|
}
|
|
|
|
CURLMcode CurlApi::MultiSocketAction(CURLM* multi_handle,
|
|
curl_socket_t s,
|
|
int ev_bitmask,
|
|
int* running_handles) {
|
|
return curl_multi_socket_action(multi_handle, s, ev_bitmask, running_handles);
|
|
}
|
|
|
|
std::string CurlApi::MultiStrError(CURLMcode code) const {
|
|
return curl_multi_strerror(code);
|
|
}
|
|
|
|
CURLMcode CurlApi::MultiPerform(CURLM* multi_handle, int* running_handles) {
|
|
return curl_multi_perform(multi_handle, running_handles);
|
|
}
|
|
|
|
CURLMcode CurlApi::MultiWait(CURLM* multi_handle,
|
|
curl_waitfd extra_fds[],
|
|
unsigned int extra_nfds,
|
|
int timeout_ms,
|
|
int* numfds) {
|
|
return curl_multi_wait(multi_handle, extra_fds, extra_nfds, timeout_ms,
|
|
numfds);
|
|
}
|
|
|
|
} // namespace http
|
|
} // namespace brillo
|