Fix build break
[chromium-blink-merge.git] / chrome / browser / renderer_host / offline_resource_throttle.cc
blob4b4dd895211b88d68cf0cf1207a01ab8a0f9f33d
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/string_util.h"
14 #include "chrome/browser/chromeos/offline/offline_load_page.h"
15 #include "chrome/browser/net/chrome_url_request_context.h"
16 #include "chrome/common/url_constants.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/resource_controller.h"
20 #include "content/public/browser/web_contents.h"
21 #include "net/base/net_errors.h"
22 #include "net/base/net_util.h"
23 #include "net/base/network_change_notifier.h"
24 #include "net/url_request/url_request.h"
25 #include "net/url_request/url_request_context.h"
26 #include "webkit/appcache/appcache_service.h"
28 using content::BrowserThread;
29 using content::RenderViewHost;
30 using content::WebContents;
32 namespace {
34 void ShowOfflinePage(
35 int render_process_id,
36 int render_view_id,
37 const GURL& url,
38 const chromeos::OfflineLoadPage::CompletionCallback& callback) {
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
41 // Check again on UI thread and proceed if it's connected.
42 if (!net::NetworkChangeNotifier::IsOffline()) {
43 BrowserThread::PostTask(
44 BrowserThread::IO, FROM_HERE, base::Bind(callback, true));
45 } else {
46 RenderViewHost* render_view_host =
47 RenderViewHost::FromID(render_process_id, render_view_id);
48 WebContents* web_contents = render_view_host ?
49 WebContents::FromRenderViewHost(render_view_host) : NULL;
50 // There is a chance that the tab closed after we decided to show
51 // the offline page on the IO thread and before we actually show the
52 // offline page here on the UI thread.
53 if (web_contents)
54 (new chromeos::OfflineLoadPage(web_contents, url, callback))->Show();
58 } // namespace
60 OfflineResourceThrottle::OfflineResourceThrottle(
61 int render_process_id,
62 int render_view_id,
63 net::URLRequest* request,
64 appcache::AppCacheService* appcache_service)
65 : render_process_id_(render_process_id),
66 render_view_id_(render_view_id),
67 request_(request),
68 appcache_service_(appcache_service) {
69 DCHECK(appcache_service);
72 OfflineResourceThrottle::~OfflineResourceThrottle() {
73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
75 if (!appcache_completion_callback_.IsCancelled())
76 appcache_completion_callback_.Cancel();
79 void OfflineResourceThrottle::WillStartRequest(bool* defer) {
80 if (!ShouldShowOfflinePage(request_->url()))
81 return;
83 DVLOG(1) << "WillStartRequest: this=" << this << ", url=" << request_->url();
85 const GURL* url = &(request_->url());
86 const GURL* first_party = &(request_->first_party_for_cookies());
88 // Anticipate a client-side HSTS based redirect from HTTP to HTTPS, and
89 // ask the appcache about the HTTPS url instead of the HTTP url.
90 GURL redirect_url;
91 if (request_->GetHSTSRedirect(&redirect_url)) {
92 if (url->GetOrigin() == first_party->GetOrigin())
93 first_party = &redirect_url;
94 url = &redirect_url;
97 DCHECK(appcache_completion_callback_.IsCancelled());
99 appcache_completion_callback_.Reset(
100 base::Bind(&OfflineResourceThrottle::OnCanHandleOfflineComplete,
101 AsWeakPtr()));
102 appcache_service_->CanHandleMainResourceOffline(
103 *url, *first_party,
104 appcache_completion_callback_.callback());
106 *defer = true;
109 void OfflineResourceThrottle::OnBlockingPageComplete(bool proceed) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
112 if (proceed) {
113 controller()->Resume();
114 } else {
115 controller()->Cancel();
119 bool OfflineResourceThrottle::IsRemote(const GURL& url) const {
120 return !net::IsLocalhost(url.host()) &&
121 (url.SchemeIs(chrome::kFtpScheme) ||
122 url.SchemeIs(chrome::kHttpScheme) ||
123 url.SchemeIs(chrome::kHttpsScheme));
126 bool OfflineResourceThrottle::ShouldShowOfflinePage(const GURL& url) const {
127 // If the network is disconnected while loading other resources, we'll simply
128 // show broken link/images.
129 return IsRemote(url) && net::NetworkChangeNotifier::IsOffline();
132 void OfflineResourceThrottle::OnCanHandleOfflineComplete(int rv) {
133 appcache_completion_callback_.Cancel();
135 if (rv == net::OK) {
136 controller()->Resume();
137 } else {
138 BrowserThread::PostTask(
139 BrowserThread::UI,
140 FROM_HERE,
141 base::Bind(
142 &ShowOfflinePage,
143 render_process_id_,
144 render_view_id_,
145 request_->url(),
146 base::Bind(
147 &OfflineResourceThrottle::OnBlockingPageComplete,
148 AsWeakPtr())));