network_impl.cc 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // Copyright 2019 The Chromium 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. #include "components/update_client/net/network_impl.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/numerics/safe_conversions.h"
  8. #include "components/update_client/net/network_chromium.h"
  9. #include "net/base/load_flags.h"
  10. #include "net/http/http_response_headers.h"
  11. #include "net/traffic_annotation/network_traffic_annotation.h"
  12. #include "services/network/public/cpp/is_potentially_trustworthy.h"
  13. #include "services/network/public/cpp/resource_request.h"
  14. #include "services/network/public/cpp/shared_url_loader_factory.h"
  15. #include "services/network/public/cpp/simple_url_loader.h"
  16. #include "services/network/public/cpp/simple_url_loader_throttle.h"
  17. #include "services/network/public/mojom/url_response_head.mojom.h"
  18. #include "url/gurl.h"
  19. namespace {
  20. const net::NetworkTrafficAnnotationTag traffic_annotation =
  21. net::DefineNetworkTrafficAnnotation("update_client", R"(
  22. semantics {
  23. sender: "Component Updater and Extension Updater"
  24. description:
  25. "This network module is used by both the component and the "
  26. "extension updaters in Chrome. "
  27. "The component updater is responsible for updating code and data "
  28. "modules such as Flash, CrlSet, Origin Trials, etc. These modules "
  29. "are updated on cycles independent of the Chrome release tracks. "
  30. "It runs in the browser process and communicates with a set of "
  31. "servers using the Omaha protocol to find the latest versions of "
  32. "components, download them, and register them with the rest of "
  33. "Chrome. "
  34. "The extension updater works similarly, but it updates user "
  35. "extensions instead of Chrome components. "
  36. trigger: "Manual or automatic software updates."
  37. data:
  38. "Various OS and Chrome parameters such as version, bitness, "
  39. "release tracks, etc. The component and the extension ids are also "
  40. "present in both the request and the response from the servers. "
  41. "The URL that refers to a component CRX payload is obfuscated for "
  42. "most components."
  43. destination: GOOGLE_OWNED_SERVICE
  44. }
  45. policy {
  46. cookies_allowed: YES
  47. cookies_store: "user"
  48. setting: "This feature cannot be disabled."
  49. chrome_policy {
  50. ComponentUpdatesEnabled {
  51. policy_options {mode: MANDATORY}
  52. ComponentUpdatesEnabled: false
  53. }
  54. }
  55. })");
  56. // Returns the string value of a header of the server response or an empty
  57. // string if the header is not available. Only the first header is returned
  58. // if multiple instances of the same header are present.
  59. std::string GetStringHeader(const network::SimpleURLLoader* simple_url_loader,
  60. const char* header_name) {
  61. DCHECK(simple_url_loader);
  62. const auto* response_info = simple_url_loader->ResponseInfo();
  63. if (!response_info || !response_info->headers)
  64. return {};
  65. std::string header_value;
  66. return response_info->headers->EnumerateHeader(nullptr, header_name,
  67. &header_value)
  68. ? header_value
  69. : std::string{};
  70. }
  71. // Returns the integral value of a header of the server response or -1 if
  72. // if the header is not available or a conversion error has occured.
  73. int64_t GetInt64Header(const network::SimpleURLLoader* simple_url_loader,
  74. const char* header_name) {
  75. DCHECK(simple_url_loader);
  76. const auto* response_info = simple_url_loader->ResponseInfo();
  77. if (!response_info || !response_info->headers)
  78. return -1;
  79. return response_info->headers->GetInt64HeaderValue(header_name);
  80. }
  81. } // namespace
  82. namespace update_client {
  83. NetworkFetcherImpl::NetworkFetcherImpl(
  84. scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory,
  85. SendCookiesPredicate cookie_predicate)
  86. : shared_url_network_factory_(shared_url_network_factory),
  87. cookie_predicate_(cookie_predicate) {}
  88. NetworkFetcherImpl::~NetworkFetcherImpl() = default;
  89. void NetworkFetcherImpl::PostRequest(
  90. const GURL& url,
  91. const std::string& post_data,
  92. const std::string& content_type,
  93. const base::flat_map<std::string, std::string>& post_additional_headers,
  94. ResponseStartedCallback response_started_callback,
  95. ProgressCallback progress_callback,
  96. PostRequestCompleteCallback post_request_complete_callback) {
  97. DCHECK(!simple_url_loader_);
  98. auto resource_request = std::make_unique<network::ResourceRequest>();
  99. resource_request->url = url;
  100. resource_request->method = "POST";
  101. resource_request->load_flags = net::LOAD_DISABLE_CACHE;
  102. resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
  103. for (const auto& header : post_additional_headers)
  104. resource_request->headers.SetHeader(header.first, header.second);
  105. simple_url_loader_ = network::SimpleURLLoader::Create(
  106. std::move(resource_request), traffic_annotation);
  107. if (network::SimpleURLLoaderThrottle::IsBatchingEnabled(traffic_annotation))
  108. simple_url_loader_->SetAllowBatching();
  109. simple_url_loader_->SetRetryOptions(
  110. kMaxRetriesOnNetworkChange,
  111. network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
  112. // The `Content-Type` header set by |AttachStringForUpload| overwrites any
  113. // `Content-Type` header present in the |ResourceRequest| above.
  114. simple_url_loader_->AttachStringForUpload(post_data, content_type);
  115. simple_url_loader_->SetOnResponseStartedCallback(base::BindOnce(
  116. &NetworkFetcherImpl::OnResponseStartedCallback, base::Unretained(this),
  117. std::move(response_started_callback)));
  118. simple_url_loader_->SetOnDownloadProgressCallback(base::BindRepeating(
  119. &NetworkFetcherImpl::OnProgressCallback, base::Unretained(this),
  120. std::move(progress_callback)));
  121. constexpr size_t kMaxResponseSize = 1024 * 1024;
  122. simple_url_loader_->DownloadToString(
  123. shared_url_network_factory_.get(),
  124. base::BindOnce(
  125. [](const network::SimpleURLLoader* simple_url_loader,
  126. PostRequestCompleteCallback post_request_complete_callback,
  127. std::unique_ptr<std::string> response_body) {
  128. std::move(post_request_complete_callback)
  129. .Run(std::move(response_body), simple_url_loader->NetError(),
  130. GetStringHeader(simple_url_loader, kHeaderEtag),
  131. GetStringHeader(simple_url_loader, kHeaderXCupServerProof),
  132. GetInt64Header(simple_url_loader, kHeaderXRetryAfter));
  133. },
  134. simple_url_loader_.get(), std::move(post_request_complete_callback)),
  135. kMaxResponseSize);
  136. }
  137. void NetworkFetcherImpl::DownloadToFile(
  138. const GURL& url,
  139. const base::FilePath& file_path,
  140. ResponseStartedCallback response_started_callback,
  141. ProgressCallback progress_callback,
  142. DownloadToFileCompleteCallback download_to_file_complete_callback) {
  143. DCHECK(!simple_url_loader_);
  144. auto resource_request = std::make_unique<network::ResourceRequest>();
  145. resource_request->url = url;
  146. resource_request->method = "GET";
  147. resource_request->load_flags = net::LOAD_DISABLE_CACHE;
  148. if (!cookie_predicate_.Run(url) ||
  149. !network::IsUrlPotentiallyTrustworthy(url)) {
  150. resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
  151. } else {
  152. resource_request->site_for_cookies = net::SiteForCookies::FromUrl(url);
  153. }
  154. simple_url_loader_ = network::SimpleURLLoader::Create(
  155. std::move(resource_request), traffic_annotation);
  156. simple_url_loader_->SetRetryOptions(
  157. kMaxRetriesOnNetworkChange,
  158. network::SimpleURLLoader::RetryMode::RETRY_ON_NETWORK_CHANGE);
  159. simple_url_loader_->SetAllowPartialResults(true);
  160. simple_url_loader_->SetOnResponseStartedCallback(base::BindOnce(
  161. &NetworkFetcherImpl::OnResponseStartedCallback, base::Unretained(this),
  162. std::move(response_started_callback)));
  163. simple_url_loader_->SetOnDownloadProgressCallback(base::BindRepeating(
  164. &NetworkFetcherImpl::OnProgressCallback, base::Unretained(this),
  165. std::move(progress_callback)));
  166. simple_url_loader_->DownloadToFile(
  167. shared_url_network_factory_.get(),
  168. base::BindOnce(
  169. [](const network::SimpleURLLoader* simple_url_loader,
  170. DownloadToFileCompleteCallback download_to_file_complete_callback,
  171. base::FilePath file_path) {
  172. std::move(download_to_file_complete_callback)
  173. .Run(simple_url_loader->NetError(),
  174. simple_url_loader->GetContentSize());
  175. },
  176. simple_url_loader_.get(),
  177. std::move(download_to_file_complete_callback)),
  178. file_path);
  179. }
  180. void NetworkFetcherImpl::OnResponseStartedCallback(
  181. ResponseStartedCallback response_started_callback,
  182. const GURL& final_url,
  183. const network::mojom::URLResponseHead& response_head) {
  184. std::move(response_started_callback)
  185. .Run(response_head.headers ? response_head.headers->response_code() : -1,
  186. response_head.content_length);
  187. }
  188. void NetworkFetcherImpl::OnProgressCallback(ProgressCallback progress_callback,
  189. uint64_t current) {
  190. progress_callback.Run(base::saturated_cast<int64_t>(current));
  191. }
  192. NetworkFetcherChromiumFactory::NetworkFetcherChromiumFactory(
  193. scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory,
  194. SendCookiesPredicate cookie_predicate)
  195. : shared_url_network_factory_(shared_url_network_factory),
  196. cookie_predicate_(cookie_predicate) {}
  197. NetworkFetcherChromiumFactory::~NetworkFetcherChromiumFactory() = default;
  198. std::unique_ptr<NetworkFetcher> NetworkFetcherChromiumFactory::Create() const {
  199. return std::make_unique<NetworkFetcherImpl>(shared_url_network_factory_,
  200. cookie_predicate_);
  201. }
  202. } // namespace update_client