blob: aa57047b7c2f62bbe5d959df52aacae95f794c74 [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"
11#include "content/public/browser/browser_thread.h"
12#include "net/base/load_flags.h"
13#include "net/http/http_status_code.h"
14#include "net/url_request/url_fetcher.h"
15#include "url/gurl.h"
16
17using content::BrowserThread;
18using net::URLFetcher;
19
20const int kNumRetries = 1;
21
treibcffa6502015-08-06 09:12:2722FileDownloader::FileDownloader(const GURL& url,
23 const base::FilePath& path,
treibf79ed40d2015-09-22 12:38:0624 bool overwrite,
treibcffa6502015-08-06 09:12:2725 net::URLRequestContextGetter* request_context,
26 const DownloadFinishedCallback& callback)
treibf136dfb2014-09-25 17:37:4727 : callback_(callback),
28 fetcher_(URLFetcher::Create(url, URLFetcher::GET, this)),
maybellefae2b702015-10-12 10:11:5829 local_path_(path),
treibf136dfb2014-09-25 17:37:4730 weak_ptr_factory_(this) {
31 fetcher_->SetRequestContext(request_context);
32 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
mmenke3cb1d73d2015-04-16 22:57:1933 net::LOAD_DO_NOT_SAVE_COOKIES);
treibf136dfb2014-09-25 17:37:4734 fetcher_->SetAutomaticallyRetryOnNetworkChanges(kNumRetries);
maybellefae2b702015-10-12 10:11:5835 fetcher_->SaveResponseToTemporaryFile(
thestig529ad8a2016-07-08 20:30:1236 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE));
treibf136dfb2014-09-25 17:37:4737
treibf79ed40d2015-09-22 12:38:0638 if (overwrite) {
39 fetcher_->Start();
40 } else {
41 base::PostTaskAndReplyWithResult(
maybellefae2b702015-10-12 10:11:5842 BrowserThread::GetBlockingPool()
43 ->GetTaskRunnerWithShutdownBehavior(
44 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
45 .get(),
46 FROM_HERE, base::Bind(&base::PathExists, local_path_),
treibf79ed40d2015-09-22 12:38:0647 base::Bind(&FileDownloader::OnFileExistsCheckDone,
48 weak_ptr_factory_.GetWeakPtr()));
49 }
treibf136dfb2014-09-25 17:37:4750}
51
treibcffa6502015-08-06 09:12:2752FileDownloader::~FileDownloader() {}
treibf136dfb2014-09-25 17:37:4753
treibcffa6502015-08-06 09:12:2754void FileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
treibf136dfb2014-09-25 17:37:4755 DCHECK_EQ(fetcher_.get(), source);
treibf136dfb2014-09-25 17:37:4756
57 const net::URLRequestStatus& status = source->GetStatus();
58 if (!status.is_success()) {
treibf79ed40d2015-09-22 12:38:0659 DLOG(WARNING) << "URLRequestStatus error " << status.error()
60 << " while trying to download " << source->GetURL().spec();
treibf38cc252016-04-07 14:44:1161 callback_.Run(FAILED);
treibf136dfb2014-09-25 17:37:4762 return;
63 }
64
65 int response_code = source->GetResponseCode();
66 if (response_code != net::HTTP_OK) {
treibf79ed40d2015-09-22 12:38:0667 DLOG(WARNING) << "HTTP error " << response_code
68 << " while trying to download " << source->GetURL().spec();
treibf38cc252016-04-07 14:44:1169 callback_.Run(FAILED);
treibf136dfb2014-09-25 17:37:4770 return;
71 }
72
treibf136dfb2014-09-25 17:37:4773 base::FilePath response_path;
maybellefae2b702015-10-12 10:11:5874 bool success = source->GetResponseAsFilePath(false, &response_path);
75 if (!success) {
treibf38cc252016-04-07 14:44:1176 callback_.Run(FAILED);
maybellefae2b702015-10-12 10:11:5877 return;
78 }
79
80 base::PostTaskAndReplyWithResult(
81 BrowserThread::GetBlockingPool()
82 ->GetTaskRunnerWithShutdownBehavior(
83 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
84 .get(),
85 FROM_HERE, base::Bind(&base::Move, response_path, local_path_),
86 base::Bind(&FileDownloader::OnFileMoveDone,
87 weak_ptr_factory_.GetWeakPtr()));
treibf136dfb2014-09-25 17:37:4788}
89
treibcffa6502015-08-06 09:12:2790void FileDownloader::OnFileExistsCheckDone(bool exists) {
91 if (exists)
treibf38cc252016-04-07 14:44:1192 callback_.Run(EXISTS);
treibcffa6502015-08-06 09:12:2793 else
treibf136dfb2014-09-25 17:37:4794 fetcher_->Start();
treibf136dfb2014-09-25 17:37:4795}
maybellefae2b702015-10-12 10:11:5896
97void FileDownloader::OnFileMoveDone(bool success) {
98 if (!success) {
99 DLOG(WARNING) << "Could not move file to "
100 << local_path_.LossyDisplayName();
101 }
102
treibf38cc252016-04-07 14:44:11103 callback_.Run(success ? DOWNLOADED : FAILED);
maybellefae2b702015-10-12 10:11:58104}