| Index: chrome/browser/android/offline_pages/offline_page_request_offline_job.cc
|
| diff --git a/chrome/browser/android/offline_pages/offline_page_request_offline_job.cc b/chrome/browser/android/offline_pages/offline_page_request_offline_job.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a75342d069b3128da495125bbfd70dea0c382e95
|
| --- /dev/null
|
| +++ b/chrome/browser/android/offline_pages/offline_page_request_offline_job.cc
|
| @@ -0,0 +1,146 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/android/offline_pages/offline_page_request_offline_job.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/files/file_path.h"
|
| +#include "base/logging.h"
|
| +#include "base/threading/thread_task_runner_handle.h"
|
| +#include "chrome/browser/android/offline_pages/offline_page_utils.h"
|
| +#include "chrome/browser/browser_process.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/profiles/profile_manager.h"
|
| +#include "chrome/common/url_constants.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "net/base/filename_util.h"
|
| +#include "net/http/http_request_headers.h"
|
| +#include "net/http/http_util.h"
|
| +#include "net/url_request/url_request.h"
|
| +
|
| +using content::BrowserThread;
|
| +
|
| +namespace offline_pages {
|
| +
|
| +namespace {
|
| +
|
| +typedef base::Callback<void(const base::FilePath&)>
|
| +GetOfflineFilePathCompleteCallback;
|
| +
|
| +void DidGetOfflineURLForOnlineURL(GetOfflineFilePathCompleteCallback callback,
|
| + const GURL& offline_file_url) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +
|
| + base::FilePath offline_file_path;
|
| + if (offline_file_url.is_valid())
|
| + net::FileURLToFilePath(offline_file_url, &offline_file_path);
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO,
|
| + FROM_HERE,
|
| + base::Bind(callback, offline_file_path));
|
| +}
|
| +
|
| +void GetOfflineFilePathOnUIThread(void* profile_id,
|
| + const GURL& online_url,
|
| + GetOfflineFilePathCompleteCallback callback) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +
|
| + // |profile_id| needs to be checked with ProfileManager::IsValidProfile
|
| + // before using it.
|
| + if (!g_browser_process->profile_manager()->IsValidProfile(profile_id)) {
|
| + DidGetOfflineURLForOnlineURL(callback, GURL());
|
| + return;
|
| + }
|
| +
|
| + Profile* profile = reinterpret_cast<Profile*>(profile_id);
|
| + OfflinePageUtils::GetOfflineURLForOnlineURL(
|
| + profile, online_url,
|
| + base::Bind(&DidGetOfflineURLForOnlineURL, callback));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +OfflinePageRequestOfflineJob::OfflinePageRequestOfflineJob(
|
| + void* profile_id,
|
| + net::URLRequest* request,
|
| + net::NetworkDelegate* network_delegate)
|
| + : net::URLRequestFileJob(
|
| + request,
|
| + network_delegate,
|
| + base::FilePath(),
|
| + BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
|
| + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
|
| + profile_id_(profile_id),
|
| + weak_ptr_factory_(this) {
|
| +}
|
| +
|
| +OfflinePageRequestOfflineJob::~OfflinePageRequestOfflineJob() {
|
| +}
|
| +
|
| +void OfflinePageRequestOfflineJob::Start() {
|
| + // Post a task to invoke StartAsync asynchronously to avoid re-entering the
|
| + // delegate, because NotifyStartError is not legal to call synchronously in
|
| + // Start().
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::Bind(&OfflinePageRequestOfflineJob::StartAsync,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void OfflinePageRequestOfflineJob::Kill() {
|
| + net::URLRequestJob::Kill();
|
| + weak_ptr_factory_.InvalidateWeakPtrs();
|
| +}
|
| +
|
| +void OfflinePageRequestOfflineJob::StartAsync() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| +
|
| + // Only GET request is supported.
|
| + if (request()->method() != "GET") {
|
| + NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
| + net::ERR_METHOD_NOT_SUPPORTED));
|
| + return;
|
| + }
|
| +
|
| + // Checks if the scheme is correct.
|
| + if (!request()->url().SchemeIs(chrome::kOfflinePageScheme)) {
|
| + NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
| + net::ERR_INVALID_URL));
|
| + return;
|
| + }
|
| +
|
| + // Extracts the online URL embedded in the offline URL that is denoted as
|
| + // "offline:http://..."
|
| + GURL online_url = GURL(request()->url().GetContent());
|
| + if (!online_url.is_valid() || !online_url.SchemeIsHTTPOrHTTPS()) {
|
| + NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
| + net::ERR_INVALID_URL));
|
| + return;
|
| + }
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(&GetOfflineFilePathOnUIThread,
|
| + profile_id_,
|
| + online_url,
|
| + base::Bind(&OfflinePageRequestOfflineJob::LoadFile,
|
| + weak_ptr_factory_.GetWeakPtr())));
|
| +}
|
| +
|
| +void OfflinePageRequestOfflineJob::LoadFile(
|
| + const base::FilePath& offline_file_path) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| +
|
| + if (offline_file_path.empty()) {
|
| + NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
| + net::ERR_INVALID_URL));
|
| + return;
|
| + }
|
| +
|
| + file_path_ = offline_file_path;
|
| + URLRequestFileJob::Start();
|
| +}
|
| +
|
| +} // namespace offline_pages
|
|
|