blob: ffbb4f96680d0740295fe45f3f16c8f93ff18e63 [file] [log] [blame]
treibcffa6502015-08-06 09:12:271// Copyright 2015 The Chromium Authors. All rights reserved.
treibf136dfb2014-09-25 17:37:472// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
treibcffa6502015-08-06 09:12:275#include "chrome/browser/net/file_downloader.h"
treibf136dfb2014-09-25 17:37:476
treibcffa6502015-08-06 09:12:277#include "base/bind.h"
treibf136dfb2014-09-25 17:37:478#include "base/files/file_path.h"
9#include "base/files/file_util.h"
10#include "base/logging.h"
tzikebc72902017-02-16 07:52:0511#include "base/threading/sequenced_worker_pool.h"
treibf136dfb2014-09-25 17:37:4712#include "content/public/browser/browser_thread.h"
13#include "net/base/load_flags.h"
14#include "net/http/http_status_code.h"
15#include "net/url_request/url_fetcher.h"
16#include "url/gurl.h"
17
18using content::BrowserThread;
19using net::URLFetcher;
20
21const int kNumRetries = 1;
22
rhalavati5f1caa2b2017-02-25 08:22:1623FileDownloader::FileDownloader(
24 const GURL& url,
25 const base::FilePath& path,
26 bool overwrite,
27 net::URLRequestContextGetter* request_context,
28 const DownloadFinishedCallback& callback,
29 const net::NetworkTrafficAnnotationTag& traffic_annotation)
treibf136dfb2014-09-25 17:37:4730 : callback_(callback),
rhalavati5f1caa2b2017-02-25 08:22:1631 fetcher_(
32 URLFetcher::Create(url, URLFetcher::GET, this, traffic_annotation)),
maybellefae2b702015-10-12 10:11:5833 local_path_(path),
treibf136dfb2014-09-25 17:37:4734 weak_ptr_factory_(this) {
35 fetcher_->SetRequestContext(request_context);
36 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
mmenke3cb1d73d2015-04-16 22:57:1937 net::LOAD_DO_NOT_SAVE_COOKIES);
treibf136dfb2014-09-25 17:37:4738 fetcher_->SetAutomaticallyRetryOnNetworkChanges(kNumRetries);
maybellefae2b702015-10-12 10:11:5839 fetcher_->SaveResponseToTemporaryFile(
thestig529ad8a2016-07-08 20:30:1240 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE));
treibf136dfb2014-09-25 17:37:4741
treibf79ed40d2015-09-22 12:38:0642 if (overwrite) {
43 fetcher_->Start();
44 } else {
45 base::PostTaskAndReplyWithResult(
maybellefae2b702015-10-12 10:11:5846 BrowserThread::GetBlockingPool()
47 ->GetTaskRunnerWithShutdownBehavior(
48 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
49 .get(),
50 FROM_HERE, base::Bind(&base::PathExists, local_path_),
treibf79ed40d2015-09-22 12:38:0651 base::Bind(&FileDownloader::OnFileExistsCheckDone,
52 weak_ptr_factory_.GetWeakPtr()));
53 }
treibf136dfb2014-09-25 17:37:4754}
55
treibcffa6502015-08-06 09:12:2756FileDownloader::~FileDownloader() {}
treibf136dfb2014-09-25 17:37:4757
treibcffa6502015-08-06 09:12:2758void FileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
treibf136dfb2014-09-25 17:37:4759 DCHECK_EQ(fetcher_.get(), source);
60
61 const net::URLRequestStatus& status = source->GetStatus();
62 if (!status.is_success()) {
treibf79ed40d2015-09-22 12:38:0663 DLOG(WARNING) << "URLRequestStatus error " << status.error()
64 << " while trying to download " << source->GetURL().spec();
treibf38cc252016-04-07 14:44:1165 callback_.Run(FAILED);
treibf136dfb2014-09-25 17:37:4766 return;
67 }
68
69 int response_code = source->GetResponseCode();
70 if (response_code != net::HTTP_OK) {
treibf79ed40d2015-09-22 12:38:0671 DLOG(WARNING) << "HTTP error " << response_code
72 << " while trying to download " << source->GetURL().spec();
treibf38cc252016-04-07 14:44:1173 callback_.Run(FAILED);
treibf136dfb2014-09-25 17:37:4774 return;
75 }
76
treibf136dfb2014-09-25 17:37:4777 base::FilePath response_path;
maybellefae2b702015-10-12 10:11:5878 bool success = source->GetResponseAsFilePath(false, &response_path);
79 if (!success) {
treibf38cc252016-04-07 14:44:1180 callback_.Run(FAILED);
maybellefae2b702015-10-12 10:11:5881 return;
82 }
83
84 base::PostTaskAndReplyWithResult(
85 BrowserThread::GetBlockingPool()
86 ->GetTaskRunnerWithShutdownBehavior(
87 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
88 .get(),
89 FROM_HERE, base::Bind(&base::Move, response_path, local_path_),
90 base::Bind(&FileDownloader::OnFileMoveDone,
91 weak_ptr_factory_.GetWeakPtr()));
treibf136dfb2014-09-25 17:37:4792}
93
treibcffa6502015-08-06 09:12:2794void FileDownloader::OnFileExistsCheckDone(bool exists) {
95 if (exists)
treibf38cc252016-04-07 14:44:1196 callback_.Run(EXISTS);
treibcffa6502015-08-06 09:12:2797 else
treibf136dfb2014-09-25 17:37:4798 fetcher_->Start();
treibf136dfb2014-09-25 17:37:4799}
maybellefae2b702015-10-12 10:11:58100
101void FileDownloader::OnFileMoveDone(bool success) {
102 if (!success) {
103 DLOG(WARNING) << "Could not move file to "
104 << local_path_.LossyDisplayName();
105 }
106
treibf38cc252016-04-07 14:44:11107 callback_.Run(success ? DOWNLOADED : FAILED);
maybellefae2b702015-10-12 10:11:58108}