7 #include "packager/media/base/http_key_fetcher.h"
10 #include "packager/base/strings/stringprintf.h"
11 #include "packager/base/synchronization/lock.h"
13 namespace edash_packager {
16 const char kUserAgentString[] =
"edash-packager-http_fetcher/1.0";
21 ScopedCurl() { ptr_ = curl_easy_init(); }
24 curl_easy_cleanup(ptr_);
27 CURL*
get() {
return ptr_; }
31 DISALLOW_COPY_AND_ASSIGN(ScopedCurl);
34 size_t AppendToString(
char* ptr,
size_t size,
size_t nmemb, std::string* response) {
37 const size_t total_size = size * nmemb;
38 response->append(ptr, total_size);
42 class LibCurlInitializer {
44 LibCurlInitializer() : initialized_(false) {
45 base::AutoLock lock(lock_);
47 curl_global_init(CURL_GLOBAL_DEFAULT);
52 ~LibCurlInitializer() {
53 base::AutoLock lock(lock_);
55 curl_global_cleanup();
64 DISALLOW_COPY_AND_ASSIGN(LibCurlInitializer);
74 : timeout_in_seconds_(timeout_in_seconds) {}
76 HttpKeyFetcher::~HttpKeyFetcher() {}
79 const std::string& request,
80 std::string* response) {
81 return Post(url, request, response);
85 return FetchInternal(GET, path,
"", response);
89 const std::string& data,
90 std::string* response) {
91 return FetchInternal(POST, path, data, response);
94 Status HttpKeyFetcher::FetchInternal(HttpMethod method,
95 const std::string& path,
96 const std::string& data,
97 std::string* response) {
98 DCHECK(method == GET || method == POST);
100 static LibCurlInitializer lib_curl_initializer;
102 ScopedCurl scoped_curl;
103 CURL* curl = scoped_curl.get();
105 LOG(ERROR) <<
"curl_easy_init() failed.";
106 return Status(error::HTTP_FAILURE,
"curl_easy_init() failed.");
110 curl_easy_setopt(curl, CURLOPT_URL, path.c_str());
111 curl_easy_setopt(curl, CURLOPT_USERAGENT, kUserAgentString);
112 curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout_in_seconds_);
113 curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
114 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
115 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, AppendToString);
116 curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
117 if (method == POST) {
118 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
119 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.size());
122 CURLcode res = curl_easy_perform(curl);
123 if (res != CURLE_OK) {
124 std::string error_message = base::StringPrintf(
125 "curl_easy_perform() failed: %s.", curl_easy_strerror(res));
126 if (res == CURLE_HTTP_RETURNED_ERROR) {
127 long response_code = 0;
128 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
129 error_message += base::StringPrintf(
" Response code: %ld.", response_code);
132 LOG(ERROR) << error_message;
134 res == CURLE_OPERATION_TIMEDOUT ? error::TIME_OUT : error::HTTP_FAILURE,