blob: 1b5c2c26c28c5d61b621559ae644125f74093fad [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)),
29 weak_ptr_factory_(this) {
30 fetcher_->SetRequestContext(request_context);
31 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
mmenke3cb1d73d2015-04-16 22:57:1932 net::LOAD_DO_NOT_SAVE_COOKIES);
treibf136dfb2014-09-25 17:37:4733 fetcher_->SetAutomaticallyRetryOnNetworkChanges(kNumRetries);
34 fetcher_->SaveResponseToFileAtPath(
35 path,
36 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
37
treibf79ed40d2015-09-22 12:38:0638 if (overwrite) {
39 fetcher_->Start();
40 } else {
41 base::PostTaskAndReplyWithResult(
42 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
43 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN).get(),
44 FROM_HERE,
45 base::Bind(&base::PathExists, path),
46 base::Bind(&FileDownloader::OnFileExistsCheckDone,
47 weak_ptr_factory_.GetWeakPtr()));
48 }
treibf136dfb2014-09-25 17:37:4749}
50
treibcffa6502015-08-06 09:12:2751FileDownloader::~FileDownloader() {}
treibf136dfb2014-09-25 17:37:4752
treibcffa6502015-08-06 09:12:2753void FileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
treibf136dfb2014-09-25 17:37:4754 DCHECK_EQ(fetcher_.get(), source);
treibcffa6502015-08-06 09:12:2755 // Delete |fetcher_| when we leave this method. This is necessary so the
56 // download file will be deleted if the download failed.
57 scoped_ptr<net::URLFetcher> fetcher(fetcher_.Pass());
treibf136dfb2014-09-25 17:37:4758
59 const net::URLRequestStatus& status = source->GetStatus();
60 if (!status.is_success()) {
treibf79ed40d2015-09-22 12:38:0661 DLOG(WARNING) << "URLRequestStatus error " << status.error()
62 << " while trying to download " << source->GetURL().spec();
treibf136dfb2014-09-25 17:37:4763 callback_.Run(false);
64 return;
65 }
66
67 int response_code = source->GetResponseCode();
68 if (response_code != net::HTTP_OK) {
treibf79ed40d2015-09-22 12:38:0669 DLOG(WARNING) << "HTTP error " << response_code
70 << " while trying to download " << source->GetURL().spec();
treibf136dfb2014-09-25 17:37:4771 callback_.Run(false);
72 return;
73 }
74
75 // Take ownership of the new file.
76 base::FilePath response_path;
77 bool success = source->GetResponseAsFilePath(true, &response_path);
78 callback_.Run(success);
79}
80
treibcffa6502015-08-06 09:12:2781void FileDownloader::OnFileExistsCheckDone(bool exists) {
82 if (exists)
treibf136dfb2014-09-25 17:37:4783 callback_.Run(true);
treibcffa6502015-08-06 09:12:2784 else
treibf136dfb2014-09-25 17:37:4785 fetcher_->Start();
treibf136dfb2014-09-25 17:37:4786}