Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / renderer_host / offline_resource_throttle.cc
blob311876569d7b9328bf1582742935ba9eb8354951
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/renderer_host/offline_resource_throttle.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/memory/singleton.h"
12 #include "base/metrics/histogram.h"
13 #include "base/strings/string_util.h"
14 #include "chrome/browser/chromeos/offline/offline_load_page.h"
15 #include "content/public/browser/appcache_service.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/resource_controller.h"
19 #include "content/public/browser/resource_request_info.h"
20 #include "content/public/browser/service_worker_context.h"
21 #include "content/public/browser/web_contents.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/net_util.h"
24 #include "net/base/network_change_notifier.h"
25 #include "net/url_request/url_request.h"
26 #include "net/url_request/url_request_context.h"
27 #include "url/url_constants.h"
29 using content::BrowserThread;
30 using content::RenderViewHost;
31 using content::WebContents;
33 namespace {
35 void ShowOfflinePage(
36 int render_process_id,
37 int render_view_id,
38 const GURL& url,
39 const chromeos::OfflineLoadPage::CompletionCallback& callback) {
40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
42 // Check again on UI thread and proceed if it's connected.
43 if (!net::NetworkChangeNotifier::IsOffline()) {
44 BrowserThread::PostTask(
45 BrowserThread::IO, FROM_HERE, base::Bind(callback, true));
46 } else {
47 RenderViewHost* render_view_host =
48 RenderViewHost::FromID(render_process_id, render_view_id);
49 WebContents* web_contents = render_view_host ?
50 WebContents::FromRenderViewHost(render_view_host) : NULL;
51 // There is a chance that the tab closed after we decided to show
52 // the offline page on the IO thread and before we actually show the
53 // offline page here on the UI thread.
54 if (web_contents)
55 (new chromeos::OfflineLoadPage(web_contents, url, callback))->Show();
59 } // namespace
61 OfflineResourceThrottle::OfflineResourceThrottle(
62 net::URLRequest* request,
63 content::AppCacheService* appcache_service)
64 : request_(request),
65 appcache_service_(appcache_service),
66 pending_callbacks_(0) {
67 DCHECK(appcache_service);
70 OfflineResourceThrottle::~OfflineResourceThrottle() {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
73 if (!completion_callback_.IsCancelled())
74 completion_callback_.Cancel();
77 void OfflineResourceThrottle::WillStartRequest(bool* defer) {
78 if (!ShouldShowOfflinePage(request_->url()))
79 return;
81 DVLOG(1) << "WillStartRequest: this=" << this << ", url=" << request_->url();
83 const GURL* url = &(request_->url());
84 const GURL* first_party = &(request_->first_party_for_cookies());
86 // Anticipate a client-side HSTS based redirect from HTTP to HTTPS, and
87 // ask the appcache about the HTTPS url instead of the HTTP url.
88 GURL redirect_url;
89 if (request_->GetHSTSRedirect(&redirect_url)) {
90 if (url->GetOrigin() == first_party->GetOrigin())
91 first_party = &redirect_url;
92 url = &redirect_url;
95 DCHECK(completion_callback_.IsCancelled());
97 completion_callback_.Reset(
98 base::Bind(&OfflineResourceThrottle::OnCanHandleOfflineComplete,
99 AsWeakPtr()));
101 pending_callbacks_ = 1;
102 appcache_service_->CanHandleMainResourceOffline(
103 *url, *first_party,
104 completion_callback_.callback());
106 content::ServiceWorkerContext* service_worker_context =
107 content::ServiceWorkerContext::GetServiceWorkerContext(request_);
108 if (service_worker_context) {
109 ++pending_callbacks_;
110 service_worker_context->CanHandleMainResourceOffline(
111 *url, *first_party,
112 completion_callback_.callback());
114 *defer = true;
117 const char* OfflineResourceThrottle::GetNameForLogging() const {
118 return "OfflineResourceThrottle";
121 void OfflineResourceThrottle::OnBlockingPageComplete(bool proceed) {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
124 if (proceed) {
125 controller()->Resume();
126 } else {
127 controller()->Cancel();
131 bool OfflineResourceThrottle::IsRemote(const GURL& url) const {
132 return !net::IsLocalhost(url.host()) && (url.SchemeIs(url::kFtpScheme) ||
133 url.SchemeIs(url::kHttpScheme) ||
134 url.SchemeIs(url::kHttpsScheme));
137 bool OfflineResourceThrottle::ShouldShowOfflinePage(const GURL& url) const {
138 // If the network is disconnected while loading other resources, we'll simply
139 // show broken link/images.
140 return IsRemote(url) && net::NetworkChangeNotifier::IsOffline();
143 void OfflineResourceThrottle::OnCanHandleOfflineComplete(int rv) {
144 --pending_callbacks_;
146 if (rv == net::OK) {
147 completion_callback_.Cancel();
148 controller()->Resume();
149 } else if (!pending_callbacks_) {
150 completion_callback_.Cancel();
151 const content::ResourceRequestInfo* info =
152 content::ResourceRequestInfo::ForRequest(request_);
153 BrowserThread::PostTask(
154 BrowserThread::UI,
155 FROM_HERE,
156 base::Bind(
157 &ShowOfflinePage,
158 info->GetChildID(),
159 info->GetRouteID(),
160 request_->url(),
161 base::Bind(
162 &OfflineResourceThrottle::OnBlockingPageComplete,
163 AsWeakPtr())));