Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2823)

Unified Diff: chrome/browser/android/offline_pages/offline_page_request_offline_job.cc

Issue 2002433002: Handle online and offline redirects via interceptor and offline scheme (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698