blob: 87ade7a90d09034fae0bc2556fd17e85ee767d4d [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
treibcffa6502015-08-06 09:12:2723FileDownloader::FileDownloader(const GURL& url,
24 const base::FilePath& path,
treibf79ed40d2015-09-22 12:38:0625 bool overwrite,
treibcffa6502015-08-06 09:12:2726 net::URLRequestContextGetter* request_context,
27 const DownloadFinishedCallback& callback)
treibf136dfb2014-09-25 17:37:4728 : callback_(callback),
29 fetcher_(URLFetcher::Create(url, URLFetcher::GET, this)),
maybellefae2b702015-10-12 10:11:5830 local_path_(path),
treibf136dfb2014-09-25 17:37:4731 weak_ptr_factory_(this) {
32 fetcher_->SetRequestContext(request_context);
33 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
mmenke3cb1d73d2015-04-16 22:57:1934 net::LOAD_DO_NOT_SAVE_COOKIES);
treibf136dfb2014-09-25 17:37:4735 fetcher_->SetAutomaticallyRetryOnNetworkChanges(kNumRetries);
maybellefae2b702015-10-12 10:11:5836 fetcher_->SaveResponseToTemporaryFile(
thestig529ad8a2016-07-08 20:30:1237 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE));
treibf136dfb2014-09-25 17:37:4738
treibf79ed40d2015-09-22 12:38:0639 if (overwrite) {
40 fetcher_->Start();
41 } else {
42 base::PostTaskAndReplyWithResult(
maybellefae2b702015-10-12 10:11:5843 BrowserThread::GetBlockingPool()
44 ->GetTaskRunnerWithShutdownBehavior(
45 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
46 .get(),
47 FROM_HERE, base::Bind(&base::PathExists, local_path_),
treibf79ed40d2015-09-22 12:38:0648 base::Bind(&FileDownloader::OnFileExistsCheckDone,
49 weak_ptr_factory_.GetWeakPtr()));
50 }
treibf136dfb2014-09-25 17:37:4751}
52
treibcffa6502015-08-06 09:12:2753FileDownloader::~FileDownloader() {}
treibf136dfb2014-09-25 17:37:4754
treibcffa6502015-08-06 09:12:2755void FileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
treibf136dfb2014-09-25 17:37:4756 DCHECK_EQ(fetcher_.get(), source);
57
58 const net::URLRequestStatus& status = source->GetStatus();
59 if (!status.is_success()) {
treibf79ed40d2015-09-22 12:38:0660 DLOG(WARNING) << "URLRequestStatus error " << status.error()
61 << " while trying to download " << source->GetURL().spec();
treibf38cc252016-04-07 14:44:1162 callback_.Run(FAILED);
treibf136dfb2014-09-25 17:37:4763 return;
64 }
65
66 int response_code = source->GetResponseCode();
67 if (response_code != net::HTTP_OK) {
treibf79ed40d2015-09-22 12:38:0668 DLOG(WARNING) << "HTTP error " << response_code
69 << " while trying to download " << source->GetURL().spec();
treibf38cc252016-04-07 14:44:1170 callback_.Run(FAILED);
treibf136dfb2014-09-25 17:37:4771 return;
72 }
73
treibf136dfb2014-09-25 17:37:4774 base::FilePath response_path;
maybellefae2b702015-10-12 10:11:5875 bool success = source->GetResponseAsFilePath(false, &response_path);
76 if (!success) {
treibf38cc252016-04-07 14:44:1177 callback_.Run(FAILED);
maybellefae2b702015-10-12 10:11:5878 return;
79 }
80
81 base::PostTaskAndReplyWithResult(
82 BrowserThread::GetBlockingPool()
83 ->GetTaskRunnerWithShutdownBehavior(
84 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
85 .get(),
86 FROM_HERE, base::Bind(&base::Move, response_path, local_path_),
87 base::Bind(&FileDownloader::OnFileMoveDone,
88 weak_ptr_factory_.GetWeakPtr()));
treibf136dfb2014-09-25 17:37:4789}
90
treibcffa6502015-08-06 09:12:2791void FileDownloader::OnFileExistsCheckDone(bool exists) {
92 if (exists)
treibf38cc252016-04-07 14:44:1193 callback_.Run(EXISTS);
treibcffa6502015-08-06 09:12:2794 else
treibf136dfb2014-09-25 17:37:4795 fetcher_->Start();
treibf136dfb2014-09-25 17:37:4796}
maybellefae2b702015-10-12 10:11:5897
98void FileDownloader::OnFileMoveDone(bool success) {
99 if (!success) {
100 DLOG(WARNING) << "Could not move file to "
101 << local_path_.LossyDisplayName();
102 }
103
treibf38cc252016-04-07 14:44:11104 callback_.Run(success ? DOWNLOADED : FAILED);
maybellefae2b702015-10-12 10:11:58105}