Commit ab2c2361 authored by Konstantin Ganenko's avatar Konstantin Ganenko Committed by Commit Bot

Fix crash on navigate with service worker script loaded from cache

Service worker's version has nullptr GetMainScriptHttpResponseInfo
 when script loaded via ServiceWorkerInstalledScriptLoader. It is
 case when non-installed service worker requests script that is already
 installed.

R=falken@chromium.org

Bug: 929017
Change-Id: Ic4663fec8f2ad51982ac50a2fa2bd69fab67928b
Reviewed-on: https://chromium-review.googlesource.com/c/1455138
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629904}
parent bbae228a
...@@ -25,10 +25,27 @@ using FinishedReason = ServiceWorkerInstalledScriptReader::FinishedReason; ...@@ -25,10 +25,27 @@ using FinishedReason = ServiceWorkerInstalledScriptReader::FinishedReason;
ServiceWorkerInstalledScriptLoader::ServiceWorkerInstalledScriptLoader( ServiceWorkerInstalledScriptLoader::ServiceWorkerInstalledScriptLoader(
uint32_t options, uint32_t options,
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
std::unique_ptr<ServiceWorkerResponseReader> response_reader) std::unique_ptr<ServiceWorkerResponseReader> response_reader,
scoped_refptr<ServiceWorkerVersion>
version_for_main_script_http_response_info,
const GURL& request_url)
: options_(options), : options_(options),
client_(std::move(client)), client_(std::move(client)),
request_start_(base::TimeTicks::Now()) { request_start_(base::TimeTicks::Now()) {
// Normally, the main script info is set by ServiceWorkerNewScriptLoader for
// new service workers and ServiceWorkerInstalledScriptsSender for installed
// service workes. But some embedders might preinstall scripts to the
// ServiceWorkerScriptCacheMap while not setting the ServiceWorkerVersion
// status to INSTALLED, so we can come to here instead of using
// SeviceWorkerInstalledScriptsSender.
// In this case, the main script info would not yet have been set, so set it
// here.
if (request_url == version_for_main_script_http_response_info->script_url() &&
!version_for_main_script_http_response_info
->GetMainScriptHttpResponseInfo()) {
version_for_main_script_http_response_info_ =
std::move(version_for_main_script_http_response_info);
}
reader_ = std::make_unique<ServiceWorkerInstalledScriptReader>( reader_ = std::make_unique<ServiceWorkerInstalledScriptReader>(
std::move(response_reader), this); std::move(response_reader), this);
reader_->Start(); reader_->Start();
...@@ -61,6 +78,12 @@ void ServiceWorkerInstalledScriptLoader::OnStarted( ...@@ -61,6 +78,12 @@ void ServiceWorkerInstalledScriptLoader::OnStarted(
void ServiceWorkerInstalledScriptLoader::OnHttpInfoRead( void ServiceWorkerInstalledScriptLoader::OnHttpInfoRead(
scoped_refptr<HttpResponseInfoIOBuffer> http_info) { scoped_refptr<HttpResponseInfoIOBuffer> http_info) {
net::HttpResponseInfo* info = http_info->http_info.get(); net::HttpResponseInfo* info = http_info->http_info.get();
DCHECK(info);
if (version_for_main_script_http_response_info_) {
version_for_main_script_http_response_info_->SetMainScriptHttpResponseInfo(
*info);
}
network::ResourceResponseHead head; network::ResourceResponseHead head;
head.request_start = request_start_; head.request_start = request_start_;
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
namespace content { namespace content {
class ServiceWorkerVersion;
// S13nServiceWorker: A URLLoader that loads an installed service worker script // S13nServiceWorker: A URLLoader that loads an installed service worker script
// for a service worker that doesn't have a // for a service worker that doesn't have a
// ServiceWorkerInstalledScriptsManager. // ServiceWorkerInstalledScriptsManager.
...@@ -34,7 +36,10 @@ class CONTENT_EXPORT ServiceWorkerInstalledScriptLoader ...@@ -34,7 +36,10 @@ class CONTENT_EXPORT ServiceWorkerInstalledScriptLoader
ServiceWorkerInstalledScriptLoader( ServiceWorkerInstalledScriptLoader(
uint32_t options, uint32_t options,
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
std::unique_ptr<ServiceWorkerResponseReader> response_reader); std::unique_ptr<ServiceWorkerResponseReader> response_reader,
scoped_refptr<ServiceWorkerVersion>
version_for_main_script_http_response_info,
const GURL& request_url);
~ServiceWorkerInstalledScriptLoader() override; ~ServiceWorkerInstalledScriptLoader() override;
// ServiceWorkerInstalledScriptReader::Client overrides: // ServiceWorkerInstalledScriptReader::Client overrides:
...@@ -67,6 +72,8 @@ class CONTENT_EXPORT ServiceWorkerInstalledScriptLoader ...@@ -67,6 +72,8 @@ class CONTENT_EXPORT ServiceWorkerInstalledScriptLoader
uint32_t options_ = network::mojom::kURLLoadOptionNone; uint32_t options_ = network::mojom::kURLLoadOptionNone;
network::mojom::URLLoaderClientPtr client_; network::mojom::URLLoaderClientPtr client_;
scoped_refptr<ServiceWorkerVersion>
version_for_main_script_http_response_info_;
base::TimeTicks request_start_; base::TimeTicks request_start_;
std::unique_ptr<ServiceWorkerInstalledScriptReader> reader_; std::unique_ptr<ServiceWorkerInstalledScriptReader> reader_;
......
...@@ -420,6 +420,7 @@ void ServiceWorkerNavigationLoader::StartResponse( ...@@ -420,6 +420,7 @@ void ServiceWorkerNavigationLoader::StartResponse(
// browser. See https://crbug.com/392409 for details about this design. // browser. See https://crbug.com/392409 for details about this design.
// TODO(horo): When we support mixed-content (HTTP) no-cors requests from a // TODO(horo): When we support mixed-content (HTTP) no-cors requests from a
// ServiceWorker, we have to check the security level of the responses. // ServiceWorker, we have to check the security level of the responses.
DCHECK(version->GetMainScriptHttpResponseInfo());
response_head_.ssl_info = version->GetMainScriptHttpResponseInfo()->ssl_info; response_head_.ssl_info = version->GetMainScriptHttpResponseInfo()->ssl_info;
// Handle a redirect response. ComputeRedirectInfo returns non-null redirect // Handle a redirect response. ComputeRedirectInfo returns non-null redirect
......
...@@ -88,7 +88,8 @@ void ServiceWorkerScriptLoaderFactory::CreateLoaderAndStart( ...@@ -88,7 +88,8 @@ void ServiceWorkerScriptLoaderFactory::CreateLoaderAndStart(
context_->storage()->CreateResponseReader(resource_id); context_->storage()->CreateResponseReader(resource_id);
mojo::MakeStrongBinding( mojo::MakeStrongBinding(
std::make_unique<ServiceWorkerInstalledScriptLoader>( std::make_unique<ServiceWorkerInstalledScriptLoader>(
options, std::move(client), std::move(response_reader)), options, std::move(client), std::move(response_reader), version,
resource_request.url),
std::move(request)); std::move(request));
return; return;
} }
...@@ -243,7 +244,8 @@ void ServiceWorkerScriptLoaderFactory::OnCopyScriptFinished( ...@@ -243,7 +244,8 @@ void ServiceWorkerScriptLoaderFactory::OnCopyScriptFinished(
mojo::MakeStrongBinding( mojo::MakeStrongBinding(
std::make_unique<ServiceWorkerInstalledScriptLoader>( std::make_unique<ServiceWorkerInstalledScriptLoader>(
options, std::move(client), options, std::move(client),
context_->storage()->CreateResponseReader(new_resource_id)), context_->storage()->CreateResponseReader(new_resource_id), version,
resource_request.url),
std::move(request)); std::move(request));
} }
} // namespace content } // namespace content
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment