xref: /aosp_15_r20/system/update_engine/common/http_fetcher.h (revision 5a9231315b4521097b8dc3750bc806fcafe0c72f)
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