blob: b8c6ad6ab10c81e5d352ae8bd2532d9532447a79 [file] [log] [blame]
rspangler@google.com49fdf182009-10-10 00:57:34 +00001// Copyright (c) 2009 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
Gilad Arnoldcf175a02014-07-10 16:48:47 -07005#ifndef UPDATE_ENGINE_HTTP_FETCHER_H_
6#define UPDATE_ENGINE_HTTP_FETCHER_H_
rspangler@google.com49fdf182009-10-10 00:57:34 +00007
Andrew de los Reyes45168102010-11-22 11:13:50 -08008#include <deque>
rspangler@google.com49fdf182009-10-10 00:57:34 +00009#include <string>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000010#include <vector>
Andrew de los Reyes45168102010-11-22 11:13:50 -080011
Ben Chan05735a12014-09-03 07:48:22 -070012#include <glib.h>
13
Alex Vakulenko4906c1c2014-08-21 13:17:44 -070014#include <base/callback.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080015#include <base/logging.h>
Ben Chan05735a12014-09-03 07:48:22 -070016#include <base/macros.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080017
Alex Deymo04f2b382014-03-21 15:45:17 -070018#include "update_engine/http_common.h"
Andrew de los Reyes45168102010-11-22 11:13:50 -080019#include "update_engine/proxy_resolver.h"
Jay Srinivasan43488792012-06-19 00:25:31 -070020#include "update_engine/system_state.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000021
22// This class is a simple wrapper around an HTTP library (libcurl). We can
23// easily mock out this interface for testing.
24
25// Implementations of this class should use asynchronous i/o. They can access
26// the glib main loop to request callbacks when timers or file descriptors
27// change.
28
29namespace chromeos_update_engine {
30
31class HttpFetcherDelegate;
32
33class HttpFetcher {
34 public:
Andrew de los Reyes45168102010-11-22 11:13:50 -080035 // |proxy_resolver| is the resolver that will be consulted for proxy
36 // settings. It may be null, in which case direct connections will
37 // be used. Does not take ownership of the resolver.
Jay Srinivasan43488792012-06-19 00:25:31 -070038 HttpFetcher(ProxyResolver* proxy_resolver, SystemState* system_state)
Darin Petkovcb466212010-08-26 09:40:11 -070039 : post_data_set_(false),
40 http_response_code_(0),
Alex Vakulenko88b591f2014-08-28 16:48:57 -070041 delegate_(nullptr),
Andrew de los Reyes45168102010-11-22 11:13:50 -080042 proxies_(1, kNoProxy),
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -080043 proxy_resolver_(proxy_resolver),
44 no_resolver_idle_id_(0),
Alex Vakulenko88b591f2014-08-28 16:48:57 -070045 callback_(nullptr),
Jay Srinivasan43488792012-06-19 00:25:31 -070046 system_state_(system_state) {}
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -080047 virtual ~HttpFetcher();
Darin Petkovcb466212010-08-26 09:40:11 -070048
49 void set_delegate(HttpFetcherDelegate* delegate) { delegate_ = delegate; }
50 HttpFetcherDelegate* delegate() const { return delegate_; }
51 int http_response_code() const { return http_response_code_; }
rspangler@google.com49fdf182009-10-10 00:57:34 +000052
53 // Optional: Post data to the server. The HttpFetcher should make a copy
Gilad Arnold9dd1e7c2012-02-16 12:13:36 -080054 // of this data and upload it via HTTP POST during the transfer. The type of
55 // the data is necessary for properly setting the Content-Type HTTP header.
56 void SetPostData(const void* data, size_t size, HttpContentType type);
57
58 // Same without a specified Content-Type.
Andrew de los Reyes45168102010-11-22 11:13:50 -080059 void SetPostData(const void* data, size_t size);
60
61 // Proxy methods to set the proxies, then to pop them off.
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -080062 // Returns true on success.
Alex Vakulenko4906c1c2014-08-21 13:17:44 -070063 bool ResolveProxiesForUrl(const std::string& url, base::Closure* callback);
Jay Srinivasan43488792012-06-19 00:25:31 -070064
Andrew de los Reyes45168102010-11-22 11:13:50 -080065 void SetProxies(const std::deque<std::string>& proxies) {
66 proxies_ = proxies;
rspangler@google.com49fdf182009-10-10 00:57:34 +000067 }
Andrew de los Reyes45168102010-11-22 11:13:50 -080068 const std::string& GetCurrentProxy() const {
69 return proxies_.front();
70 }
71 bool HasProxy() const { return !proxies_.empty(); }
72 void PopProxy() { proxies_.pop_front(); }
rspangler@google.com49fdf182009-10-10 00:57:34 +000073
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070074 // Downloading should resume from this offset
75 virtual void SetOffset(off_t offset) = 0;
76
Gilad Arnolde4ad2502011-12-29 17:08:54 -080077 // Set/unset the length of the range to be downloaded.
78 virtual void SetLength(size_t length) = 0;
79 virtual void UnsetLength() = 0;
80
Darin Petkov9ce452b2010-11-17 14:33:28 -080081 // Begins the transfer to the specified URL. This fetcher instance should not
82 // be destroyed until either TransferComplete, or TransferTerminated is
83 // called.
rspangler@google.com49fdf182009-10-10 00:57:34 +000084 virtual void BeginTransfer(const std::string& url) = 0;
85
Darin Petkov9ce452b2010-11-17 14:33:28 -080086 // Aborts the transfer. The transfer may not abort right away -- delegate's
87 // TransferTerminated() will be called when the transfer is actually done.
rspangler@google.com49fdf182009-10-10 00:57:34 +000088 virtual void TerminateTransfer() = 0;
89
90 // If data is coming in too quickly, you can call Pause() to pause the
91 // transfer. The delegate will not have ReceivedBytes() called while
92 // an HttpFetcher is paused.
93 virtual void Pause() = 0;
94
95 // Used to unpause an HttpFetcher and let the bytes stream in again.
96 // If a delegate is set, ReceivedBytes() may be called on it before
97 // Unpause() returns
98 virtual void Unpause() = 0;
99
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700100 // These two function are overloaded in LibcurlHttp fetcher to speed
101 // testing.
102 virtual void set_idle_seconds(int seconds) {}
103 virtual void set_retry_seconds(int seconds) {}
104
David Zeuthen34135a92013-08-06 11:16:16 -0700105 // Sets the values used to time out the connection if the transfer
106 // rate is less than |low_speed_bps| bytes/sec for more than
107 // |low_speed_sec| seconds.
108 virtual void set_low_speed_limit(int low_speed_bps, int low_speed_sec) = 0;
109
110 // Sets the connect timeout, e.g. the maximum amount of time willing
111 // to wait for establishing a connection to the server.
112 virtual void set_connect_timeout(int connect_timeout_seconds) = 0;
113
114 // Sets the number of allowed retries.
115 virtual void set_max_retry_count(int max_retry_count) = 0;
116
Gilad Arnold48085ba2011-11-16 09:36:08 -0800117 // Get the total number of bytes downloaded by fetcher.
118 virtual size_t GetBytesDownloaded() = 0;
119
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800120 ProxyResolver* proxy_resolver() const { return proxy_resolver_; }
121
Alex Deymo7984bf02014-04-02 20:41:57 -0700122 // Returns the global SystemState.
Jay Srinivasan43488792012-06-19 00:25:31 -0700123 SystemState* GetSystemState() {
124 return system_state_;
125 }
126
rspangler@google.com49fdf182009-10-10 00:57:34 +0000127 protected:
128 // The URL we're actively fetching from
129 std::string url_;
130
131 // POST data for the transfer, and whether or not it was ever set
132 bool post_data_set_;
133 std::vector<char> post_data_;
Gilad Arnold9dd1e7c2012-02-16 12:13:36 -0800134 HttpContentType post_content_type_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000135
Darin Petkovcb466212010-08-26 09:40:11 -0700136 // The server's HTTP response code from the last transfer. This
137 // field should be set to 0 when a new transfer is initiated, and
138 // set to the response code when the transfer is complete.
139 int http_response_code_;
140
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700141 // The delegate; may be null.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000142 HttpFetcherDelegate* delegate_;
Andrew de los Reyes45168102010-11-22 11:13:50 -0800143
144 // Proxy servers
145 std::deque<std::string> proxies_;
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800146
Andrew de los Reyes45168102010-11-22 11:13:50 -0800147 ProxyResolver* const proxy_resolver_;
148
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800149 // The ID of the idle callback, used when we have no proxy resolver.
150 guint no_resolver_idle_id_;
151
152 // Callback for when we are resolving proxies
Alex Vakulenko4906c1c2014-08-21 13:17:44 -0700153 base::Closure* callback_;
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800154
Jay Srinivasan43488792012-06-19 00:25:31 -0700155 // Global system context.
156 SystemState* system_state_;
157
rspangler@google.com49fdf182009-10-10 00:57:34 +0000158 private:
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800159 // Callback from the proxy resolver
160 void ProxiesResolved(const std::deque<std::string>& proxies);
161 static void StaticProxiesResolved(const std::deque<std::string>& proxies,
162 void* data) {
163 reinterpret_cast<HttpFetcher*>(data)->ProxiesResolved(proxies);
164 }
Jay Srinivasan43488792012-06-19 00:25:31 -0700165
rspangler@google.com49fdf182009-10-10 00:57:34 +0000166 DISALLOW_COPY_AND_ASSIGN(HttpFetcher);
167};
168
169// Interface for delegates
170class HttpFetcherDelegate {
171 public:
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700172 // Called every time bytes are received.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000173 virtual void ReceivedBytes(HttpFetcher* fetcher,
174 const char* bytes,
175 int length) = 0;
176
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700177 // Called if the fetcher seeks to a particular offset.
178 virtual void SeekToOffset(off_t offset) {}
179
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800180 // When a transfer has completed, exactly one of these two methods will be
181 // called. TransferTerminated is called when the transfer has been aborted
182 // through TerminateTransfer. TransferComplete is called in all other
183 // situations. It's OK to destroy the |fetcher| object in this callback.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000184 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) = 0;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800185 virtual void TransferTerminated(HttpFetcher* fetcher) {}
rspangler@google.com49fdf182009-10-10 00:57:34 +0000186};
187
188} // namespace chromeos_update_engine
189
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700190#endif // UPDATE_ENGINE_HTTP_FETCHER_H_