diff options
author | clamy <clamy@chromium.org> | 2016-01-29 03:24:21 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-29 11:25:31 +0000 |
commit | dcb0185ea06d638aa182385e7ee589b33830bb57 (patch) | |
tree | eff68d126ce4fc36b5aa1678f1bacaf35b00b501 /content | |
parent | 194702589109b4f5374f131aa5f591965eb0f57b (diff) | |
download | chromium_src-dcb0185ea06d638aa182385e7ee589b33830bb57.zip chromium_src-dcb0185ea06d638aa182385e7ee589b33830bb57.tar.gz chromium_src-dcb0185ea06d638aa182385e7ee589b33830bb57.tar.bz2 |
PlzNavigate: fix issue with navigation cancellation and ServiceWorker
This CL fixes a race condition happening when Plznavigate is enabled and a
navigation is cancelled while being committed. The RenderFrame committing it
creates a ServiceWorkerNetworkProvider based on an id given by the browser.
When the ServiceWorkerDispatcherHost tries to retrieve the pre-created
ServiceWorkerProviderHost, it has already been destroyed by the navigation
cancellation. The SWDH considers this as bad message and kills the renderer.
Now it just returns, as the navigation is about to be cancelled.
Similarly, when the ServiceWorkerNetworkProvider is destroyed due to the
navigation cancellation and had a pre-created ServiceWorkerDispatcherHost that
was not registered (due to the condition described above), the SWDH will no
longer consider it a bad message, and will just return early.
BUG=475027
Review URL: https://codereview.chromium.org/1649763003
Cr-Commit-Position: refs/heads/master@{#372328}
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/service_worker/service_worker_dispatcher_host.cc | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc index f8d80e0..78c54d1 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host.cc @@ -748,11 +748,11 @@ void ServiceWorkerDispatcherHost::OnProviderCreated( GetContext()->GetNavigationHandleCore(provider_id); if (navigation_handle_core != nullptr) provider_host = navigation_handle_core->RetrievePreCreatedHost(); - if (provider_host == nullptr) { - bad_message::ReceivedBadMessage( - this, bad_message::SWDH_PROVIDER_CREATED_NO_HOST); + + // If no host is found, the navigation has been cancelled in the meantime. + // Just return as the navigation will be stopped in the renderer as well. + if (provider_host == nullptr) return; - } DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, provider_type); provider_host->CompleteNavigationInitialized(render_process_id_, route_id, this); @@ -776,8 +776,15 @@ void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) { if (!GetContext()) return; if (!GetContext()->GetProviderHost(render_process_id_, provider_id)) { - bad_message::ReceivedBadMessage( - this, bad_message::SWDH_PROVIDER_DESTROYED_NO_HOST); + // PlzNavigate: in some cancellation of navigation cases, it is possible + // for the pre-created hoist to have been destroyed before being claimed by + // the renderer. The provider is then destroyed in the renderer, and no + // matching host will be found. + if (!IsBrowserSideNavigationEnabled() || + !ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id)) { + bad_message::ReceivedBadMessage( + this, bad_message::SWDH_PROVIDER_DESTROYED_NO_HOST); + } return; } GetContext()->RemoveProviderHost(render_process_id_, provider_id); |