OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 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/renderer_host/offline_resource_handler.h" |
| 6 |
| 7 #include <vector> |
| 8 |
| 9 #include "base/histogram.h" |
| 10 #include "base/logging.h" |
| 11 #include "base/singleton.h" |
| 12 #include "base/string_util.h" |
| 13 #include "chrome/browser/chrome_thread.h" |
| 14 #include "chrome/browser/chromeos/network_state_notifier.h" |
| 15 #include "chrome/browser/chromeos/offline/offline_load_page.h" |
| 16 #include "chrome/browser/chromeos/offline/offline_load_service.h" |
| 17 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
| 18 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" |
| 19 #include "chrome/common/url_constants.h" |
| 20 |
| 21 OfflineResourceHandler::OfflineResourceHandler( |
| 22 ResourceHandler* handler, |
| 23 int host_id, |
| 24 int route_id, |
| 25 ResourceDispatcherHost* rdh, |
| 26 URLRequest* request) |
| 27 : next_handler_(handler), |
| 28 process_host_id_(host_id), |
| 29 render_view_id_(route_id), |
| 30 rdh_(rdh), |
| 31 request_(request), |
| 32 deferred_request_id_(-1) { |
| 33 } |
| 34 |
| 35 bool OfflineResourceHandler::OnUploadProgress(int request_id, |
| 36 uint64 position, |
| 37 uint64 size) { |
| 38 return next_handler_->OnUploadProgress(request_id, position, size); |
| 39 } |
| 40 |
| 41 bool OfflineResourceHandler::OnRequestRedirected(int request_id, |
| 42 const GURL& new_url, |
| 43 ResourceResponse* response, |
| 44 bool* defer) { |
| 45 return next_handler_->OnRequestRedirected( |
| 46 request_id, new_url, response, defer); |
| 47 } |
| 48 |
| 49 bool OfflineResourceHandler::OnResponseStarted(int request_id, |
| 50 ResourceResponse* response) { |
| 51 return next_handler_->OnResponseStarted(request_id, response); |
| 52 } |
| 53 |
| 54 bool OfflineResourceHandler::OnResponseCompleted( |
| 55 int request_id, |
| 56 const URLRequestStatus& status, |
| 57 const std::string& security_info) { |
| 58 return next_handler_->OnResponseCompleted(request_id, status, security_info); |
| 59 } |
| 60 |
| 61 void OfflineResourceHandler::OnRequestClosed() { |
| 62 next_handler_->OnRequestClosed(); |
| 63 } |
| 64 |
| 65 bool OfflineResourceHandler::OnWillStart(int request_id, |
| 66 const GURL& url, |
| 67 bool* defer) { |
| 68 if (ShouldShowOfflinePage(url)) { |
| 69 deferred_request_id_ = request_id; |
| 70 deferred_url_ = url; |
| 71 DLOG(INFO) << "WillStart: this=" << this << ", request id=" << request_id; |
| 72 AddRef(); // Balanced with OnBlockingPageComplete |
| 73 ChromeThread::PostTask( |
| 74 ChromeThread::UI, FROM_HERE, |
| 75 NewRunnableMethod(this, &OfflineResourceHandler::ShowOfflinePage)); |
| 76 *defer = true; |
| 77 return true; |
| 78 } |
| 79 return next_handler_->OnWillStart(request_id, url, defer); |
| 80 } |
| 81 |
| 82 // We'll let the original event handler provide a buffer, and reuse it for |
| 83 // subsequent reads until we're done buffering. |
| 84 bool OfflineResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, |
| 85 int* buf_size, int min_size) { |
| 86 return next_handler_->OnWillRead(request_id, buf, buf_size, min_size); |
| 87 } |
| 88 |
| 89 bool OfflineResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { |
| 90 return next_handler_->OnReadCompleted(request_id, bytes_read); |
| 91 } |
| 92 |
| 93 void OfflineResourceHandler::OnBlockingPageComplete(bool proceed) { |
| 94 if (deferred_request_id_ < 0) { |
| 95 LOG(WARNING) << "OnBlockingPageComplete called after completion: " |
| 96 << " this=" << this << ", request_id=" |
| 97 << deferred_request_id_; |
| 98 NOTREACHED(); |
| 99 return; |
| 100 } |
| 101 if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { |
| 102 ChromeThread::PostTask( |
| 103 ChromeThread::IO, FROM_HERE, |
| 104 NewRunnableMethod(this, |
| 105 &OfflineResourceHandler::OnBlockingPageComplete, |
| 106 proceed)); |
| 107 return; |
| 108 } |
| 109 if (proceed) { |
| 110 Resume(); |
| 111 } else { |
| 112 int request_id = deferred_request_id_; |
| 113 ClearRequestInfo(); |
| 114 rdh_->CancelRequest(process_host_id_, request_id, false); |
| 115 } |
| 116 Release(); // Balanced with OnWillStart |
| 117 } |
| 118 |
| 119 void OfflineResourceHandler::ClearRequestInfo() { |
| 120 deferred_url_ = GURL(); |
| 121 deferred_request_id_ = -1; |
| 122 } |
| 123 |
| 124 bool OfflineResourceHandler::IsRemote(const GURL& url) const { |
| 125 return url.SchemeIs(chrome::kFtpScheme) || |
| 126 url.SchemeIs(chrome::kHttpScheme) || |
| 127 url.SchemeIs(chrome::kHttpsScheme); |
| 128 } |
| 129 |
| 130 bool OfflineResourceHandler::ShouldShowOfflinePage(const GURL& url) const { |
| 131 // Only check main frame. If the network is disconnected while |
| 132 // loading other resources, we'll simply show broken link/images. |
| 133 return IsRemote(url) && |
| 134 !chromeos::NetworkStateNotifier::is_connected() && |
| 135 ResourceDispatcherHost::InfoForRequest(request_)->resource_type() |
| 136 == ResourceType::MAIN_FRAME && |
| 137 !chromeos::OfflineLoadService::Get()->ShouldProceed( |
| 138 process_host_id_, render_view_id_, url); |
| 139 } |
| 140 |
| 141 void OfflineResourceHandler::Resume() { |
| 142 const GURL url = deferred_url_; |
| 143 int request_id = deferred_request_id_; |
| 144 ClearRequestInfo(); |
| 145 |
| 146 chromeos::OfflineLoadService::Get()->Proceeded( |
| 147 process_host_id_, render_view_id_, url); |
| 148 |
| 149 DCHECK_NE(request_id, -1); |
| 150 bool defer = false; |
| 151 DLOG(INFO) << "Resume load: this=" << this |
| 152 << ", request id=" << request_id; |
| 153 next_handler_->OnWillStart(request_id, url, &defer); |
| 154 if (!defer) |
| 155 rdh_->StartDeferredRequest(process_host_id_, request_id); |
| 156 } |
| 157 |
| 158 void OfflineResourceHandler::ShowOfflinePage() { |
| 159 chromeos::OfflineLoadPage::Show( |
| 160 process_host_id_, render_view_id_, deferred_url_, this); |
| 161 } |
OLD | NEW |