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_H_ 6 #define LIBBRILLO_BRILLO_HTTP_HTTP_TRANSPORT_H_ 7 8 #include <memory> 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include <base/callback_forward.h> 14 #include <base/files/file_path.h> 15 #include <base/location.h> 16 #include <base/macros.h> 17 #include <base/time/time.h> 18 #include <brillo/brillo_export.h> 19 #include <brillo/errors/error.h> 20 21 namespace brillo { 22 namespace http { 23 24 BRILLO_EXPORT extern const char kErrorDomain[]; 25 // Constant referring to 'direct' proxy which implies no proxy server. 26 BRILLO_EXPORT extern const char kDirectProxy[]; // direct:// 27 28 class Request; 29 class Response; 30 class Connection; 31 32 using RequestID = int; 33 34 using HeaderList = std::vector<std::pair<std::string, std::string>>; 35 using SuccessCallback = 36 base::Callback<void(RequestID, std::unique_ptr<Response>)>; 37 using ErrorCallback = base::Callback<void(RequestID, const brillo::Error*)>; 38 39 /////////////////////////////////////////////////////////////////////////////// 40 // Transport is a base class for specific implementation of HTTP communication. 41 // This class (and its underlying implementation) is used by http::Request and 42 // http::Response classes to provide HTTP functionality to the clients. By 43 // default, this interface will use CA certificates that only allow secure 44 // (HTTPS) communication with Google services. 45 /////////////////////////////////////////////////////////////////////////////// 46 class BRILLO_EXPORT Transport : public std::enable_shared_from_this<Transport> { 47 public: 48 enum class Certificate { 49 // Default certificate; only allows communication with Google services. 50 kDefault, 51 // Certificates for communicating only with production SM-DP+ and SM-DS 52 // servers. 53 kHermesProd, 54 // Certificates for communicating only with test SM-DP+ and SM-DS servers. 55 kHermesTest, 56 // The NSS certificate store, which the curl command-line tool and libcurl 57 // library use by default. This set of certificates does not restrict 58 // secure communication to only Google services. 59 kNss, 60 }; 61 62 Transport() = default; 63 virtual ~Transport() = default; 64 65 // Creates a connection object and initializes it with the specified data. 66 // |transport| is a shared pointer to this transport object instance, 67 // used to maintain the object alive as long as the connection exists. 68 // The |url| here is the full URL specified in the request. It is passed 69 // to the underlying transport (e.g. CURL) to establish the connection. 70 virtual std::shared_ptr<Connection> CreateConnection( 71 const std::string& url, 72 const std::string& method, 73 const HeaderList& headers, 74 const std::string& user_agent, 75 const std::string& referer, 76 brillo::ErrorPtr* error) = 0; 77 78 // Runs |callback| on the task runner (message loop) associated with the 79 // transport. For transports that do not contain references to real message 80 // loops (e.g. a fake transport), calls the callback immediately. 81 virtual void RunCallbackAsync(const base::Location& from_here, 82 const base::Closure& callback) = 0; 83 84 // Initiates an asynchronous transfer on the given |connection|. 85 // The actual implementation of an async I/O is transport-specific. 86 // Returns a request ID which can be used to cancel the request. 87 virtual RequestID StartAsyncTransfer( 88 Connection* connection, 89 const SuccessCallback& success_callback, 90 const ErrorCallback& error_callback) = 0; 91 92 // Cancels a pending asynchronous request. This will cancel a pending request 93 // scheduled by the transport while the I/O operations are still in progress. 94 // As soon as all I/O completes for the request/response, or when an error 95 // occurs, the success/error callbacks are invoked and the request is 96 // considered complete and can no longer be canceled. 97 // Returns false if pending request with |request_id| is not found (e.g. it 98 // has already completed/its callbacks are dispatched). 99 virtual bool CancelRequest(RequestID request_id) = 0; 100 101 // Set the default timeout of requests made. 102 virtual void SetDefaultTimeout(base::TimeDelta timeout) = 0; 103 104 // Set the local IP address of requests 105 virtual void SetLocalIpAddress(const std::string& ip_address) = 0; 106 107 // Use the default CA certificate for certificate verification. This 108 // means that clients are only allowed to communicate with Google services. UseDefaultCertificate()109 virtual void UseDefaultCertificate() {} 110 111 // Set the CA certificate to use for certificate verification. 112 // 113 // This call can allow a client to securly communicate with a different subset 114 // of services than it can otherwise. However, setting a custom certificate 115 // should be done only when necessary, and should be done with careful control 116 // over the certificates that are contained in the relevant path. See 117 // https://chromium.googlesource.com/chromiumos/docs/+/master/ca_certs.md for 118 // more information on certificates in Chrome OS. UseCustomCertificate(Transport::Certificate cert)119 virtual void UseCustomCertificate(Transport::Certificate cert) {} 120 121 // Appends host entry to DNS cache. curl can only do HTTPS request to a custom 122 // IP if it resolves an HTTPS hostname to that IP. This is useful in 123 // forcing a particular mapping for an HTTPS host. See CURLOPT_RESOLVE for 124 // more details. ResolveHostToIp(const std::string & host,uint16_t port,const std::string & ip_address)125 virtual void ResolveHostToIp(const std::string& host, 126 uint16_t port, 127 const std::string& ip_address) {} 128 129 // Creates a default http::Transport (currently, using http::curl::Transport). 130 static std::shared_ptr<Transport> CreateDefault(); 131 132 // Creates a default http::Transport that will utilize the passed in proxy 133 // server (currently, using a http::curl::Transport). |proxy| should be of the 134 // form scheme://[user:pass@]host:port or may be the empty string or the 135 // string kDirectProxy (i.e. direct://) to indicate no proxy. 136 static std::shared_ptr<Transport> CreateDefaultWithProxy( 137 const std::string& proxy); 138 139 protected: 140 // Clears the forced DNS mappings created by ResolveHostToIp. ClearHost()141 virtual void ClearHost() {} 142 143 static base::FilePath CertificateToPath(Certificate cert); 144 145 private: 146 DISALLOW_COPY_AND_ASSIGN(Transport); 147 }; 148 149 } // namespace http 150 } // namespace brillo 151 152 #endif // LIBBRILLO_BRILLO_HTTP_HTTP_TRANSPORT_H_ 153