1*5a923131SAndroid Build Coastguard Worker // 2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2009 The Android Open Source Project 3*5a923131SAndroid Build Coastguard Worker // 4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at 7*5a923131SAndroid Build Coastguard Worker // 8*5a923131SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 9*5a923131SAndroid Build Coastguard Worker // 10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 14*5a923131SAndroid Build Coastguard Worker // limitations under the License. 15*5a923131SAndroid Build Coastguard Worker // 16*5a923131SAndroid Build Coastguard Worker 17*5a923131SAndroid Build Coastguard Worker #ifndef UPDATE_ENGINE_COMMON_HTTP_FETCHER_H_ 18*5a923131SAndroid Build Coastguard Worker #define UPDATE_ENGINE_COMMON_HTTP_FETCHER_H_ 19*5a923131SAndroid Build Coastguard Worker 20*5a923131SAndroid Build Coastguard Worker #include <deque> 21*5a923131SAndroid Build Coastguard Worker #include <memory> 22*5a923131SAndroid Build Coastguard Worker #include <string> 23*5a923131SAndroid Build Coastguard Worker #include <vector> 24*5a923131SAndroid Build Coastguard Worker 25*5a923131SAndroid Build Coastguard Worker #include <base/callback.h> 26*5a923131SAndroid Build Coastguard Worker #include <base/logging.h> 27*5a923131SAndroid Build Coastguard Worker #include <android-base/macros.h> 28*5a923131SAndroid Build Coastguard Worker #include <brillo/message_loops/message_loop.h> 29*5a923131SAndroid Build Coastguard Worker #include <brillo/secure_blob.h> 30*5a923131SAndroid Build Coastguard Worker 31*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/constants.h" 32*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/error_code.h" 33*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/http_common.h" 34*5a923131SAndroid Build Coastguard Worker 35*5a923131SAndroid Build Coastguard Worker // This class is a simple wrapper around an HTTP library (libcurl). We can 36*5a923131SAndroid Build Coastguard Worker // easily mock out this interface for testing. 37*5a923131SAndroid Build Coastguard Worker 38*5a923131SAndroid Build Coastguard Worker // Implementations of this class should use asynchronous i/o. They can access 39*5a923131SAndroid Build Coastguard Worker // the MessageLoop to request callbacks when timers or file descriptors change. 40*5a923131SAndroid Build Coastguard Worker 41*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine { 42*5a923131SAndroid Build Coastguard Worker 43*5a923131SAndroid Build Coastguard Worker class HttpFetcherDelegate; 44*5a923131SAndroid Build Coastguard Worker 45*5a923131SAndroid Build Coastguard Worker class HttpFetcher { 46*5a923131SAndroid Build Coastguard Worker public: 47*5a923131SAndroid Build Coastguard Worker // |proxy_resolver| is the resolver that will be consulted for proxy 48*5a923131SAndroid Build Coastguard Worker // settings. It may be null, in which case direct connections will 49*5a923131SAndroid Build Coastguard Worker // be used. Does not take ownership of the resolver. HttpFetcher()50*5a923131SAndroid Build Coastguard Worker HttpFetcher() 51*5a923131SAndroid Build Coastguard Worker : post_data_set_(false), 52*5a923131SAndroid Build Coastguard Worker http_response_code_(0), 53*5a923131SAndroid Build Coastguard Worker delegate_(nullptr), 54*5a923131SAndroid Build Coastguard Worker proxies_(1, kNoProxy), 55*5a923131SAndroid Build Coastguard Worker callback_(nullptr) {} 56*5a923131SAndroid Build Coastguard Worker virtual ~HttpFetcher(); 57*5a923131SAndroid Build Coastguard Worker set_delegate(HttpFetcherDelegate * delegate)58*5a923131SAndroid Build Coastguard Worker void set_delegate(HttpFetcherDelegate* delegate) { delegate_ = delegate; } delegate()59*5a923131SAndroid Build Coastguard Worker HttpFetcherDelegate* delegate() const { return delegate_; } http_response_code()60*5a923131SAndroid Build Coastguard Worker int http_response_code() const { return http_response_code_; } 61*5a923131SAndroid Build Coastguard Worker 62*5a923131SAndroid Build Coastguard Worker // Returns additional error code that can't be expressed in terms of an HTTP 63*5a923131SAndroid Build Coastguard Worker // response code. For example, if there was a specific internal error code in 64*5a923131SAndroid Build Coastguard Worker // the objects used in the implementation of this class (like libcurl) that we 65*5a923131SAndroid Build Coastguard Worker // are interested about, we can communicate it through this value. GetAuxiliaryErrorCode()66*5a923131SAndroid Build Coastguard Worker ErrorCode GetAuxiliaryErrorCode() const { return auxiliary_error_code_; } 67*5a923131SAndroid Build Coastguard Worker 68*5a923131SAndroid Build Coastguard Worker // Optional: Post data to the server. The HttpFetcher should make a copy 69*5a923131SAndroid Build Coastguard Worker // of this data and upload it via HTTP POST during the transfer. The type of 70*5a923131SAndroid Build Coastguard Worker // the data is necessary for properly setting the Content-Type HTTP header. 71*5a923131SAndroid Build Coastguard Worker void SetPostData(const void* data, size_t size, HttpContentType type); 72*5a923131SAndroid Build Coastguard Worker 73*5a923131SAndroid Build Coastguard Worker // Same without a specified Content-Type. 74*5a923131SAndroid Build Coastguard Worker void SetPostData(const void* data, size_t size); 75*5a923131SAndroid Build Coastguard Worker SetProxies(const std::deque<std::string> & proxies)76*5a923131SAndroid Build Coastguard Worker virtual void SetProxies(const std::deque<std::string>& proxies) { 77*5a923131SAndroid Build Coastguard Worker proxies_ = proxies; 78*5a923131SAndroid Build Coastguard Worker } GetCurrentProxy()79*5a923131SAndroid Build Coastguard Worker const std::string& GetCurrentProxy() const { return proxies_.front(); } HasProxy()80*5a923131SAndroid Build Coastguard Worker bool HasProxy() const { return !proxies_.empty(); } PopProxy()81*5a923131SAndroid Build Coastguard Worker void PopProxy() { proxies_.pop_front(); } 82*5a923131SAndroid Build Coastguard Worker 83*5a923131SAndroid Build Coastguard Worker // Downloading should resume from this offset 84*5a923131SAndroid Build Coastguard Worker virtual void SetOffset(off_t offset) = 0; 85*5a923131SAndroid Build Coastguard Worker 86*5a923131SAndroid Build Coastguard Worker // Set/unset the length of the range to be downloaded. 87*5a923131SAndroid Build Coastguard Worker virtual void SetLength(size_t length) = 0; 88*5a923131SAndroid Build Coastguard Worker virtual void UnsetLength() = 0; 89*5a923131SAndroid Build Coastguard Worker 90*5a923131SAndroid Build Coastguard Worker // Begins the transfer to the specified URL. This fetcher instance should not 91*5a923131SAndroid Build Coastguard Worker // be destroyed until either TransferComplete, or TransferTerminated is 92*5a923131SAndroid Build Coastguard Worker // called. 93*5a923131SAndroid Build Coastguard Worker virtual void BeginTransfer(const std::string& url) = 0; 94*5a923131SAndroid Build Coastguard Worker 95*5a923131SAndroid Build Coastguard Worker // Aborts the transfer. The transfer may not abort right away -- delegate's 96*5a923131SAndroid Build Coastguard Worker // TransferTerminated() will be called when the transfer is actually done. 97*5a923131SAndroid Build Coastguard Worker virtual void TerminateTransfer() = 0; 98*5a923131SAndroid Build Coastguard Worker 99*5a923131SAndroid Build Coastguard Worker // Add or update a custom header to be sent with every request. If the same 100*5a923131SAndroid Build Coastguard Worker // |header_name| is passed twice, the second |header_value| would override the 101*5a923131SAndroid Build Coastguard Worker // previous value. 102*5a923131SAndroid Build Coastguard Worker virtual void SetHeader(const std::string& header_name, 103*5a923131SAndroid Build Coastguard Worker const std::string& header_value) = 0; 104*5a923131SAndroid Build Coastguard Worker 105*5a923131SAndroid Build Coastguard Worker // Only used for testing. 106*5a923131SAndroid Build Coastguard Worker // If |header_name| is set, the value will be set into |header_value|. 107*5a923131SAndroid Build Coastguard Worker // On success the boolean true will be returned, hoewever on failture to find 108*5a923131SAndroid Build Coastguard Worker // the |header_name| in the header the return value will be false. The state 109*5a923131SAndroid Build Coastguard Worker // in which |header_value| is left in for failures is an empty string. 110*5a923131SAndroid Build Coastguard Worker virtual bool GetHeader(const std::string& header_name, 111*5a923131SAndroid Build Coastguard Worker std::string* header_value) const = 0; 112*5a923131SAndroid Build Coastguard Worker 113*5a923131SAndroid Build Coastguard Worker // If data is coming in too quickly, you can call Pause() to pause the 114*5a923131SAndroid Build Coastguard Worker // transfer. The delegate will not have ReceivedBytes() called while 115*5a923131SAndroid Build Coastguard Worker // an HttpFetcher is paused. 116*5a923131SAndroid Build Coastguard Worker virtual void Pause() = 0; 117*5a923131SAndroid Build Coastguard Worker 118*5a923131SAndroid Build Coastguard Worker // Used to unpause an HttpFetcher and let the bytes stream in again. 119*5a923131SAndroid Build Coastguard Worker // If a delegate is set, ReceivedBytes() may be called on it before 120*5a923131SAndroid Build Coastguard Worker // Unpause() returns 121*5a923131SAndroid Build Coastguard Worker virtual void Unpause() = 0; 122*5a923131SAndroid Build Coastguard Worker 123*5a923131SAndroid Build Coastguard Worker // These two function are overloaded in LibcurlHttp fetcher to speed 124*5a923131SAndroid Build Coastguard Worker // testing. set_idle_seconds(int seconds)125*5a923131SAndroid Build Coastguard Worker virtual void set_idle_seconds(int seconds) {} set_retry_seconds(int seconds)126*5a923131SAndroid Build Coastguard Worker virtual void set_retry_seconds(int seconds) {} 127*5a923131SAndroid Build Coastguard Worker 128*5a923131SAndroid Build Coastguard Worker // Sets the values used to time out the connection if the transfer 129*5a923131SAndroid Build Coastguard Worker // rate is less than |low_speed_bps| bytes/sec for more than 130*5a923131SAndroid Build Coastguard Worker // |low_speed_sec| seconds. 131*5a923131SAndroid Build Coastguard Worker virtual void set_low_speed_limit(int low_speed_bps, int low_speed_sec) = 0; 132*5a923131SAndroid Build Coastguard Worker 133*5a923131SAndroid Build Coastguard Worker // Sets the connect timeout, e.g. the maximum amount of time willing 134*5a923131SAndroid Build Coastguard Worker // to wait for establishing a connection to the server. 135*5a923131SAndroid Build Coastguard Worker virtual void set_connect_timeout(int connect_timeout_seconds) = 0; 136*5a923131SAndroid Build Coastguard Worker 137*5a923131SAndroid Build Coastguard Worker // Sets the number of allowed retries. 138*5a923131SAndroid Build Coastguard Worker virtual void set_max_retry_count(int max_retry_count) = 0; 139*5a923131SAndroid Build Coastguard Worker 140*5a923131SAndroid Build Coastguard Worker // Get the total number of bytes downloaded by fetcher. 141*5a923131SAndroid Build Coastguard Worker virtual size_t GetBytesDownloaded() = 0; 142*5a923131SAndroid Build Coastguard Worker 143*5a923131SAndroid Build Coastguard Worker protected: 144*5a923131SAndroid Build Coastguard Worker // The URL we're actively fetching from 145*5a923131SAndroid Build Coastguard Worker std::string url_; 146*5a923131SAndroid Build Coastguard Worker 147*5a923131SAndroid Build Coastguard Worker // POST data for the transfer, and whether or not it was ever set 148*5a923131SAndroid Build Coastguard Worker bool post_data_set_; 149*5a923131SAndroid Build Coastguard Worker brillo::Blob post_data_; 150*5a923131SAndroid Build Coastguard Worker HttpContentType post_content_type_{}; 151*5a923131SAndroid Build Coastguard Worker 152*5a923131SAndroid Build Coastguard Worker // The server's HTTP response code from the last transfer. This 153*5a923131SAndroid Build Coastguard Worker // field should be set to 0 when a new transfer is initiated, and 154*5a923131SAndroid Build Coastguard Worker // set to the response code when the transfer is complete. 155*5a923131SAndroid Build Coastguard Worker int http_response_code_; 156*5a923131SAndroid Build Coastguard Worker 157*5a923131SAndroid Build Coastguard Worker // Set when there is an error that can't be expressed in the form of 158*5a923131SAndroid Build Coastguard Worker // |http_response_code_|. 159*5a923131SAndroid Build Coastguard Worker ErrorCode auxiliary_error_code_{ErrorCode::kSuccess}; 160*5a923131SAndroid Build Coastguard Worker 161*5a923131SAndroid Build Coastguard Worker // The delegate; may be null. 162*5a923131SAndroid Build Coastguard Worker HttpFetcherDelegate* delegate_ = nullptr; 163*5a923131SAndroid Build Coastguard Worker 164*5a923131SAndroid Build Coastguard Worker // Proxy servers 165*5a923131SAndroid Build Coastguard Worker std::deque<std::string> proxies_; 166*5a923131SAndroid Build Coastguard Worker 167*5a923131SAndroid Build Coastguard Worker // Callback for when we are resolving proxies 168*5a923131SAndroid Build Coastguard Worker std::unique_ptr<base::Closure> callback_; 169*5a923131SAndroid Build Coastguard Worker 170*5a923131SAndroid Build Coastguard Worker private: 171*5a923131SAndroid Build Coastguard Worker // Callback from the proxy resolver 172*5a923131SAndroid Build Coastguard Worker void ProxiesResolved(const std::deque<std::string>& proxies); 173*5a923131SAndroid Build Coastguard Worker 174*5a923131SAndroid Build Coastguard Worker // Callback used to run the proxy resolver callback when there is no 175*5a923131SAndroid Build Coastguard Worker // |proxy_resolver_|. 176*5a923131SAndroid Build Coastguard Worker void NoProxyResolverCallback(); 177*5a923131SAndroid Build Coastguard Worker 178*5a923131SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(HttpFetcher); 179*5a923131SAndroid Build Coastguard Worker }; 180*5a923131SAndroid Build Coastguard Worker 181*5a923131SAndroid Build Coastguard Worker // Interface for delegates 182*5a923131SAndroid Build Coastguard Worker class HttpFetcherDelegate { 183*5a923131SAndroid Build Coastguard Worker public: 184*5a923131SAndroid Build Coastguard Worker virtual ~HttpFetcherDelegate() = default; 185*5a923131SAndroid Build Coastguard Worker 186*5a923131SAndroid Build Coastguard Worker // Called every time bytes are received. Returns false if this call causes the 187*5a923131SAndroid Build Coastguard Worker // transfer be terminated or completed otherwise it returns true. 188*5a923131SAndroid Build Coastguard Worker virtual bool ReceivedBytes(HttpFetcher* fetcher, 189*5a923131SAndroid Build Coastguard Worker const void* bytes, 190*5a923131SAndroid Build Coastguard Worker size_t length) = 0; 191*5a923131SAndroid Build Coastguard Worker 192*5a923131SAndroid Build Coastguard Worker // Called if the fetcher seeks to a particular offset. SeekToOffset(off_t offset)193*5a923131SAndroid Build Coastguard Worker virtual void SeekToOffset(off_t offset) {} 194*5a923131SAndroid Build Coastguard Worker 195*5a923131SAndroid Build Coastguard Worker // When a transfer has completed, exactly one of these two methods will be 196*5a923131SAndroid Build Coastguard Worker // called. TransferTerminated is called when the transfer has been aborted 197*5a923131SAndroid Build Coastguard Worker // through TerminateTransfer. TransferComplete is called in all other 198*5a923131SAndroid Build Coastguard Worker // situations. It's OK to destroy the |fetcher| object in this callback. 199*5a923131SAndroid Build Coastguard Worker virtual void TransferComplete(HttpFetcher* fetcher, bool successful) = 0; TransferTerminated(HttpFetcher * fetcher)200*5a923131SAndroid Build Coastguard Worker virtual void TransferTerminated(HttpFetcher* fetcher) {} 201*5a923131SAndroid Build Coastguard Worker }; 202*5a923131SAndroid Build Coastguard Worker 203*5a923131SAndroid Build Coastguard Worker } // namespace chromeos_update_engine 204*5a923131SAndroid Build Coastguard Worker 205*5a923131SAndroid Build Coastguard Worker #endif // UPDATE_ENGINE_COMMON_HTTP_FETCHER_H_ 206