103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/url_fetcher_downloader.h" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <stdint.h> 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/logging.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/sequenced_task_runner.h" 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_utils.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/base/load_flags.h" 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/url_request/url_fetcher.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "url/gurl.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace component_updater { 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)UrlFetcherDownloader::UrlFetcherDownloader( 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<CrxDownloader> successor, 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::URLRequestContextGetter* context_getter, 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_refptr<base::SequencedTaskRunner> task_runner) 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : CrxDownloader(successor.Pass()), 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) context_getter_(context_getter), 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) task_runner_(task_runner), 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) downloaded_bytes_(-1), 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_bytes_(-1) { 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UrlFetcherDownloader::~UrlFetcherDownloader() { 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void UrlFetcherDownloader::DoStartDownload(const GURL& url) { 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url_fetcher_.reset( 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) net::URLFetcher::Create(0, url, net::URLFetcher::GET, this)); 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) url_fetcher_->SetRequestContext(context_getter_); 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::LOAD_DO_NOT_SAVE_COOKIES | 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::LOAD_DISABLE_CACHE); 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) url_fetcher_->SetAutomaticallyRetryOn5xx(false); 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) url_fetcher_->SaveResponseToTemporaryFile(task_runner_); 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Starting background download: " << url.spec(); 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) url_fetcher_->Start(); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) download_start_time_ = base::Time::Now(); 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) downloaded_bytes_ = -1; 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_bytes_ = -1; 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void UrlFetcherDownloader::OnURLFetchComplete(const net::URLFetcher* source) { 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Time download_end_time(base::Time::Now()); 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::TimeDelta download_time = 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) download_end_time >= download_start_time_ 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ? download_end_time - download_start_time_ 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : base::TimeDelta(); 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Consider a 5xx response from the server as an indication to terminate 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // the request and avoid overloading the server in this case. 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // is not accepting requests for the moment. 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const int fetch_error(GetFetchError(*url_fetcher_)); 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const bool is_handled = fetch_error == 0 || IsHttpServerError(fetch_error); 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Result result; 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) result.error = fetch_error; 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!fetch_error) { 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) source->GetResponseAsFilePath(true, &result.response); 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result.downloaded_bytes = downloaded_bytes_; 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result.total_bytes = total_bytes_; 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DownloadMetrics download_metrics; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) download_metrics.url = url(); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) download_metrics.downloader = DownloadMetrics::kUrlFetcher; 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) download_metrics.error = fetch_error; 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) download_metrics.downloaded_bytes = downloaded_bytes_; 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) download_metrics.total_bytes = total_bytes_; 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) download_metrics.download_time_ms = download_time.InMilliseconds(); 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::FilePath local_path_; 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu source->GetResponseAsFilePath(false, &local_path_); 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Downloaded " << downloaded_bytes_ << " bytes in " 885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << download_time.InMilliseconds() << "ms from " 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << source->GetURL().spec() << " to " << local_path_.value(); 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CrxDownloader::OnDownloadComplete(is_handled, result, download_metrics); 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void UrlFetcherDownloader::OnURLFetchDownloadProgress( 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::URLFetcher* source, 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int64_t current, 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int64_t total) { 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) downloaded_bytes_ = current; 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_bytes_ = total; 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Result result; 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result.downloaded_bytes = downloaded_bytes_; 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result.total_bytes = total_bytes_; 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) OnDownloadProgress(result); 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace component_updater 110