http_fetcher.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. //
  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. //
  16. #ifndef UPDATE_ENGINE_COMMON_HTTP_FETCHER_H_
  17. #define UPDATE_ENGINE_COMMON_HTTP_FETCHER_H_
  18. #include <deque>
  19. #include <memory>
  20. #include <string>
  21. #include <vector>
  22. #include <base/callback.h>
  23. #include <base/logging.h>
  24. #include <base/macros.h>
  25. #include <brillo/message_loops/message_loop.h>
  26. #include "update_engine/common/http_common.h"
  27. #include "update_engine/common/proxy_resolver.h"
  28. // This class is a simple wrapper around an HTTP library (libcurl). We can
  29. // easily mock out this interface for testing.
  30. // Implementations of this class should use asynchronous i/o. They can access
  31. // the MessageLoop to request callbacks when timers or file descriptors change.
  32. namespace chromeos_update_engine {
  33. class HttpFetcherDelegate;
  34. class HttpFetcher {
  35. public:
  36. // |proxy_resolver| is the resolver that will be consulted for proxy
  37. // settings. It may be null, in which case direct connections will
  38. // be used. Does not take ownership of the resolver.
  39. explicit HttpFetcher(ProxyResolver* proxy_resolver)
  40. : post_data_set_(false),
  41. http_response_code_(0),
  42. delegate_(nullptr),
  43. proxies_(1, kNoProxy),
  44. proxy_resolver_(proxy_resolver),
  45. callback_(nullptr) {}
  46. virtual ~HttpFetcher();
  47. void set_delegate(HttpFetcherDelegate* delegate) { delegate_ = delegate; }
  48. HttpFetcherDelegate* delegate() const { return delegate_; }
  49. int http_response_code() const { return http_response_code_; }
  50. // Optional: Post data to the server. The HttpFetcher should make a copy
  51. // of this data and upload it via HTTP POST during the transfer. The type of
  52. // the data is necessary for properly setting the Content-Type HTTP header.
  53. void SetPostData(const void* data, size_t size, HttpContentType type);
  54. // Same without a specified Content-Type.
  55. void SetPostData(const void* data, size_t size);
  56. // Proxy methods to set the proxies, then to pop them off.
  57. void ResolveProxiesForUrl(const std::string& url,
  58. const base::Closure& callback);
  59. void SetProxies(const std::deque<std::string>& proxies) {
  60. proxies_ = proxies;
  61. }
  62. const std::string& GetCurrentProxy() const { return proxies_.front(); }
  63. bool HasProxy() const { return !proxies_.empty(); }
  64. void PopProxy() { proxies_.pop_front(); }
  65. // Downloading should resume from this offset
  66. virtual void SetOffset(off_t offset) = 0;
  67. // Set/unset the length of the range to be downloaded.
  68. virtual void SetLength(size_t length) = 0;
  69. virtual void UnsetLength() = 0;
  70. // Begins the transfer to the specified URL. This fetcher instance should not
  71. // be destroyed until either TransferComplete, or TransferTerminated is
  72. // called.
  73. virtual void BeginTransfer(const std::string& url) = 0;
  74. // Aborts the transfer. The transfer may not abort right away -- delegate's
  75. // TransferTerminated() will be called when the transfer is actually done.
  76. virtual void TerminateTransfer() = 0;
  77. // Add or update a custom header to be sent with every request. If the same
  78. // |header_name| is passed twice, the second |header_value| would override the
  79. // previous value.
  80. virtual void SetHeader(const std::string& header_name,
  81. const std::string& header_value) = 0;
  82. // If data is coming in too quickly, you can call Pause() to pause the
  83. // transfer. The delegate will not have ReceivedBytes() called while
  84. // an HttpFetcher is paused.
  85. virtual void Pause() = 0;
  86. // Used to unpause an HttpFetcher and let the bytes stream in again.
  87. // If a delegate is set, ReceivedBytes() may be called on it before
  88. // Unpause() returns
  89. virtual void Unpause() = 0;
  90. // These two function are overloaded in LibcurlHttp fetcher to speed
  91. // testing.
  92. virtual void set_idle_seconds(int seconds) {}
  93. virtual void set_retry_seconds(int seconds) {}
  94. // Sets the values used to time out the connection if the transfer
  95. // rate is less than |low_speed_bps| bytes/sec for more than
  96. // |low_speed_sec| seconds.
  97. virtual void set_low_speed_limit(int low_speed_bps, int low_speed_sec) = 0;
  98. // Sets the connect timeout, e.g. the maximum amount of time willing
  99. // to wait for establishing a connection to the server.
  100. virtual void set_connect_timeout(int connect_timeout_seconds) = 0;
  101. // Sets the number of allowed retries.
  102. virtual void set_max_retry_count(int max_retry_count) = 0;
  103. // Get the total number of bytes downloaded by fetcher.
  104. virtual size_t GetBytesDownloaded() = 0;
  105. ProxyResolver* proxy_resolver() const { return proxy_resolver_; }
  106. protected:
  107. // Cancels a proxy resolution in progress. The callback passed to
  108. // ResolveProxiesForUrl() will not be called. Returns whether there was a
  109. // pending proxy resolution to be canceled.
  110. bool CancelProxyResolution();
  111. // The URL we're actively fetching from
  112. std::string url_;
  113. // POST data for the transfer, and whether or not it was ever set
  114. bool post_data_set_;
  115. brillo::Blob post_data_;
  116. HttpContentType post_content_type_;
  117. // The server's HTTP response code from the last transfer. This
  118. // field should be set to 0 when a new transfer is initiated, and
  119. // set to the response code when the transfer is complete.
  120. int http_response_code_;
  121. // The delegate; may be null.
  122. HttpFetcherDelegate* delegate_;
  123. // Proxy servers
  124. std::deque<std::string> proxies_;
  125. ProxyResolver* const proxy_resolver_;
  126. // The ID of the idle callback, used when we have no proxy resolver.
  127. brillo::MessageLoop::TaskId no_resolver_idle_id_{
  128. brillo::MessageLoop::kTaskIdNull};
  129. // Callback for when we are resolving proxies
  130. std::unique_ptr<base::Closure> callback_;
  131. private:
  132. // Callback from the proxy resolver
  133. void ProxiesResolved(const std::deque<std::string>& proxies);
  134. // Callback used to run the proxy resolver callback when there is no
  135. // |proxy_resolver_|.
  136. void NoProxyResolverCallback();
  137. // Stores the ongoing proxy request id if there is one, otherwise
  138. // kProxyRequestIdNull.
  139. ProxyRequestId proxy_request_{kProxyRequestIdNull};
  140. DISALLOW_COPY_AND_ASSIGN(HttpFetcher);
  141. };
  142. // Interface for delegates
  143. class HttpFetcherDelegate {
  144. public:
  145. virtual ~HttpFetcherDelegate() = default;
  146. // Called every time bytes are received. Returns false if this call causes the
  147. // transfer be terminated or completed otherwise it returns true.
  148. virtual bool ReceivedBytes(HttpFetcher* fetcher,
  149. const void* bytes,
  150. size_t length) = 0;
  151. // Called if the fetcher seeks to a particular offset.
  152. virtual void SeekToOffset(off_t offset) {}
  153. // When a transfer has completed, exactly one of these two methods will be
  154. // called. TransferTerminated is called when the transfer has been aborted
  155. // through TerminateTransfer. TransferComplete is called in all other
  156. // situations. It's OK to destroy the |fetcher| object in this callback.
  157. virtual void TransferComplete(HttpFetcher* fetcher, bool successful) = 0;
  158. virtual void TransferTerminated(HttpFetcher* fetcher) {}
  159. };
  160. } // namespace chromeos_update_engine
  161. #endif // UPDATE_ENGINE_COMMON_HTTP_FETCHER_H_