blob: 269f40a594a64a3485fad33cc150effa21daffcf [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2009 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
rspangler@google.com49fdf182009-10-10 00:57:34 +000016
Gilad Arnoldcf175a02014-07-10 16:48:47 -070017#ifndef UPDATE_ENGINE_HTTP_FETCHER_H_
18#define UPDATE_ENGINE_HTTP_FETCHER_H_
rspangler@google.com49fdf182009-10-10 00:57:34 +000019
Andrew de los Reyes45168102010-11-22 11:13:50 -080020#include <deque>
rspangler@google.com49fdf182009-10-10 00:57:34 +000021#include <string>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000022#include <vector>
Andrew de los Reyes45168102010-11-22 11:13:50 -080023
Alex Vakulenko4906c1c2014-08-21 13:17:44 -070024#include <base/callback.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080025#include <base/logging.h>
Ben Chan05735a12014-09-03 07:48:22 -070026#include <base/macros.h>
Alex Deymo60ca1a72015-06-18 18:19:15 -070027#include <chromeos/message_loops/message_loop.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080028
Alex Deymo04f2b382014-03-21 15:45:17 -070029#include "update_engine/http_common.h"
Andrew de los Reyes45168102010-11-22 11:13:50 -080030#include "update_engine/proxy_resolver.h"
Jay Srinivasan43488792012-06-19 00:25:31 -070031#include "update_engine/system_state.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000032
33// This class is a simple wrapper around an HTTP library (libcurl). We can
34// easily mock out this interface for testing.
35
36// Implementations of this class should use asynchronous i/o. They can access
Alex Deymo60ca1a72015-06-18 18:19:15 -070037// the MessageLoop to request callbacks when timers or file descriptors change.
rspangler@google.com49fdf182009-10-10 00:57:34 +000038
39namespace chromeos_update_engine {
40
41class HttpFetcherDelegate;
42
43class HttpFetcher {
44 public:
Andrew de los Reyes45168102010-11-22 11:13:50 -080045 // |proxy_resolver| is the resolver that will be consulted for proxy
46 // settings. It may be null, in which case direct connections will
47 // be used. Does not take ownership of the resolver.
Jay Srinivasan43488792012-06-19 00:25:31 -070048 HttpFetcher(ProxyResolver* proxy_resolver, SystemState* system_state)
Darin Petkovcb466212010-08-26 09:40:11 -070049 : post_data_set_(false),
50 http_response_code_(0),
Alex Vakulenko88b591f2014-08-28 16:48:57 -070051 delegate_(nullptr),
Andrew de los Reyes45168102010-11-22 11:13:50 -080052 proxies_(1, kNoProxy),
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -080053 proxy_resolver_(proxy_resolver),
Alex Vakulenko88b591f2014-08-28 16:48:57 -070054 callback_(nullptr),
Jay Srinivasan43488792012-06-19 00:25:31 -070055 system_state_(system_state) {}
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -080056 virtual ~HttpFetcher();
Darin Petkovcb466212010-08-26 09:40:11 -070057
58 void set_delegate(HttpFetcherDelegate* delegate) { delegate_ = delegate; }
59 HttpFetcherDelegate* delegate() const { return delegate_; }
60 int http_response_code() const { return http_response_code_; }
rspangler@google.com49fdf182009-10-10 00:57:34 +000061
62 // Optional: Post data to the server. The HttpFetcher should make a copy
Gilad Arnold9dd1e7c2012-02-16 12:13:36 -080063 // of this data and upload it via HTTP POST during the transfer. The type of
64 // the data is necessary for properly setting the Content-Type HTTP header.
65 void SetPostData(const void* data, size_t size, HttpContentType type);
66
67 // Same without a specified Content-Type.
Andrew de los Reyes45168102010-11-22 11:13:50 -080068 void SetPostData(const void* data, size_t size);
69
70 // Proxy methods to set the proxies, then to pop them off.
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -080071 // Returns true on success.
Alex Deymo60ca1a72015-06-18 18:19:15 -070072 bool ResolveProxiesForUrl(const std::string& url,
73 const base::Closure& callback);
Jay Srinivasan43488792012-06-19 00:25:31 -070074
Andrew de los Reyes45168102010-11-22 11:13:50 -080075 void SetProxies(const std::deque<std::string>& proxies) {
76 proxies_ = proxies;
rspangler@google.com49fdf182009-10-10 00:57:34 +000077 }
Andrew de los Reyes45168102010-11-22 11:13:50 -080078 const std::string& GetCurrentProxy() const {
79 return proxies_.front();
80 }
81 bool HasProxy() const { return !proxies_.empty(); }
82 void PopProxy() { proxies_.pop_front(); }
rspangler@google.com49fdf182009-10-10 00:57:34 +000083
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070084 // Downloading should resume from this offset
85 virtual void SetOffset(off_t offset) = 0;
86
Gilad Arnolde4ad2502011-12-29 17:08:54 -080087 // Set/unset the length of the range to be downloaded.
88 virtual void SetLength(size_t length) = 0;
89 virtual void UnsetLength() = 0;
90
Darin Petkov9ce452b2010-11-17 14:33:28 -080091 // Begins the transfer to the specified URL. This fetcher instance should not
92 // be destroyed until either TransferComplete, or TransferTerminated is
93 // called.
rspangler@google.com49fdf182009-10-10 00:57:34 +000094 virtual void BeginTransfer(const std::string& url) = 0;
95
Darin Petkov9ce452b2010-11-17 14:33:28 -080096 // Aborts the transfer. The transfer may not abort right away -- delegate's
97 // TransferTerminated() will be called when the transfer is actually done.
rspangler@google.com49fdf182009-10-10 00:57:34 +000098 virtual void TerminateTransfer() = 0;
99
100 // If data is coming in too quickly, you can call Pause() to pause the
101 // transfer. The delegate will not have ReceivedBytes() called while
102 // an HttpFetcher is paused.
103 virtual void Pause() = 0;
104
105 // Used to unpause an HttpFetcher and let the bytes stream in again.
106 // If a delegate is set, ReceivedBytes() may be called on it before
107 // Unpause() returns
108 virtual void Unpause() = 0;
109
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700110 // These two function are overloaded in LibcurlHttp fetcher to speed
111 // testing.
112 virtual void set_idle_seconds(int seconds) {}
113 virtual void set_retry_seconds(int seconds) {}
114
David Zeuthen34135a92013-08-06 11:16:16 -0700115 // Sets the values used to time out the connection if the transfer
116 // rate is less than |low_speed_bps| bytes/sec for more than
117 // |low_speed_sec| seconds.
118 virtual void set_low_speed_limit(int low_speed_bps, int low_speed_sec) = 0;
119
120 // Sets the connect timeout, e.g. the maximum amount of time willing
121 // to wait for establishing a connection to the server.
122 virtual void set_connect_timeout(int connect_timeout_seconds) = 0;
123
124 // Sets the number of allowed retries.
125 virtual void set_max_retry_count(int max_retry_count) = 0;
126
Gilad Arnold48085ba2011-11-16 09:36:08 -0800127 // Get the total number of bytes downloaded by fetcher.
128 virtual size_t GetBytesDownloaded() = 0;
129
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800130 ProxyResolver* proxy_resolver() const { return proxy_resolver_; }
131
Alex Deymo7984bf02014-04-02 20:41:57 -0700132 // Returns the global SystemState.
Jay Srinivasan43488792012-06-19 00:25:31 -0700133 SystemState* GetSystemState() {
134 return system_state_;
135 }
136
rspangler@google.com49fdf182009-10-10 00:57:34 +0000137 protected:
138 // The URL we're actively fetching from
139 std::string url_;
140
141 // POST data for the transfer, and whether or not it was ever set
142 bool post_data_set_;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800143 chromeos::Blob post_data_;
Gilad Arnold9dd1e7c2012-02-16 12:13:36 -0800144 HttpContentType post_content_type_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000145
Darin Petkovcb466212010-08-26 09:40:11 -0700146 // The server's HTTP response code from the last transfer. This
147 // field should be set to 0 when a new transfer is initiated, and
148 // set to the response code when the transfer is complete.
149 int http_response_code_;
150
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700151 // The delegate; may be null.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000152 HttpFetcherDelegate* delegate_;
Andrew de los Reyes45168102010-11-22 11:13:50 -0800153
154 // Proxy servers
155 std::deque<std::string> proxies_;
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800156
Andrew de los Reyes45168102010-11-22 11:13:50 -0800157 ProxyResolver* const proxy_resolver_;
158
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800159 // The ID of the idle callback, used when we have no proxy resolver.
Alex Deymo60ca1a72015-06-18 18:19:15 -0700160 chromeos::MessageLoop::TaskId no_resolver_idle_id_{
161 chromeos::MessageLoop::kTaskIdNull};
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800162
163 // Callback for when we are resolving proxies
Alex Deymo60ca1a72015-06-18 18:19:15 -0700164 std::unique_ptr<base::Closure> callback_;
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800165
Jay Srinivasan43488792012-06-19 00:25:31 -0700166 // Global system context.
167 SystemState* system_state_;
168
rspangler@google.com49fdf182009-10-10 00:57:34 +0000169 private:
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800170 // Callback from the proxy resolver
171 void ProxiesResolved(const std::deque<std::string>& proxies);
172 static void StaticProxiesResolved(const std::deque<std::string>& proxies,
173 void* data) {
174 reinterpret_cast<HttpFetcher*>(data)->ProxiesResolved(proxies);
175 }
Jay Srinivasan43488792012-06-19 00:25:31 -0700176
Alex Deymo60ca1a72015-06-18 18:19:15 -0700177 // Callback used to run the proxy resolver callback when there is no
178 // |proxy_resolver_|.
179 void NoProxyResolverCallback();
180
rspangler@google.com49fdf182009-10-10 00:57:34 +0000181 DISALLOW_COPY_AND_ASSIGN(HttpFetcher);
182};
183
184// Interface for delegates
185class HttpFetcherDelegate {
186 public:
Alex Deymoe8948702014-11-11 21:44:45 -0800187 virtual ~HttpFetcherDelegate() = default;
188
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700189 // Called every time bytes are received.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000190 virtual void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800191 const void* bytes,
192 size_t length) = 0;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000193
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700194 // Called if the fetcher seeks to a particular offset.
195 virtual void SeekToOffset(off_t offset) {}
196
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800197 // When a transfer has completed, exactly one of these two methods will be
198 // called. TransferTerminated is called when the transfer has been aborted
199 // through TerminateTransfer. TransferComplete is called in all other
200 // situations. It's OK to destroy the |fetcher| object in this callback.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000201 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) = 0;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800202 virtual void TransferTerminated(HttpFetcher* fetcher) {}
rspangler@google.com49fdf182009-10-10 00:57:34 +0000203};
204
205} // namespace chromeos_update_engine
206
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700207#endif // UPDATE_ENGINE_HTTP_FETCHER_H_