blob: 326369adbbb7f07351e425a96384c6df4d43d08c [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"
Marc Treib6b8ccbd2017-06-16 15:18:4911#include "base/task_runner_util.h"
fdoray15e8fb8c2017-04-27 12:10:3812#include "base/task_scheduler/post_task.h"
Marc Treib6b8ccbd2017-06-16 15:18:4913#include "base/task_scheduler/task_traits.h"
treibf136dfb2014-09-25 17:37:4714#include "net/base/load_flags.h"
15#include "net/http/http_status_code.h"
16#include "net/url_request/url_fetcher.h"
17#include "url/gurl.h"
18
treibf136dfb2014-09-25 17:37:4719using 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(
Marc Treib6b8ccbd2017-06-16 15:18:4940 base::CreateSequencedTaskRunnerWithTraits(
41 {base::MayBlock(), base::TaskPriority::BACKGROUND,
42 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}));
treibf136dfb2014-09-25 17:37:4743
treibf79ed40d2015-09-22 12:38:0644 if (overwrite) {
45 fetcher_->Start();
46 } else {
47 base::PostTaskAndReplyWithResult(
fdoray15e8fb8c2017-04-27 12:10:3848 base::CreateTaskRunnerWithTraits(
fdoray4ad14932017-05-03 21:21:1149 {base::MayBlock(), base::TaskPriority::BACKGROUND,
50 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})
maybellefae2b702015-10-12 10:11:5851 .get(),
52 FROM_HERE, base::Bind(&base::PathExists, local_path_),
treibf79ed40d2015-09-22 12:38:0653 base::Bind(&FileDownloader::OnFileExistsCheckDone,
54 weak_ptr_factory_.GetWeakPtr()));
55 }
treibf136dfb2014-09-25 17:37:4756}
57
treibcffa6502015-08-06 09:12:2758FileDownloader::~FileDownloader() {}
treibf136dfb2014-09-25 17:37:4759
treibcffa6502015-08-06 09:12:2760void FileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
treibf136dfb2014-09-25 17:37:4761 DCHECK_EQ(fetcher_.get(), source);
62
63 const net::URLRequestStatus& status = source->GetStatus();
64 if (!status.is_success()) {
treibf79ed40d2015-09-22 12:38:0665 DLOG(WARNING) << "URLRequestStatus error " << status.error()
66 << " while trying to download " << source->GetURL().spec();
treibf38cc252016-04-07 14:44:1167 callback_.Run(FAILED);
treibf136dfb2014-09-25 17:37:4768 return;
69 }
70
71 int response_code = source->GetResponseCode();
72 if (response_code != net::HTTP_OK) {
treibf79ed40d2015-09-22 12:38:0673 DLOG(WARNING) << "HTTP error " << response_code
74 << " while trying to download " << source->GetURL().spec();
treibf38cc252016-04-07 14:44:1175 callback_.Run(FAILED);
treibf136dfb2014-09-25 17:37:4776 return;
77 }
78
treibf136dfb2014-09-25 17:37:4779 base::FilePath response_path;
maybellefae2b702015-10-12 10:11:5880 bool success = source->GetResponseAsFilePath(false, &response_path);
81 if (!success) {
treibf38cc252016-04-07 14:44:1182 callback_.Run(FAILED);
maybellefae2b702015-10-12 10:11:5883 return;
84 }
85
86 base::PostTaskAndReplyWithResult(
fdoray15e8fb8c2017-04-27 12:10:3887 base::CreateTaskRunnerWithTraits(
fdoray4ad14932017-05-03 21:21:1188 {base::MayBlock(), base::TaskPriority::BACKGROUND,
89 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})
maybellefae2b702015-10-12 10:11:5890 .get(),
91 FROM_HERE, base::Bind(&base::Move, response_path, local_path_),
92 base::Bind(&FileDownloader::OnFileMoveDone,
93 weak_ptr_factory_.GetWeakPtr()));
treibf136dfb2014-09-25 17:37:4794}
95
treibcffa6502015-08-06 09:12:2796void FileDownloader::OnFileExistsCheckDone(bool exists) {
97 if (exists)
treibf38cc252016-04-07 14:44:1198 callback_.Run(EXISTS);
treibcffa6502015-08-06 09:12:2799 else
treibf136dfb2014-09-25 17:37:47100 fetcher_->Start();
treibf136dfb2014-09-25 17:37:47101}
maybellefae2b702015-10-12 10:11:58102
103void FileDownloader::OnFileMoveDone(bool success) {
104 if (!success) {
105 DLOG(WARNING) << "Could not move file to "
106 << local_path_.LossyDisplayName();
107 }
108
treibf38cc252016-04-07 14:44:11109 callback_.Run(success ? DOWNLOADED : FAILED);
maybellefae2b702015-10-12 10:11:58110}