Index: chrome/browser/renderer_host/offline_resource_handler.cc |
diff --git a/chrome/browser/renderer_host/offline_resource_handler.cc b/chrome/browser/renderer_host/offline_resource_handler.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c270d14d377a2892a250b0542f3897e440feff4e |
--- /dev/null |
+++ b/chrome/browser/renderer_host/offline_resource_handler.cc |
@@ -0,0 +1,161 @@ |
+// Copyright (c) 2010 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/renderer_host/offline_resource_handler.h" |
+ |
+#include <vector> |
+ |
+#include "base/histogram.h" |
+#include "base/logging.h" |
+#include "base/singleton.h" |
+#include "base/string_util.h" |
+#include "chrome/browser/chrome_thread.h" |
+#include "chrome/browser/chromeos/network_state_notifier.h" |
+#include "chrome/browser/chromeos/offline/offline_load_page.h" |
+#include "chrome/browser/chromeos/offline/offline_load_service.h" |
+#include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
+#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" |
+#include "chrome/common/url_constants.h" |
+ |
+OfflineResourceHandler::OfflineResourceHandler( |
+ ResourceHandler* handler, |
+ int host_id, |
+ int route_id, |
+ ResourceDispatcherHost* rdh, |
+ URLRequest* request) |
+ : next_handler_(handler), |
+ process_host_id_(host_id), |
+ render_view_id_(route_id), |
+ rdh_(rdh), |
+ request_(request), |
+ deferred_request_id_(-1) { |
+} |
+ |
+bool OfflineResourceHandler::OnUploadProgress(int request_id, |
+ uint64 position, |
+ uint64 size) { |
+ return next_handler_->OnUploadProgress(request_id, position, size); |
+} |
+ |
+bool OfflineResourceHandler::OnRequestRedirected(int request_id, |
+ const GURL& new_url, |
+ ResourceResponse* response, |
+ bool* defer) { |
+ return next_handler_->OnRequestRedirected( |
+ request_id, new_url, response, defer); |
+} |
+ |
+bool OfflineResourceHandler::OnResponseStarted(int request_id, |
+ ResourceResponse* response) { |
+ return next_handler_->OnResponseStarted(request_id, response); |
+} |
+ |
+bool OfflineResourceHandler::OnResponseCompleted( |
+ int request_id, |
+ const URLRequestStatus& status, |
+ const std::string& security_info) { |
+ return next_handler_->OnResponseCompleted(request_id, status, security_info); |
+} |
+ |
+void OfflineResourceHandler::OnRequestClosed() { |
+ next_handler_->OnRequestClosed(); |
+} |
+ |
+bool OfflineResourceHandler::OnWillStart(int request_id, |
+ const GURL& url, |
+ bool* defer) { |
+ if (ShouldShowOfflinePage(url)) { |
+ deferred_request_id_ = request_id; |
+ deferred_url_ = url; |
+ DLOG(INFO) << "WillStart: this=" << this << ", request id=" << request_id; |
+ AddRef(); // Balanced with OnBlockingPageComplete |
+ ChromeThread::PostTask( |
+ ChromeThread::UI, FROM_HERE, |
+ NewRunnableMethod(this, &OfflineResourceHandler::ShowOfflinePage)); |
+ *defer = true; |
+ return true; |
+ } |
+ return next_handler_->OnWillStart(request_id, url, defer); |
+} |
+ |
+// We'll let the original event handler provide a buffer, and reuse it for |
+// subsequent reads until we're done buffering. |
+bool OfflineResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, |
+ int* buf_size, int min_size) { |
+ return next_handler_->OnWillRead(request_id, buf, buf_size, min_size); |
+} |
+ |
+bool OfflineResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { |
+ return next_handler_->OnReadCompleted(request_id, bytes_read); |
+} |
+ |
+void OfflineResourceHandler::OnBlockingPageComplete(bool proceed) { |
+ if (deferred_request_id_ < 0) { |
+ LOG(WARNING) << "OnBlockingPageComplete called after completion: " |
+ << " this=" << this << ", request_id=" |
+ << deferred_request_id_; |
+ NOTREACHED(); |
+ return; |
+ } |
+ if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { |
+ ChromeThread::PostTask( |
+ ChromeThread::IO, FROM_HERE, |
+ NewRunnableMethod(this, |
+ &OfflineResourceHandler::OnBlockingPageComplete, |
+ proceed)); |
+ return; |
+ } |
+ if (proceed) { |
+ Resume(); |
+ } else { |
+ int request_id = deferred_request_id_; |
+ ClearRequestInfo(); |
+ rdh_->CancelRequest(process_host_id_, request_id, false); |
+ } |
+ Release(); // Balanced with OnWillStart |
+} |
+ |
+void OfflineResourceHandler::ClearRequestInfo() { |
+ deferred_url_ = GURL(); |
+ deferred_request_id_ = -1; |
+} |
+ |
+bool OfflineResourceHandler::IsRemote(const GURL& url) const { |
+ return url.SchemeIs(chrome::kFtpScheme) || |
+ url.SchemeIs(chrome::kHttpScheme) || |
+ url.SchemeIs(chrome::kHttpsScheme); |
+} |
+ |
+bool OfflineResourceHandler::ShouldShowOfflinePage(const GURL& url) const { |
+ // Only check main frame. If the network is disconnected while |
+ // loading other resources, we'll simply show broken link/images. |
+ return IsRemote(url) && |
+ !chromeos::NetworkStateNotifier::is_connected() && |
+ ResourceDispatcherHost::InfoForRequest(request_)->resource_type() |
+ == ResourceType::MAIN_FRAME && |
+ !chromeos::OfflineLoadService::Get()->ShouldProceed( |
+ process_host_id_, render_view_id_, url); |
+} |
+ |
+void OfflineResourceHandler::Resume() { |
+ const GURL url = deferred_url_; |
+ int request_id = deferred_request_id_; |
+ ClearRequestInfo(); |
+ |
+ chromeos::OfflineLoadService::Get()->Proceeded( |
+ process_host_id_, render_view_id_, url); |
+ |
+ DCHECK_NE(request_id, -1); |
+ bool defer = false; |
+ DLOG(INFO) << "Resume load: this=" << this |
+ << ", request id=" << request_id; |
+ next_handler_->OnWillStart(request_id, url, &defer); |
+ if (!defer) |
+ rdh_->StartDeferredRequest(process_host_id_, request_id); |
+} |
+ |
+void OfflineResourceHandler::ShowOfflinePage() { |
+ chromeos::OfflineLoadPage::Show( |
+ process_host_id_, render_view_id_, deferred_url_, this); |
+} |