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