Chromium Code Reviews| Index: content/browser/loader/resource_dispatcher_host_impl.cc |
| diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc |
| index c68198438ff841e7cfc0d743b8dd0ca27cde06a9..b54a2053408b21ed91941eede366cb3743a7a0ef 100644 |
| --- a/content/browser/loader/resource_dispatcher_host_impl.cc |
| +++ b/content/browser/loader/resource_dispatcher_host_impl.cc |
| @@ -19,6 +19,7 @@ |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/shared_memory.h" |
| #include "base/message_loop/message_loop.h" |
| +#include "base/metrics/field_trial.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "base/metrics/sparse_histogram.h" |
| #include "base/profiler/scoped_tracker.h" |
| @@ -37,6 +38,7 @@ |
| #include "content/browser/frame_host/navigation_request_info.h" |
| #include "content/browser/frame_host/navigator.h" |
| #include "content/browser/loader/async_resource_handler.h" |
| +#include "content/browser/loader/async_revalidation_manager.h" |
| #include "content/browser/loader/cross_site_resource_handler.h" |
| #include "content/browser/loader/detachable_resource_handler.h" |
| #include "content/browser/loader/mime_type_resource_handler.h" |
| @@ -482,6 +484,23 @@ ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() |
| base::Unretained(this))); |
| update_load_states_timer_.reset(new base::RepeatingTimer()); |
| + |
| + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| + // This needs to be called to mark the trial as active, even if the result |
| + // isn't used. |
| + std::string stale_while_revalidate_trial_group = |
| + base::FieldTrialList::FindFullName("StaleWhileRevalidate"); |
| + // Browser-side navigation and stale-while-revalidate do not work |
| + // together. Only enable stale-while-revalidate if browser navigation is not |
| + // enabled. |
| + // TODO(ricea): Disable stale-while-revalidate completely before browser-side |
| + // navigation becomes the default. Or make them work together. |
| + // crbug.com/561610 |
| + if (!command_line->HasSwitch(switches::kEnableBrowserSideNavigation) && |
| + (stale_while_revalidate_trial_group == "Enabled" || |
| + command_line->HasSwitch(switches::kEnableStaleWhileRevalidate))) { |
| + async_revalidation_manager_.reset(new AsyncRevalidationManager); |
| + } |
| } |
| ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { |
| @@ -587,6 +606,13 @@ void ResourceDispatcherHostImpl::CancelRequestsForContext( |
| loaders_to_cancel.clear(); |
| + if (async_revalidation_manager_) { |
| + // Cancelling async revalidations should not result in the creation of new |
| + // requests. Do it before the CHECKs to ensure this does not happen. |
| + async_revalidation_manager_->CancelAsyncRevalidationsForResourceContext( |
| + context); |
| + } |
| + |
| // Validate that no more requests for this context were added. |
| for (LoaderMap::const_iterator i = pending_loaders_.begin(); |
| i != pending_loaders_.end(); ++i) { |
| @@ -835,6 +861,28 @@ void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader, |
| if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) |
| return; |
| + net::URLRequest* request = loader->request(); |
| + if (request->response_info().async_revalidation_required) { |
| + // Async revalidation is only supported for the first redirect leg. |
| + DCHECK_EQ(request->url_chain().size(), 1u); |
| + DCHECK(async_revalidation_manager_); |
| + |
| + async_revalidation_manager_->BeginAsyncRevalidation(*request, |
| + scheduler_.get()); |
| + } |
| + |
| + // Remove the LOAD_SUPPORT_ASYNC_REVALIDATION flag if it is present. |
| + // It is difficult to create a URLRequest with the correct flags and headers |
| + // for redirect legs other than the first one. Since stale-while-revalidate in |
| + // combination with redirects isn't needed for experimental use, punt on it |
| + // for now. |
| + // TODO(ricea): Fix this before launching the feature. |
| + if (request->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION) { |
| + int new_load_flags = |
| + request->load_flags() & ~net::LOAD_SUPPORT_ASYNC_REVALIDATION; |
| + request->SetLoadFlags(new_load_flags); |
| + } |
| + |
| // Don't notify WebContents observers for requests known to be |
| // downloads; they aren't really associated with the Webcontents. |
| // Note that not all downloads are known before content sniffing. |
| @@ -863,6 +911,12 @@ void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) { |
| info->GetChildID(), info->GetRouteID()); |
| } |
| + if (request->response_info().async_revalidation_required) { |
| + DCHECK(async_revalidation_manager_); |
| + async_revalidation_manager_->BeginAsyncRevalidation(*request, |
| + scheduler_.get()); |
| + } |
| + |
| int render_process_id, render_frame_host; |
| if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) |
| return; |
| @@ -1322,6 +1376,13 @@ void ResourceDispatcherHostImpl::BeginRequest( |
| load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; |
| } |
| + bool support_async_revalidation = |
| + (!is_sync_load && async_revalidation_manager_ && |
| + AsyncRevalidationManager::QualifiesForAsyncRevalidation(request_data)); |
| + |
| + if (support_async_revalidation) |
| + load_flags |= net::LOAD_SUPPORT_ASYNC_REVALIDATION; |
| + |
| // Sync loads should have maximum priority and should be the only |
| // requets that have the ignore limits flag set. |
| if (is_sync_load) { |
| @@ -1358,7 +1419,8 @@ void ResourceDispatcherHostImpl::BeginRequest( |
| report_raw_headers, |
| !is_sync_load, |
| IsUsingLoFi(request_data.lofi_state, delegate_, |
| - *new_request, resource_context)); |
| + *new_request, resource_context), |
| + support_async_revalidation ? request_data.headers : std::string()); |
| // Request takes ownership. |
| extra_info->AssociateWithRequest(new_request.get()); |
| @@ -1645,7 +1707,8 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo( |
| base::WeakPtr<ResourceMessageFilter>(), // filter |
| false, // report_raw_headers |
| true, // is_async |
| - false); // is_using_lofi |
| + false, // is_using_lofi |
| + std::string()); // original_headers |
| } |
| void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id, |
| @@ -2058,6 +2121,9 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( |
| // |
| // TODO(davidben): Associate the request with the FrameTreeNode and/or tab so |
| // that IO thread -> UI thread hops will work. |
| + // |
| + // TODO(ricea): The original_headers field here is just a placeholder |
| + // and wouldn't work properly with stale-while-revalidate. crbug.com/561610 |
|
kinuko
2015/12/03 07:51:41
This comment isn't feels a bit unclear when reader
Adam Rice
2015/12/03 14:20:43
Done.
|
| ResourceRequestInfoImpl* extra_info = new ResourceRequestInfoImpl( |
| PROCESS_TYPE_BROWSER, |
| -1, // child_id |
| @@ -2085,9 +2151,10 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( |
| blink::WebPageVisibilityStateVisible, resource_context, |
| base::WeakPtr<ResourceMessageFilter>(), // filter |
| false, // request_data.report_raw_headers |
| - true, |
| + true, // is_async |
| IsUsingLoFi(info.common_params.lofi_state, delegate_, |
| - *new_request, resource_context)); |
| + *new_request, resource_context), |
| + std::string()); // original_headers |
|
kinuko
2015/12/03 07:51:41
We don't seem to be really aligning comments in th
Adam Rice
2015/12/03 14:20:43
Fixed.
|
| // Request takes ownership. |
| extra_info->AssociateWithRequest(new_request.get()); |
| @@ -2125,6 +2192,11 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest( |
| BeginRequestInternal(new_request.Pass(), handler.Pass()); |
| } |
| +void ResourceDispatcherHostImpl::EnableStaleWhileRevalidateForTesting() { |
| + if (!async_revalidation_manager_) |
| + async_revalidation_manager_.reset(new AsyncRevalidationManager); |
| +} |
| + |
| // static |
| int ResourceDispatcherHostImpl::CalculateApproximateMemoryCost( |
| net::URLRequest* request) { |