Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 1 | // Copyright 2014 The Chromium OS Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "buffet/http_transport_curl.h" |
| 6 | |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 7 | #include <base/logging.h> |
| 8 | |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 9 | #include "buffet/http_connection_curl.h" |
| 10 | #include "buffet/http_request.h" |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 11 | |
Alex Vakulenko | af23b32 | 2014-05-08 16:25:45 -0700 | [diff] [blame] | 12 | namespace buffet { |
| 13 | namespace http { |
| 14 | namespace curl { |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 15 | |
Alex Vakulenko | af23b32 | 2014-05-08 16:25:45 -0700 | [diff] [blame] | 16 | const char kErrorDomain[] = "http_transport"; |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 17 | |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 18 | Transport::Transport() { |
| 19 | VLOG(1) << "curl::Transport created"; |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 20 | } |
| 21 | |
| 22 | Transport::~Transport() { |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 23 | VLOG(1) << "curl::Transport destroyed"; |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 24 | } |
| 25 | |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 26 | std::unique_ptr<http::Connection> Transport::CreateConnection( |
| 27 | std::shared_ptr<http::Transport> transport, |
| 28 | const std::string& url, |
| 29 | const std::string& method, |
| 30 | const HeaderList& headers, |
| 31 | const std::string& user_agent, |
| 32 | const std::string& referer, |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 33 | ErrorPtr* error) { |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 34 | CURL* curl_handle = curl_easy_init(); |
| 35 | if (!curl_handle) { |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 36 | LOG(ERROR) << "Failed to initialize CURL"; |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 37 | Error::AddTo(error, http::curl::kErrorDomain, "curl_init_failed", |
| 38 | "Failed to initialize CURL"); |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 39 | return std::unique_ptr<http::Connection>(); |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 40 | } |
| 41 | |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 42 | LOG(INFO) << "Sending a " << method << " request to " << url; |
| 43 | curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str()); |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 44 | |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 45 | if (!user_agent.empty()) { |
| 46 | curl_easy_setopt(curl_handle, |
| 47 | CURLOPT_USERAGENT, user_agent.c_str()); |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 48 | } |
| 49 | |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 50 | if (!referer.empty()) { |
| 51 | curl_easy_setopt(curl_handle, |
| 52 | CURLOPT_REFERER, referer.c_str()); |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | // Setup HTTP request method and optional request body. |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 56 | if (method == request_type::kGet) { |
| 57 | curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1L); |
| 58 | } else if (method == request_type::kHead) { |
| 59 | curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L); |
| 60 | } else if (method == request_type::kPut) { |
| 61 | curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1L); |
Alex Vakulenko | b645cc9 | 2014-04-15 11:34:35 -0700 | [diff] [blame] | 62 | } else { |
| 63 | // POST and custom request methods |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 64 | curl_easy_setopt(curl_handle, CURLOPT_POST, 1L); |
| 65 | curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, nullptr); |
| 66 | if (method != request_type::kPost) |
| 67 | curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, method.c_str()); |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 68 | } |
| 69 | |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 70 | std::unique_ptr<http::Connection> connection( |
| 71 | new http::curl::Connection(curl_handle, method, transport)); |
| 72 | CHECK(connection) << "Unable to create Connection object"; |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 73 | if (!connection->SendHeaders(headers, error)) { |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 74 | connection.reset(); |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 75 | } |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 76 | return connection; |
Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 77 | } |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 78 | |
Alex Vakulenko | af23b32 | 2014-05-08 16:25:45 -0700 | [diff] [blame] | 79 | } // namespace curl |
| 80 | } // namespace http |
| 81 | } // namespace buffet |