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 #ifndef LIBBRILLO_BRILLO_HTTP_HTTP_TRANSPORT_CURL_H_ 6 #define LIBBRILLO_BRILLO_HTTP_HTTP_TRANSPORT_CURL_H_ 7 8 #include <map> 9 #include <memory> 10 #include <string> 11 #include <utility> 12 13 #include <base/location.h> 14 #include <base/memory/weak_ptr.h> 15 #include <brillo/brillo_export.h> 16 #include <brillo/http/curl_api.h> 17 #include <brillo/http/http_transport.h> 18 19 namespace brillo { 20 namespace http { 21 namespace curl { 22 23 class Connection; 24 25 /////////////////////////////////////////////////////////////////////////////// 26 // An implementation of http::Transport that uses libcurl for 27 // HTTP communications. This class (as http::Transport base) 28 // is used by http::Request and http::Response classes to provide HTTP 29 // functionality to the clients. 30 // See http_transport.h for more details. 31 /////////////////////////////////////////////////////////////////////////////// 32 class BRILLO_EXPORT Transport : public http::Transport { 33 public: 34 // Constructs the transport using the current message loop for async 35 // operations. 36 explicit Transport(const std::shared_ptr<CurlInterface>& curl_interface); 37 // Creates a transport object using a proxy. 38 // |proxy| is of the form [protocol://][user:password@]host[:port]. 39 // If not defined, protocol is assumed to be http://. 40 Transport(const std::shared_ptr<CurlInterface>& curl_interface, 41 const std::string& proxy); 42 ~Transport() override; 43 44 // Overrides from http::Transport. 45 std::shared_ptr<http::Connection> CreateConnection( 46 const std::string& url, 47 const std::string& method, 48 const HeaderList& headers, 49 const std::string& user_agent, 50 const std::string& referer, 51 brillo::ErrorPtr* error) override; 52 53 void RunCallbackAsync(const base::Location& from_here, 54 const base::Closure& callback) override; 55 56 RequestID StartAsyncTransfer(http::Connection* connection, 57 const SuccessCallback& success_callback, 58 const ErrorCallback& error_callback) override; 59 60 bool CancelRequest(RequestID request_id) override; 61 62 void SetDefaultTimeout(base::TimeDelta timeout) override; 63 64 void SetLocalIpAddress(const std::string& ip_address) override; 65 66 void UseDefaultCertificate() override; 67 68 void UseCustomCertificate(Certificate cert) override; 69 70 void ResolveHostToIp(const std::string& host, 71 uint16_t port, 72 const std::string& ip_address) override; 73 74 // Helper methods to convert CURL error codes (CURLcode and CURLMcode) 75 // into brillo::Error object. 76 static void AddEasyCurlError(brillo::ErrorPtr* error, 77 const base::Location& location, 78 CURLcode code, 79 CurlInterface* curl_interface); 80 81 static void AddMultiCurlError(brillo::ErrorPtr* error, 82 const base::Location& location, 83 CURLMcode code, 84 CurlInterface* curl_interface); 85 86 protected: 87 void ClearHost() override; 88 89 private: 90 // Forward-declaration of internal implementation structures. 91 struct AsyncRequestData; 92 class SocketPollData; 93 94 // Initializes CURL for async operation. 95 bool SetupAsyncCurl(brillo::ErrorPtr* error); 96 97 // Stops CURL's async operations. 98 void ShutDownAsyncCurl(); 99 100 // Handles all pending async messages from CURL. 101 void ProcessAsyncCurlMessages(); 102 103 // Processes the transfer completion message (success or failure). 104 void OnTransferComplete(http::curl::Connection* connection, 105 CURLcode code); 106 107 // Cleans up internal data for a completed/canceled asynchronous operation 108 // on a connection. 109 void CleanAsyncConnection(http::curl::Connection* connection); 110 111 // Called after a timeout delay requested by CURL has elapsed. 112 void OnTimer(); 113 114 // Callback for CURL to handle curl_socket_callback() notifications. 115 // The parameters correspond to those of curl_socket_callback(). 116 static int MultiSocketCallback(CURL* easy, 117 curl_socket_t s, 118 int what, 119 void* userp, 120 void* socketp); 121 122 // Callback for CURL to handle curl_multi_timer_callback() notifications. 123 // The parameters correspond to those of curl_multi_timer_callback(). 124 // CURL actually uses "long" types in callback signatures, so we must comply. 125 static int MultiTimerCallback(CURLM* multi, 126 long timeout_ms, // NOLINT(runtime/int) 127 void* userp); 128 129 std::shared_ptr<CurlInterface> curl_interface_; 130 std::string proxy_; 131 // CURL "multi"-handle for processing requests on multiple connections. 132 CURLM* curl_multi_handle_{nullptr}; 133 // A map to find a corresponding Connection* using a request ID. 134 std::map<RequestID, Connection*> request_id_map_; 135 // Stores the connection-specific asynchronous data (such as the success 136 // and error callbacks that need to be called at the end of the async 137 // operation). 138 std::map<Connection*, std::unique_ptr<AsyncRequestData>> async_requests_; 139 // Internal data associated with in-progress asynchronous operations. 140 std::map<std::pair<CURL*, curl_socket_t>, SocketPollData*> poll_data_map_; 141 // The last request ID used for asynchronous operations. 142 RequestID last_request_id_{0}; 143 // The connection timeout for the requests made. 144 base::TimeDelta connection_timeout_; 145 std::string ip_address_; 146 base::FilePath certificate_path_; 147 curl_slist* host_list_{nullptr}; 148 149 base::WeakPtrFactory<Transport> weak_ptr_factory_for_timer_{this}; 150 base::WeakPtrFactory<Transport> weak_ptr_factory_{this}; 151 DISALLOW_COPY_AND_ASSIGN(Transport); 152 }; 153 154 } // namespace curl 155 } // namespace http 156 } // namespace brillo 157 158 #endif // LIBBRILLO_BRILLO_HTTP_HTTP_TRANSPORT_CURL_H_ 159