blob: e4f791a13a18184165e0fe4bdb2d82b04975659c [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
adlr@google.comc98a7ed2009-12-04 18:54:03 +00005#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_HTTP_FETCHER_H__
6#define CHROMEOS_PLATFORM_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
12#include <base/basictypes.h>
13#include <base/logging.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000014#include <glib.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080015
16#include "update_engine/proxy_resolver.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000017
18// This class is a simple wrapper around an HTTP library (libcurl). We can
19// easily mock out this interface for testing.
20
21// Implementations of this class should use asynchronous i/o. They can access
22// the glib main loop to request callbacks when timers or file descriptors
23// change.
24
25namespace chromeos_update_engine {
26
27class HttpFetcherDelegate;
28
29class HttpFetcher {
30 public:
Andrew de los Reyes45168102010-11-22 11:13:50 -080031 // |proxy_resolver| is the resolver that will be consulted for proxy
32 // settings. It may be null, in which case direct connections will
33 // be used. Does not take ownership of the resolver.
34 explicit HttpFetcher(ProxyResolver* proxy_resolver)
Darin Petkovcb466212010-08-26 09:40:11 -070035 : post_data_set_(false),
36 http_response_code_(0),
Andrew de los Reyes45168102010-11-22 11:13:50 -080037 delegate_(NULL),
38 proxies_(1, kNoProxy),
39 proxy_resolver_(proxy_resolver) {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000040 virtual ~HttpFetcher() {}
Darin Petkovcb466212010-08-26 09:40:11 -070041
42 void set_delegate(HttpFetcherDelegate* delegate) { delegate_ = delegate; }
43 HttpFetcherDelegate* delegate() const { return delegate_; }
44 int http_response_code() const { return http_response_code_; }
rspangler@google.com49fdf182009-10-10 00:57:34 +000045
46 // Optional: Post data to the server. The HttpFetcher should make a copy
47 // of this data and upload it via HTTP POST during the transfer.
Andrew de los Reyes45168102010-11-22 11:13:50 -080048 void SetPostData(const void* data, size_t size);
49
50 // Proxy methods to set the proxies, then to pop them off.
51 void ResolveProxiesForUrl(const std::string& url);
52
53 void SetProxies(const std::deque<std::string>& proxies) {
54 proxies_ = proxies;
rspangler@google.com49fdf182009-10-10 00:57:34 +000055 }
Andrew de los Reyes45168102010-11-22 11:13:50 -080056 const std::string& GetCurrentProxy() const {
57 return proxies_.front();
58 }
59 bool HasProxy() const { return !proxies_.empty(); }
60 void PopProxy() { proxies_.pop_front(); }
rspangler@google.com49fdf182009-10-10 00:57:34 +000061
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070062 // Downloading should resume from this offset
63 virtual void SetOffset(off_t offset) = 0;
64
Darin Petkov9ce452b2010-11-17 14:33:28 -080065 // Begins the transfer to the specified URL. This fetcher instance should not
66 // be destroyed until either TransferComplete, or TransferTerminated is
67 // called.
rspangler@google.com49fdf182009-10-10 00:57:34 +000068 virtual void BeginTransfer(const std::string& url) = 0;
69
Darin Petkov9ce452b2010-11-17 14:33:28 -080070 // Aborts the transfer. The transfer may not abort right away -- delegate's
71 // TransferTerminated() will be called when the transfer is actually done.
rspangler@google.com49fdf182009-10-10 00:57:34 +000072 virtual void TerminateTransfer() = 0;
73
74 // If data is coming in too quickly, you can call Pause() to pause the
75 // transfer. The delegate will not have ReceivedBytes() called while
76 // an HttpFetcher is paused.
77 virtual void Pause() = 0;
78
79 // Used to unpause an HttpFetcher and let the bytes stream in again.
80 // If a delegate is set, ReceivedBytes() may be called on it before
81 // Unpause() returns
82 virtual void Unpause() = 0;
83
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070084 // These two function are overloaded in LibcurlHttp fetcher to speed
85 // testing.
86 virtual void set_idle_seconds(int seconds) {}
87 virtual void set_retry_seconds(int seconds) {}
88
Andrew de los Reyes819fef22010-12-17 11:33:58 -080089 ProxyResolver* proxy_resolver() const { return proxy_resolver_; }
90
91 // These are used for testing:
92 virtual void SetConnectionAsExpensive(bool is_expensive) {}
93 virtual void SetBuildType(bool is_official) {}
94
rspangler@google.com49fdf182009-10-10 00:57:34 +000095 protected:
96 // The URL we're actively fetching from
97 std::string url_;
98
99 // POST data for the transfer, and whether or not it was ever set
100 bool post_data_set_;
101 std::vector<char> post_data_;
102
Darin Petkovcb466212010-08-26 09:40:11 -0700103 // The server's HTTP response code from the last transfer. This
104 // field should be set to 0 when a new transfer is initiated, and
105 // set to the response code when the transfer is complete.
106 int http_response_code_;
107
rspangler@google.com49fdf182009-10-10 00:57:34 +0000108 // The delegate; may be NULL.
109 HttpFetcherDelegate* delegate_;
Andrew de los Reyes45168102010-11-22 11:13:50 -0800110
111 // Proxy servers
112 std::deque<std::string> proxies_;
113
114 ProxyResolver* const proxy_resolver_;
115
rspangler@google.com49fdf182009-10-10 00:57:34 +0000116 private:
117 DISALLOW_COPY_AND_ASSIGN(HttpFetcher);
118};
119
120// Interface for delegates
121class HttpFetcherDelegate {
122 public:
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700123 // Called every time bytes are received.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000124 virtual void ReceivedBytes(HttpFetcher* fetcher,
125 const char* bytes,
126 int length) = 0;
127
Andrew de los Reyes34e41a12010-10-26 20:07:58 -0700128 // Called if the fetcher seeks to a particular offset.
129 virtual void SeekToOffset(off_t offset) {}
130
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800131 // When a transfer has completed, exactly one of these two methods will be
132 // called. TransferTerminated is called when the transfer has been aborted
133 // through TerminateTransfer. TransferComplete is called in all other
134 // situations. It's OK to destroy the |fetcher| object in this callback.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000135 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) = 0;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800136 virtual void TransferTerminated(HttpFetcher* fetcher) {}
rspangler@google.com49fdf182009-10-10 00:57:34 +0000137};
138
139} // namespace chromeos_update_engine
140
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000141#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_HTTP_FETCHER_H__