| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/android/offline_pages/offline_page_request_offline_job.
h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" |
| 9 #include "base/logging.h" |
| 10 #include "base/threading/thread_task_runner_handle.h" |
| 11 #include "chrome/browser/android/offline_pages/offline_page_utils.h" |
| 12 #include "chrome/browser/browser_process.h" |
| 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/profiles/profile_manager.h" |
| 15 #include "chrome/common/url_constants.h" |
| 16 #include "content/public/browser/browser_thread.h" |
| 17 #include "net/base/filename_util.h" |
| 18 #include "net/http/http_request_headers.h" |
| 19 #include "net/http/http_util.h" |
| 20 #include "net/url_request/url_request.h" |
| 21 |
| 22 using content::BrowserThread; |
| 23 |
| 24 namespace offline_pages { |
| 25 |
| 26 namespace { |
| 27 |
| 28 typedef base::Callback<void(const base::FilePath&)> |
| 29 GetOfflineFilePathCompleteCallback; |
| 30 |
| 31 void DidGetOfflineURLForOnlineURL(GetOfflineFilePathCompleteCallback callback, |
| 32 const GURL& offline_file_url) { |
| 33 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 34 |
| 35 base::FilePath offline_file_path; |
| 36 if (offline_file_url.is_valid()) |
| 37 net::FileURLToFilePath(offline_file_url, &offline_file_path); |
| 38 |
| 39 BrowserThread::PostTask( |
| 40 BrowserThread::IO, |
| 41 FROM_HERE, |
| 42 base::Bind(callback, offline_file_path)); |
| 43 } |
| 44 |
| 45 void GetOfflineFilePathOnUIThread(void* profile_id, |
| 46 const GURL& online_url, |
| 47 GetOfflineFilePathCompleteCallback callback) { |
| 48 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 49 |
| 50 // |profile_id| needs to be checked with ProfileManager::IsValidProfile |
| 51 // before using it. |
| 52 if (!g_browser_process->profile_manager()->IsValidProfile(profile_id)) { |
| 53 DidGetOfflineURLForOnlineURL(callback, GURL()); |
| 54 return; |
| 55 } |
| 56 |
| 57 Profile* profile = reinterpret_cast<Profile*>(profile_id); |
| 58 OfflinePageUtils::GetOfflineURLForOnlineURL( |
| 59 profile, online_url, |
| 60 base::Bind(&DidGetOfflineURLForOnlineURL, callback)); |
| 61 } |
| 62 |
| 63 } // namespace |
| 64 |
| 65 OfflinePageRequestOfflineJob::OfflinePageRequestOfflineJob( |
| 66 void* profile_id, |
| 67 net::URLRequest* request, |
| 68 net::NetworkDelegate* network_delegate) |
| 69 : net::URLRequestFileJob( |
| 70 request, |
| 71 network_delegate, |
| 72 base::FilePath(), |
| 73 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( |
| 74 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), |
| 75 profile_id_(profile_id), |
| 76 weak_ptr_factory_(this) { |
| 77 } |
| 78 |
| 79 OfflinePageRequestOfflineJob::~OfflinePageRequestOfflineJob() { |
| 80 } |
| 81 |
| 82 void OfflinePageRequestOfflineJob::Start() { |
| 83 // Post a task to invoke StartAsync asynchronously to avoid re-entering the |
| 84 // delegate, because NotifyStartError is not legal to call synchronously in |
| 85 // Start(). |
| 86 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 87 FROM_HERE, base::Bind(&OfflinePageRequestOfflineJob::StartAsync, |
| 88 weak_ptr_factory_.GetWeakPtr())); |
| 89 } |
| 90 |
| 91 void OfflinePageRequestOfflineJob::Kill() { |
| 92 net::URLRequestJob::Kill(); |
| 93 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 94 } |
| 95 |
| 96 void OfflinePageRequestOfflineJob::StartAsync() { |
| 97 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 98 |
| 99 // Only GET request is supported. |
| 100 if (request()->method() != "GET") { |
| 101 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| 102 net::ERR_METHOD_NOT_SUPPORTED)); |
| 103 return; |
| 104 } |
| 105 |
| 106 // Checks if the scheme is correct. |
| 107 if (!request()->url().SchemeIs(chrome::kOfflinePageScheme)) { |
| 108 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| 109 net::ERR_INVALID_URL)); |
| 110 return; |
| 111 } |
| 112 |
| 113 // Extracts the online URL embedded in the offline URL that is denoted as |
| 114 // "offline:http://..." |
| 115 GURL online_url = GURL(request()->url().GetContent()); |
| 116 if (!online_url.is_valid() || !online_url.SchemeIsHTTPOrHTTPS()) { |
| 117 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| 118 net::ERR_INVALID_URL)); |
| 119 return; |
| 120 } |
| 121 |
| 122 BrowserThread::PostTask( |
| 123 BrowserThread::UI, |
| 124 FROM_HERE, |
| 125 base::Bind(&GetOfflineFilePathOnUIThread, |
| 126 profile_id_, |
| 127 online_url, |
| 128 base::Bind(&OfflinePageRequestOfflineJob::LoadFile, |
| 129 weak_ptr_factory_.GetWeakPtr()))); |
| 130 } |
| 131 |
| 132 void OfflinePageRequestOfflineJob::LoadFile( |
| 133 const base::FilePath& offline_file_path) { |
| 134 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 135 |
| 136 if (offline_file_path.empty()) { |
| 137 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| 138 net::ERR_INVALID_URL)); |
| 139 return; |
| 140 } |
| 141 |
| 142 file_path_ = offline_file_path; |
| 143 URLRequestFileJob::Start(); |
| 144 } |
| 145 |
| 146 } // namespace offline_pages |
| OLD | NEW |