7 #include "packager/media/base/http_key_fetcher.h"
11 #include "packager/base/logging.h"
12 #include "packager/base/strings/stringprintf.h"
13 #include "packager/base/synchronization/lock.h"
18 const char kUserAgentString[] =
"shaka-packager-http_fetcher/1.0";
23 ScopedCurl() { ptr_ = curl_easy_init(); }
26 curl_easy_cleanup(ptr_);
29 CURL*
get() {
return ptr_; }
33 DISALLOW_COPY_AND_ASSIGN(ScopedCurl);
36 size_t AppendToString(
char* ptr,
size_t size,
size_t nmemb, std::string* response) {
39 const size_t total_size = size * nmemb;
40 response->append(ptr, total_size);
44 class LibCurlInitializer {
46 LibCurlInitializer() : initialized_(false) {
47 base::AutoLock lock(lock_);
49 curl_global_init(CURL_GLOBAL_DEFAULT);
54 ~LibCurlInitializer() {
55 base::AutoLock lock(lock_);
57 curl_global_cleanup();
66 DISALLOW_COPY_AND_ASSIGN(LibCurlInitializer);
76 : timeout_in_seconds_(timeout_in_seconds) {}
78 HttpKeyFetcher::~HttpKeyFetcher() {}
81 const std::string& request,
82 std::string* response) {
83 return Post(url, request, response);
87 return FetchInternal(GET, path,
"", response);
91 const std::string& data,
92 std::string* response) {
93 return FetchInternal(POST, path, data, response);
96 Status HttpKeyFetcher::FetchInternal(HttpMethod method,
97 const std::string& path,
98 const std::string& data,
99 std::string* response) {
100 DCHECK(method == GET || method == POST);
102 static LibCurlInitializer lib_curl_initializer;
104 ScopedCurl scoped_curl;
105 CURL* curl = scoped_curl.get();
107 LOG(ERROR) <<
"curl_easy_init() failed.";
108 return Status(error::HTTP_FAILURE,
"curl_easy_init() failed.");
112 curl_easy_setopt(curl, CURLOPT_URL, path.c_str());
113 curl_easy_setopt(curl, CURLOPT_USERAGENT, kUserAgentString);
114 curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout_in_seconds_);
115 curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
116 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
117 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, AppendToString);
118 curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
119 if (method == POST) {
120 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
121 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.size());
124 CURLcode res = curl_easy_perform(curl);
125 if (res != CURLE_OK) {
126 std::string error_message = base::StringPrintf(
127 "curl_easy_perform() failed: %s.", curl_easy_strerror(res));
128 if (res == CURLE_HTTP_RETURNED_ERROR) {
129 long response_code = 0;
130 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
131 error_message += base::StringPrintf(
" Response code: %ld.", response_code);
134 LOG(ERROR) << error_message;
136 res == CURLE_OPERATION_TIMEDOUT ? error::TIME_OUT : error::HTTP_FAILURE,