1 // Copyright 2014 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 5 #include "components/component_updater/url_fetcher_downloader.h" 6 7 #include <stdint.h> 8 9 #include "base/logging.h" 10 #include "base/sequenced_task_runner.h" 11 #include "components/component_updater/component_updater_utils.h" 12 #include "net/base/load_flags.h" 13 #include "net/url_request/url_fetcher.h" 14 #include "url/gurl.h" 15 16 namespace component_updater { 17 18 UrlFetcherDownloader::UrlFetcherDownloader( 19 scoped_ptr<CrxDownloader> successor, 20 net::URLRequestContextGetter* context_getter, 21 scoped_refptr<base::SequencedTaskRunner> task_runner) 22 : CrxDownloader(successor.Pass()), 23 context_getter_(context_getter), 24 task_runner_(task_runner), 25 downloaded_bytes_(-1), 26 total_bytes_(-1) { 27 } 28 29 UrlFetcherDownloader::~UrlFetcherDownloader() { 30 DCHECK(thread_checker_.CalledOnValidThread()); 31 } 32 33 void UrlFetcherDownloader::DoStartDownload(const GURL& url) { 34 DCHECK(thread_checker_.CalledOnValidThread()); 35 36 url_fetcher_.reset( 37 net::URLFetcher::Create(0, url, net::URLFetcher::GET, this)); 38 url_fetcher_->SetRequestContext(context_getter_); 39 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 40 net::LOAD_DO_NOT_SAVE_COOKIES | 41 net::LOAD_DISABLE_CACHE); 42 url_fetcher_->SetAutomaticallyRetryOn5xx(false); 43 url_fetcher_->SaveResponseToTemporaryFile(task_runner_); 44 45 VLOG(1) << "Starting background download: " << url.spec(); 46 url_fetcher_->Start(); 47 48 download_start_time_ = base::Time::Now(); 49 50 downloaded_bytes_ = -1; 51 total_bytes_ = -1; 52 } 53 54 void UrlFetcherDownloader::OnURLFetchComplete(const net::URLFetcher* source) { 55 DCHECK(thread_checker_.CalledOnValidThread()); 56 57 const base::Time download_end_time(base::Time::Now()); 58 const base::TimeDelta download_time = 59 download_end_time >= download_start_time_ 60 ? download_end_time - download_start_time_ 61 : base::TimeDelta(); 62 63 // Consider a 5xx response from the server as an indication to terminate 64 // the request and avoid overloading the server in this case. 65 // is not accepting requests for the moment. 66 const int fetch_error(GetFetchError(*url_fetcher_)); 67 const bool is_handled = fetch_error == 0 || IsHttpServerError(fetch_error); 68 69 Result result; 70 result.error = fetch_error; 71 if (!fetch_error) { 72 source->GetResponseAsFilePath(true, &result.response); 73 } 74 result.downloaded_bytes = downloaded_bytes_; 75 result.total_bytes = total_bytes_; 76 77 DownloadMetrics download_metrics; 78 download_metrics.url = url(); 79 download_metrics.downloader = DownloadMetrics::kUrlFetcher; 80 download_metrics.error = fetch_error; 81 download_metrics.downloaded_bytes = downloaded_bytes_; 82 download_metrics.total_bytes = total_bytes_; 83 download_metrics.download_time_ms = download_time.InMilliseconds(); 84 85 base::FilePath local_path_; 86 source->GetResponseAsFilePath(false, &local_path_); 87 VLOG(1) << "Downloaded " << downloaded_bytes_ << " bytes in " 88 << download_time.InMilliseconds() << "ms from " 89 << source->GetURL().spec() << " to " << local_path_.value(); 90 CrxDownloader::OnDownloadComplete(is_handled, result, download_metrics); 91 } 92 93 void UrlFetcherDownloader::OnURLFetchDownloadProgress( 94 const net::URLFetcher* source, 95 int64_t current, 96 int64_t total) { 97 DCHECK(thread_checker_.CalledOnValidThread()); 98 99 downloaded_bytes_ = current; 100 total_bytes_ = total; 101 102 Result result; 103 result.downloaded_bytes = downloaded_bytes_; 104 result.total_bytes = total_bytes_; 105 106 OnDownloadProgress(result); 107 } 108 109 } // namespace component_updater 110