summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorrdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-20 02:53:08 +0000
committerrdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-20 02:53:08 +0000
commit7cf7ccb7750a8bb104fe9eb6fce3312871346237 (patch)
tree9e9be9db372821412f2b3be1d52939f6f4a82827 /content
parentffc5e7758b4accca486b767b84c6158520aa39e7 (diff)
downloadchromium_src-7cf7ccb7750a8bb104fe9eb6fce3312871346237.zip
chromium_src-7cf7ccb7750a8bb104fe9eb6fce3312871346237.tar.gz
chromium_src-7cf7ccb7750a8bb104fe9eb6fce3312871346237.tar.bz2
Implement offline mode behind a flag.
BUG=2204 Review URL: https://chromiumcodereview.appspot.com/12886022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195374 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/loader/global_routing_id.h42
-rw-r--r--content/browser/loader/offline_policy.cc73
-rw-r--r--content/browser/loader/offline_policy.h56
-rw-r--r--content/browser/loader/offline_policy_unittest.cc96
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.cc85
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.h11
-rw-r--r--content/browser/loader/resource_request_info_impl.cc5
-rw-r--r--content/browser/loader/resource_request_info_impl.h2
-rw-r--r--content/content_browser.gypi3
-rw-r--r--content/content_tests.gypi1
-rw-r--r--content/public/common/content_switches.cc3
-rw-r--r--content/public/common/content_switches.h1
12 files changed, 350 insertions, 28 deletions
diff --git a/content/browser/loader/global_routing_id.h b/content/browser/loader/global_routing_id.h
new file mode 100644
index 0000000..4715c5a
--- /dev/null
+++ b/content/browser/loader/global_routing_id.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2012 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.
+
+#ifndef CONTENT_PUBLIC_BROWSER_GLOBAL_ROUTING_ID_H_
+#define CONTENT_PUBLIC_BROWSER_GLOBAL_ROUTING_ID_H_
+
+namespace content {
+
+// Uniquely identifies the route from which a net::URLRequest comes.
+struct GlobalRoutingID {
+ GlobalRoutingID() : child_id(-1), route_id(-1) {
+ }
+
+ GlobalRoutingID(int child_id, int route_id)
+ : child_id(child_id),
+ route_id(route_id) {
+ }
+
+ // The unique ID of the child process (different from OS's PID).
+ int child_id;
+
+ // The route ID (unique for each URLRequest source).
+ int route_id;
+
+ bool operator<(const GlobalRoutingID& other) const {
+ if (child_id == other.child_id)
+ return route_id < other.route_id;
+ return child_id < other.child_id;
+ }
+ bool operator==(const GlobalRoutingID& other) const {
+ return child_id == other.child_id &&
+ route_id == other.route_id;
+ }
+ bool operator!=(const GlobalRoutingID& other) const {
+ return !(*this == other);
+ }
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_GLOBAL_ROUTING_ID_H_
diff --git a/content/browser/loader/offline_policy.cc b/content/browser/loader/offline_policy.cc
new file mode 100644
index 0000000..bd904ee
--- /dev/null
+++ b/content/browser/loader/offline_policy.cc
@@ -0,0 +1,73 @@
+// Copyright (c) 2013 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 "content/browser/loader/offline_policy.h"
+
+#include "base/command_line.h"
+#include "content/public/common/content_switches.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_info.h"
+#include "net/url_request/url_request.h"
+
+namespace content {
+
+OfflinePolicy::OfflinePolicy()
+ : enabled_(CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableOfflineCacheAccess)),
+ state_(INIT) {}
+
+OfflinePolicy::~OfflinePolicy() {}
+
+int OfflinePolicy::GetAdditionalLoadFlags(int current_flags,
+ bool reset_state) {
+
+ // Don't do anything if offline mode is disabled.
+ if (!enabled_)
+ return 0;
+
+ if (reset_state)
+ state_ = INIT;
+
+ // If a consumer has requested something contradictory, it wins; we
+ // don't modify the load flags.
+ if (current_flags &
+ (net::LOAD_BYPASS_CACHE | net::LOAD_PREFERRING_CACHE |
+ net::LOAD_ONLY_FROM_CACHE | net::LOAD_FROM_CACHE_IF_OFFLINE |
+ net::LOAD_DISABLE_CACHE)) {
+ return 0;
+ }
+
+ switch(state_) {
+ case INIT:
+ return net::LOAD_FROM_CACHE_IF_OFFLINE;
+ case ONLINE:
+ return 0;
+ case OFFLINE:
+ return net::LOAD_ONLY_FROM_CACHE;
+ }
+ NOTREACHED();
+ return 0;
+}
+
+void OfflinePolicy::UpdateStateForCompletedRequest(
+ const net::HttpResponseInfo& response_info) {
+ // Don't do anything if offline mode is disabled.
+ if (!enabled_)
+ return;
+
+ if (state_ != INIT)
+ // We've already made the decision for the rest of this set
+ // of navigations.
+ return;
+
+ if (response_info.server_data_unavailable) {
+ state_ = OFFLINE;
+ } else if (response_info.network_accessed) {
+ // If we got the response from the network or validated it as part
+ // of this request, that means our connection to the host is working.
+ state_ = ONLINE;
+ }
+}
+
+} // namespace content
diff --git a/content/browser/loader/offline_policy.h b/content/browser/loader/offline_policy.h
new file mode 100644
index 0000000..b1acfa9
--- /dev/null
+++ b/content/browser/loader/offline_policy.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2013 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.
+
+#ifndef CONTENT_BROWSER_LOADER_OFFLINE_POLICY
+#define CONTENT_BROWSER_LOADER_OFFLINE_POLICY
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "content/common/content_export.h"
+
+struct ResourceHostMsg_Request;
+
+namespace net {
+class HttpResponseInfo;
+class URLRequest;
+}
+
+namespace content {
+
+// This class controls under what conditions resources will be fetched
+// from cache even if stale rather than from the network. For example,
+// one policy would be that if requests for a particular route (e.g. "tab")
+// is unable to reach the server, other requests made with the same route
+// can be loaded from cache without first requiring a network timeout.
+//
+// There is a single OfflinePolicy object per user navigation unit
+// (generally a tab).
+class CONTENT_EXPORT OfflinePolicy {
+ public:
+ OfflinePolicy();
+ ~OfflinePolicy();
+
+ // Return any additional load flags to be ORed for a request from
+ // this route with the given |resource_type|. |reset_state| indicates
+ // that this request should reinitialized the internal state for this
+ // policy object (e.g. in the case of a main frame load).
+ int GetAdditionalLoadFlags(int current_flags, bool reset_state);
+
+ // Incorporate online/offline information from a completed request.
+ void UpdateStateForCompletedRequest(
+ const net::HttpResponseInfo& response_info);
+
+private:
+ enum State { INIT, ONLINE, OFFLINE };
+
+ bool enabled_;
+ State state_;
+
+ DISALLOW_COPY_AND_ASSIGN(OfflinePolicy);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_LOADER_OFFLINE_POLICY
diff --git a/content/browser/loader/offline_policy_unittest.cc b/content/browser/loader/offline_policy_unittest.cc
new file mode 100644
index 0000000..91256c6
--- /dev/null
+++ b/content/browser/loader/offline_policy_unittest.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 2013 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 "content/browser/loader/offline_policy.h"
+
+#include "base/command_line.h"
+#include "content/public/common/content_switches.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/glue/resource_type.h"
+
+namespace content {
+
+class OfflinePolicyTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableOfflineCacheAccess);
+ policy_ = new OfflinePolicy;
+ }
+
+ virtual void TearDown() {
+ delete policy_;
+ policy_ = NULL;
+ }
+
+ OfflinePolicy* policy_;
+};
+
+// Confirm that the initial state of an offline object is to return
+// LOAD_FROM_CACHE_IF_OFFLINE until it gets changed.
+TEST_F(OfflinePolicyTest, InitialState) {
+ // Two loads without any reset, no UpdateStateForCompletedRequest.
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// Completion without any network probing doesn't change result value.
+TEST_F(OfflinePolicyTest, CompletedUncertain) {
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ net::HttpResponseInfo response_info;
+ policy_->UpdateStateForCompletedRequest(response_info);
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// Completion with a failed network probe changes result value.
+TEST_F(OfflinePolicyTest, CompletedNoNetwork) {
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ net::HttpResponseInfo response_info;
+ response_info.server_data_unavailable = true;
+ policy_->UpdateStateForCompletedRequest(response_info);
+ EXPECT_EQ(net::LOAD_ONLY_FROM_CACHE,
+ policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// Completion with a successful network probe changes result value.
+TEST_F(OfflinePolicyTest, CompletedNetwork) {
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ net::HttpResponseInfo response_info;
+ response_info.network_accessed = true;
+ policy_->UpdateStateForCompletedRequest(response_info);
+ EXPECT_EQ(0, policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// A new navigation resets a state change.
+TEST_F(OfflinePolicyTest, NewNavigationReset) {
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ net::HttpResponseInfo response_info;
+ response_info.network_accessed = true;
+ policy_->UpdateStateForCompletedRequest(response_info);
+ EXPECT_EQ(0, policy_->GetAdditionalLoadFlags(0, false));
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// Cache related flags inhibit the returning of any special flags.
+TEST_F(OfflinePolicyTest, ConsumerFlagOverride) {
+ EXPECT_EQ(0, policy_->GetAdditionalLoadFlags(net::LOAD_BYPASS_CACHE, true));
+ net::HttpResponseInfo response_info;
+ response_info.server_data_unavailable = true;
+ policy_->UpdateStateForCompletedRequest(response_info);
+ EXPECT_EQ(0, policy_->GetAdditionalLoadFlags(net::LOAD_BYPASS_CACHE, false));
+}
+
+}
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 7eee77b..f3a441b 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -231,8 +231,10 @@ net::Error CallbackAndReturn(
return net_error;
}
-int BuildLoadFlagsForRequest(const ResourceHostMsg_Request& request_data,
- int child_id, bool is_sync_load) {
+int BuildLoadFlagsForRequest(
+ const ResourceHostMsg_Request& request_data,
+ int child_id,
+ bool is_sync_load) {
int load_flags = request_data.load_flags;
// Although EV status is irrelevant to sub-frames and sub-resources, we have
@@ -480,6 +482,13 @@ net::Error ResourceDispatcherHostImpl::BeginDownload(
extra_load_flags |= net::LOAD_DISABLE_CACHE;
}
request->set_load_flags(request->load_flags() | extra_load_flags);
+
+ // No need to get offline load flags for downloads, but make sure
+ // we have an OfflinePolicy to receive request completions.
+ GlobalRoutingID id(child_id, route_id);
+ if (!offline_policy_map_[id])
+ offline_policy_map_[id] = new OfflinePolicy();
+
// Check if the renderer is permitted to request the requested URL.
if (!ChildProcessSecurityPolicyImpl::GetInstance()->
CanRequestURL(child_id, url)) {
@@ -702,6 +711,12 @@ void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader,
void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) {
ResourceRequestInfoImpl* info = loader->GetRequestInfo();
+ // There should be an entry in the map created when we dispatched the
+ // request.
+ GlobalRoutingID routing_id(info->GetGlobalRoutingID());
+ DCHECK(offline_policy_map_.end() != offline_policy_map_.find(routing_id));
+ offline_policy_map_[routing_id]->
+ UpdateStateForCompletedRequest(loader->request()->response_info());
int render_process_id, render_view_id;
if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id))
@@ -789,17 +804,17 @@ void ResourceDispatcherHostImpl::OnShutdown() {
// Note that we have to do this in 2 passes as we cannot call
// CancelBlockedRequestsForRoute while iterating over
// blocked_loaders_map_, as it modifies it.
- std::set<ProcessRouteIDs> ids;
+ std::set<GlobalRoutingID> ids;
for (BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.begin();
iter != blocked_loaders_map_.end(); ++iter) {
- std::pair<std::set<ProcessRouteIDs>::iterator, bool> result =
+ std::pair<std::set<GlobalRoutingID>::iterator, bool> result =
ids.insert(iter->first);
// We should not have duplicates.
DCHECK(result.second);
}
- for (std::set<ProcessRouteIDs>::const_iterator iter = ids.begin();
+ for (std::set<GlobalRoutingID>::const_iterator iter = ids.begin();
iter != ids.end(); ++iter) {
- CancelBlockedRequestsForRoute(iter->first, iter->second);
+ CancelBlockedRequestsForRoute(iter->child_id, iter->route_id);
}
scheduler_.reset();
@@ -936,6 +951,12 @@ void ResourceDispatcherHostImpl::BeginRequest(
int load_flags =
BuildLoadFlagsForRequest(request_data, child_id, is_sync_load);
+ GlobalRoutingID id(child_id, route_id);
+ if (!offline_policy_map_[id])
+ offline_policy_map_[id] = new OfflinePolicy();
+ load_flags |= offline_policy_map_[id]->GetAdditionalLoadFlags(
+ load_flags, request_data.resource_type == ResourceType::MAIN_FRAME);
+
// Construct the request.
scoped_ptr<net::URLRequest> new_request;
net::URLRequest* request;
@@ -1276,6 +1297,12 @@ void ResourceDispatcherHostImpl::BeginSaveFile(
// future, maybe we can use a configuration to configure this behavior.
request->set_load_flags(net::LOAD_PREFERRING_CACHE);
+ // No need to get offline load flags for save files, but make sure
+ // we have an OfflinePolicy to receive request completions.
+ GlobalRoutingID id(child_id, route_id);
+ if (!offline_policy_map_[id])
+ offline_policy_map_[id] = new OfflinePolicy();
+
// Since we're just saving some resources we need, disallow downloading.
ResourceRequestInfoImpl* extra_info =
CreateRequestInfo(child_id, route_id, false, context);
@@ -1351,7 +1378,7 @@ void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id,
// Now deal with blocked requests if any.
if (route_id != -1) {
- if (blocked_loaders_map_.find(ProcessRouteIDs(child_id, route_id)) !=
+ if (blocked_loaders_map_.find(GlobalRoutingID(child_id, route_id)) !=
blocked_loaders_map_.end()) {
CancelBlockedRequestsForRoute(child_id, route_id);
}
@@ -1363,14 +1390,22 @@ void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id,
std::set<int> route_ids;
for (BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.begin();
iter != blocked_loaders_map_.end(); ++iter) {
- if (iter->first.first == child_id)
- route_ids.insert(iter->first.second);
+ if (iter->first.child_id == child_id)
+ route_ids.insert(iter->first.route_id);
}
for (std::set<int>::const_iterator iter = route_ids.begin();
iter != route_ids.end(); ++iter) {
CancelBlockedRequestsForRoute(child_id, *iter);
}
}
+
+ // Cleanup the offline state for the route.
+ OfflineMap::iterator it = offline_policy_map_.find(
+ GlobalRoutingID(child_id, route_id));
+ if (offline_policy_map_.end() != it) {
+ delete it->second;
+ offline_policy_map_.erase(it);
+ }
}
// Cancels the request and removes it from the list.
@@ -1502,8 +1537,8 @@ void ResourceDispatcherHostImpl::BeginRequestInternal(
linked_ptr<ResourceLoader> loader(
new ResourceLoader(request.Pass(), handler.Pass(), this));
- ProcessRouteIDs pair_id(info->GetChildID(), info->GetRouteID());
- BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(pair_id);
+ GlobalRoutingID id(info->GetGlobalRoutingID());
+ BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(id);
if (iter != blocked_loaders_map_.end()) {
// The request should be blocked.
iter->second->push_back(loader);
@@ -1565,8 +1600,8 @@ struct LoadInfo {
uint64 upload_size;
};
-// Map from ProcessID+ViewID pair to LoadState
-typedef std::map<std::pair<int, int>, LoadInfo> LoadInfoMap;
+// Map from ProcessID+RouteID pair to LoadState
+typedef std::map<GlobalRoutingID, LoadInfo> LoadInfoMap;
// Used to marshal calls to LoadStateChanged from the IO to UI threads. We do
// them all as a single callback to avoid spamming the UI thread.
@@ -1574,7 +1609,7 @@ void LoadInfoUpdateCallback(const LoadInfoMap& info_map) {
LoadInfoMap::const_iterator i;
for (i = info_map.begin(); i != info_map.end(); ++i) {
RenderViewHostImpl* view =
- RenderViewHostImpl::FromID(i->first.first, i->first.second);
+ RenderViewHostImpl::FromID(i->first.child_id, i->first.route_id);
if (view) // The view could be gone at this point.
view->LoadStateChanged(i->second.url, i->second.load_state,
i->second.upload_position,
@@ -1593,16 +1628,16 @@ void ResourceDispatcherHostImpl::UpdateLoadStates() {
// Determine the largest upload size of all requests
// in each View (good chance it's zero).
- std::map<std::pair<int, int>, uint64> largest_upload_size;
+ std::map<GlobalRoutingID, uint64> largest_upload_size;
for (i = pending_loaders_.begin(); i != pending_loaders_.end(); ++i) {
net::URLRequest* request = i->second->request();
ResourceRequestInfoImpl* info = i->second->GetRequestInfo();
uint64 upload_size = request->GetUploadProgress().size();
if (request->GetLoadState().state != net::LOAD_STATE_SENDING_REQUEST)
upload_size = 0;
- std::pair<int, int> key(info->GetChildID(), info->GetRouteID());
- if (upload_size && largest_upload_size[key] < upload_size)
- largest_upload_size[key] = upload_size;
+ GlobalRoutingID id(info->GetGlobalRoutingID());
+ if (upload_size && largest_upload_size[id] < upload_size)
+ largest_upload_size[id] = upload_size;
}
for (i = pending_loaders_.begin(); i != pending_loaders_.end(); ++i) {
@@ -1615,23 +1650,23 @@ void ResourceDispatcherHostImpl::UpdateLoadStates() {
// progress ipc messages to the plugin process.
i->second->ReportUploadProgress();
- std::pair<int, int> key(info->GetChildID(), info->GetRouteID());
+ GlobalRoutingID id(info->GetGlobalRoutingID());
// If a request is uploading data, ignore all other requests so that the
// upload progress takes priority for being shown in the status bar.
- if (largest_upload_size.find(key) != largest_upload_size.end() &&
- progress.size() < largest_upload_size[key])
+ if (largest_upload_size.find(id) != largest_upload_size.end() &&
+ progress.size() < largest_upload_size[id])
continue;
net::LoadStateWithParam to_insert = load_state;
- LoadInfoMap::iterator existing = info_map.find(key);
+ LoadInfoMap::iterator existing = info_map.find(id);
if (existing != info_map.end()) {
to_insert =
MoreInterestingLoadState(existing->second.load_state, load_state);
if (to_insert.state == existing->second.load_state.state)
continue;
}
- LoadInfo& load_info = info_map[key];
+ LoadInfo& load_info = info_map[id];
load_info.url = request->url();
load_info.load_state = to_insert;
load_info.upload_size = progress.size();
@@ -1649,7 +1684,7 @@ void ResourceDispatcherHostImpl::UpdateLoadStates() {
void ResourceDispatcherHostImpl::BlockRequestsForRoute(int child_id,
int route_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- ProcessRouteIDs key(child_id, route_id);
+ GlobalRoutingID key(child_id, route_id);
DCHECK(blocked_loaders_map_.find(key) == blocked_loaders_map_.end()) <<
"BlockRequestsForRoute called multiple time for the same RVH";
blocked_loaders_map_[key] = new BlockedLoadersList();
@@ -1670,7 +1705,7 @@ void ResourceDispatcherHostImpl::ProcessBlockedRequestsForRoute(
int route_id,
bool cancel_requests) {
BlockedLoadersMap::iterator iter = blocked_loaders_map_.find(
- std::pair<int, int>(child_id, route_id));
+ GlobalRoutingID(child_id, route_id));
if (iter == blocked_loaders_map_.end()) {
// It's possible to reach here if the renderer crashed while an interstitial
// page was showing.
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h
index 5dc36e6..b459ec8 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -25,6 +25,8 @@
#include "base/time.h"
#include "base/timer.h"
#include "content/browser/download/download_resource_handler.h"
+#include "content/browser/loader/global_routing_id.h"
+#include "content/browser/loader/offline_policy.h"
#include "content/browser/loader/render_view_host_tracker.h"
#include "content/browser/loader/resource_loader.h"
#include "content/browser/loader/resource_loader_delegate.h"
@@ -32,6 +34,7 @@
#include "content/common/content_export.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/download_id.h"
+#include "content/public/browser/global_request_id.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "ipc/ipc_message.h"
@@ -60,7 +63,6 @@ class ResourceRequestInfoImpl;
class SaveFileManager;
class WebContentsImpl;
struct DownloadSaveInfo;
-struct GlobalRequestID;
struct Referrer;
class CONTENT_EXPORT ResourceDispatcherHostImpl
@@ -409,8 +411,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
bool is_shutdown_;
typedef std::vector<linked_ptr<ResourceLoader> > BlockedLoadersList;
- typedef std::pair<int, int> ProcessRouteIDs;
- typedef std::map<ProcessRouteIDs, BlockedLoadersList*> BlockedLoadersMap;
+ typedef std::map<GlobalRoutingID, BlockedLoadersList*> BlockedLoadersMap;
BlockedLoadersMap blocked_loaders_map_;
// Maps the child_ids to the approximate number of bytes
@@ -452,6 +453,10 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
RenderViewHostTracker tracker_; // Lives on UI thread.
+ typedef std::map<GlobalRoutingID, OfflinePolicy*> OfflineMap;
+
+ OfflineMap offline_policy_map_;
+
DISALLOW_COPY_AND_ASSIGN(ResourceDispatcherHostImpl);
};
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc
index 8039a12..09b82ca 100644
--- a/content/browser/loader/resource_request_info_impl.cc
+++ b/content/browser/loader/resource_request_info_impl.cc
@@ -4,6 +4,7 @@
#include "content/browser/loader/resource_request_info_impl.h"
+#include "content/browser/loader/global_routing_id.h"
#include "content/browser/worker_host/worker_service_impl.h"
#include "content/common/net/url_request_user_data.h"
#include "content/public/browser/global_request_id.h"
@@ -221,6 +222,10 @@ GlobalRequestID ResourceRequestInfoImpl::GetGlobalRequestID() const {
return GlobalRequestID(child_id_, request_id_);
}
+GlobalRoutingID ResourceRequestInfoImpl::GetGlobalRoutingID() const {
+ return GlobalRoutingID(child_id_, route_id_);
+}
+
void ResourceRequestInfoImpl::set_requested_blob_data(
webkit_blob::BlobData* data) {
requested_blob_data_ = data;
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h
index 8b23b2a..1c663257 100644
--- a/content/browser/loader/resource_request_info_impl.h
+++ b/content/browser/loader/resource_request_info_impl.h
@@ -24,6 +24,7 @@ namespace content {
class CrossSiteResourceHandler;
class ResourceContext;
struct GlobalRequestID;
+struct GlobalRoutingID;
// Holds the data ResourceDispatcherHost associates with each request.
// Retrieve this data by calling ResourceDispatcherHost::InfoForRequest.
@@ -82,6 +83,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
CONTENT_EXPORT void AssociateWithRequest(net::URLRequest* request);
CONTENT_EXPORT GlobalRequestID GetGlobalRequestID() const;
+ GlobalRoutingID GetGlobalRoutingID() const;
// CrossSiteResourceHandler for this request. May be null.
CrossSiteResourceHandler* cross_site_handler() {
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index f238f9a..0bec54e 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -558,8 +558,11 @@
'browser/loader/cross_site_resource_handler.h',
'browser/loader/doomed_resource_handler.cc',
'browser/loader/doomed_resource_handler.h',
+ 'browser/loader/global_routing_id.h',
'browser/loader/layered_resource_handler.cc',
'browser/loader/layered_resource_handler.h',
+ 'browser/loader/offline_policy.cc',
+ 'browser/loader/offline_policy.h',
'browser/loader/power_save_block_resource_throttle.cc',
'browser/loader/power_save_block_resource_throttle.h',
'browser/loader/redirect_to_file_resource_handler.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index ae7f650..97f8f95 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -304,6 +304,7 @@
'browser/in_process_webkit/webkit_thread_unittest.cc',
'browser/indexed_db/indexed_db_unittest.cc',
'browser/indexed_db/indexed_db_quota_client_unittest.cc',
+ 'browser/loader/offline_policy_unittest.cc',
'browser/loader/resource_buffer_unittest.cc',
'browser/loader/resource_dispatcher_host_unittest.cc',
'browser/loader/resource_loader_unittest.cc',
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index e50916b..b66ce99 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -339,6 +339,9 @@ const char kEnableMonitorProfile[] = "enable-monitor-profile";
const char kEnablePinch[] = "enable-pinch";
const char kDisablePinch[] = "disable-pinch";
+// Enables use of cache if offline, even if it's stale
+const char kEnableOfflineCacheAccess[] = "enable-offline-cache-access";
+
// Enable caching of pre-parsed JS script data. See http://crbug.com/32407.
const char kEnablePreparsedJsCaching[] = "enable-preparsed-js-caching";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 6501fb4..c1c75be 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -116,6 +116,7 @@ CONTENT_EXPORT extern const char kUseFakeDeviceForMediaStream[];
extern const char kEnableMonitorProfile[];
extern const char kEnableUserMediaScreenCapturing[];
extern const char kEnablePinch[];
+CONTENT_EXPORT extern const char kEnableOfflineCacheAccess[];
extern const char kDisablePinch[];
extern const char kEnablePreparsedJsCaching[];
CONTENT_EXPORT extern const char kEnablePrivilegedWebGLExtensions[];