diff options
author | rdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-20 02:53:08 +0000 |
---|---|---|
committer | rdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-20 02:53:08 +0000 |
commit | 7cf7ccb7750a8bb104fe9eb6fce3312871346237 (patch) | |
tree | 9e9be9db372821412f2b3be1d52939f6f4a82827 /content | |
parent | ffc5e7758b4accca486b767b84c6158520aa39e7 (diff) | |
download | chromium_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.h | 42 | ||||
-rw-r--r-- | content/browser/loader/offline_policy.cc | 73 | ||||
-rw-r--r-- | content/browser/loader/offline_policy.h | 56 | ||||
-rw-r--r-- | content/browser/loader/offline_policy_unittest.cc | 96 | ||||
-rw-r--r-- | content/browser/loader/resource_dispatcher_host_impl.cc | 85 | ||||
-rw-r--r-- | content/browser/loader/resource_dispatcher_host_impl.h | 11 | ||||
-rw-r--r-- | content/browser/loader/resource_request_info_impl.cc | 5 | ||||
-rw-r--r-- | content/browser/loader/resource_request_info_impl.h | 2 | ||||
-rw-r--r-- | content/content_browser.gypi | 3 | ||||
-rw-r--r-- | content/content_tests.gypi | 1 | ||||
-rw-r--r-- | content/public/common/content_switches.cc | 3 | ||||
-rw-r--r-- | content/public/common/content_switches.h | 1 |
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[]; |