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 tracked_objects::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 // Helper methods to convert CURL error codes (CURLcode and CURLMcode) 63 // into brillo::Error object. 64 static void AddEasyCurlError(brillo::ErrorPtr* error, 65 const tracked_objects::Location& location, 66 CURLcode code, 67 CurlInterface* curl_interface); 68 69 static void AddMultiCurlError(brillo::ErrorPtr* error, 70 const tracked_objects::Location& location, 71 CURLMcode code, 72 CurlInterface* curl_interface); 73 74 private: 75 // Forward-declaration of internal implementation structures. 76 struct AsyncRequestData; 77 class SocketPollData; 78 79 // Initializes CURL for async operation. 80 bool SetupAsyncCurl(brillo::ErrorPtr* error); 81 82 // Stops CURL's async operations. 83 void ShutDownAsyncCurl(); 84 85 // Handles all pending async messages from CURL. 86 void ProcessAsyncCurlMessages(); 87 88 // Processes the transfer completion message (success or failure). 89 void OnTransferComplete(http::curl::Connection* connection, 90 CURLcode code); 91 92 // Cleans up internal data for a completed/canceled asynchronous operation 93 // on a connection. 94 void CleanAsyncConnection(http::curl::Connection* connection); 95 96 // Called after a timeout delay requested by CURL has elapsed. 97 void OnTimer(); 98 99 // Callback for CURL to handle curl_socket_callback() notifications. 100 // The parameters correspond to those of curl_socket_callback(). 101 static int MultiSocketCallback(CURL* easy, 102 curl_socket_t s, 103 int what, 104 void* userp, 105 void* socketp); 106 107 // Callback for CURL to handle curl_multi_timer_callback() notifications. 108 // The parameters correspond to those of curl_multi_timer_callback(). 109 // CURL actually uses "long" types in callback signatures, so we must comply. 110 static int MultiTimerCallback(CURLM* multi, 111 long timeout_ms, // NOLINT(runtime/int) 112 void* userp); 113 114 std::shared_ptr<CurlInterface> curl_interface_; 115 std::string proxy_; 116 // CURL "multi"-handle for processing requests on multiple connections. 117 CURLM* curl_multi_handle_{nullptr}; 118 // A map to find a corresponding Connection* using a request ID. 119 std::map<RequestID, Connection*> request_id_map_; 120 // Stores the connection-specific asynchronous data (such as the success 121 // and error callbacks that need to be called at the end of the async 122 // operation). 123 std::map<Connection*, std::unique_ptr<AsyncRequestData>> async_requests_; 124 // Internal data associated with in-progress asynchronous operations. 125 std::map<std::pair<CURL*, curl_socket_t>, SocketPollData*> poll_data_map_; 126 // The last request ID used for asynchronous operations. 127 RequestID last_request_id_{0}; 128 // The connection timeout for the requests made. 129 base::TimeDelta connection_timeout_; 130 131 base::WeakPtrFactory<Transport> weak_ptr_factory_for_timer_{this}; 132 base::WeakPtrFactory<Transport> weak_ptr_factory_{this}; 133 DISALLOW_COPY_AND_ASSIGN(Transport); 134 }; 135 136 } // namespace curl 137 } // namespace http 138 } // namespace brillo 139 140 #endif // LIBBRILLO_BRILLO_HTTP_HTTP_TRANSPORT_CURL_H_ 141