| Index: content/browser/service_worker/service_worker_dispatcher_host.cc
|
| diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
|
| index 03773e6a4d32c98f7cae02576d168ce22451af09..bd34fabf1b4cd971d3d2c844db7ea84a57845de2 100644
|
| --- a/content/browser/service_worker/service_worker_dispatcher_host.cc
|
| +++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
|
| @@ -35,6 +35,7 @@
|
| #include "content/public/common/content_client.h"
|
| #include "content/public/common/origin_util.h"
|
| #include "ipc/ipc_message_macros.h"
|
| +#include "net/http/http_util.h"
|
| #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
|
| #include "url/gurl.h"
|
|
|
| @@ -55,6 +56,8 @@ const char kEnableNavigationPreloadErrorPrefix[] =
|
| "Failed to enable or disable navigation preload: ";
|
| const char kGetNavigationPreloadStateErrorPrefix[] =
|
| "Failed to get navigation preload state: ";
|
| +const char kSetNavigationPreloadHeaderErrorPrefix[] =
|
| + "Failed to set navigation preload header: ";
|
|
|
| const uint32_t kFilteredMessageClasses[] = {
|
| ServiceWorkerMsgStart, EmbeddedWorkerMsgStart,
|
| @@ -190,6 +193,8 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(
|
| OnEnableNavigationPreload)
|
| IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetNavigationPreloadState,
|
| OnGetNavigationPreloadState)
|
| + IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetNavigationPreloadHeader,
|
| + OnSetNavigationPreloadHeader)
|
| IPC_MESSAGE_UNHANDLED(handled = false)
|
| IPC_END_MESSAGE_MAP()
|
|
|
| @@ -786,7 +791,83 @@ void ServiceWorkerDispatcherHost::OnGetNavigationPreloadState(
|
| }
|
|
|
| Send(new ServiceWorkerMsg_DidGetNavigationPreloadState(
|
| - thread_id, request_id, registration->is_navigation_preload_enabled()));
|
| + thread_id, request_id,
|
| + NavigationPreloadState(registration->is_navigation_preload_enabled(),
|
| + registration->navigation_preload_header())));
|
| +}
|
| +
|
| +void ServiceWorkerDispatcherHost::OnSetNavigationPreloadHeader(
|
| + int thread_id,
|
| + int request_id,
|
| + int provider_id,
|
| + int64_t registration_id,
|
| + const std::string& value) {
|
| + ProviderStatus provider_status;
|
| + ServiceWorkerProviderHost* provider_host =
|
| + GetProviderHostForRequest(&provider_status, provider_id);
|
| + switch (provider_status) {
|
| + case ProviderStatus::NO_CONTEXT: // fallthrough
|
| + case ProviderStatus::DEAD_HOST:
|
| + Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError(
|
| + thread_id, request_id, WebServiceWorkerError::ErrorTypeAbort,
|
| + std::string(kSetNavigationPreloadHeaderErrorPrefix) +
|
| + std::string(kShutdownErrorMessage)));
|
| + return;
|
| + case ProviderStatus::NO_HOST:
|
| + bad_message::ReceivedBadMessage(
|
| + this, bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_NO_HOST);
|
| + return;
|
| + case ProviderStatus::NO_URL:
|
| + Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError(
|
| + thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity,
|
| + std::string(kSetNavigationPreloadHeaderErrorPrefix) +
|
| + std::string(kNoDocumentURLErrorMessage)));
|
| + return;
|
| + case ProviderStatus::OK:
|
| + break;
|
| + }
|
| +
|
| + ServiceWorkerRegistration* registration =
|
| + GetContext()->GetLiveRegistration(registration_id);
|
| + if (!registration) {
|
| + // |registration| must be alive because a renderer retains a registration
|
| + // reference at this point.
|
| + bad_message::ReceivedBadMessage(
|
| + this,
|
| + bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_REGISTRATION_ID);
|
| + return;
|
| + }
|
| +
|
| + std::vector<GURL> urls = {provider_host->document_url(),
|
| + registration->pattern()};
|
| + if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
|
| + bad_message::ReceivedBadMessage(
|
| + this, bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_INVALID_ORIGIN);
|
| + return;
|
| + }
|
| +
|
| + // TODO(falken): Ideally this would match Blink's isValidHTTPHeaderValue.
|
| + // Chrome's check is less restrictive: it allows non-latin1 characters.
|
| + if (!net::HttpUtil::IsValidHeaderValue(value)) {
|
| + bad_message::ReceivedBadMessage(
|
| + this, bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_VALUE);
|
| + return;
|
| + }
|
| +
|
| + if (!GetContentClient()->browser()->AllowServiceWorker(
|
| + registration->pattern(), provider_host->topmost_frame_url(),
|
| + resource_context_, render_process_id_, provider_host->frame_id())) {
|
| + Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError(
|
| + thread_id, request_id, WebServiceWorkerError::ErrorTypeDisabled,
|
| + std::string(kSetNavigationPreloadHeaderErrorPrefix) +
|
| + std::string(kUserDeniedPermissionMessage)));
|
| + return;
|
| + }
|
| +
|
| + // TODO(falken): Write to disk before resolving the promise.
|
| + registration->SetNavigationPreloadHeader(value);
|
| + Send(new ServiceWorkerMsg_DidSetNavigationPreloadHeader(thread_id,
|
| + request_id));
|
| }
|
|
|
| void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
|
|
|