Home | History | Annotate | Download | only in http
      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