| Index: content/renderer/service_worker/service_worker_context_client.cc
|
| diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
|
| index b4167723f70b9cf6ce9005eb2ccfdf4ca4553647..67a2f39d83dcfe9d3d8f79428efb8f60ebe8c254 100644
|
| --- a/content/renderer/service_worker/service_worker_context_client.cc
|
| +++ b/content/renderer/service_worker/service_worker_context_client.cc
|
| @@ -27,6 +27,7 @@
|
| #include "content/child/service_worker/web_service_worker_provider_impl.h"
|
| #include "content/child/service_worker/web_service_worker_registration_impl.h"
|
| #include "content/child/thread_safe_sender.h"
|
| +#include "content/child/web_data_consumer_handle_impl.h"
|
| #include "content/child/webmessageportchannel_impl.h"
|
| #include "content/common/devtools_messages.h"
|
| #include "content/common/message_port_messages.h"
|
| @@ -59,6 +60,7 @@
|
| #include "third_party/WebKit/public/platform/modules/background_sync/WebSyncRegistration.h"
|
| #include "third_party/WebKit/public/platform/modules/notifications/WebNotificationData.h"
|
| #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerClientQueryOptions.h"
|
| +#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
|
| #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h"
|
| #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h"
|
| #include "third_party/WebKit/public/web/WebDataSource.h"
|
| @@ -189,6 +191,9 @@ struct ServiceWorkerContextClient::WorkerContextData {
|
| IDMap<const base::Callback<void(ServiceWorkerStatusCode,
|
| base::Time /* dispatch_event_time */)>,
|
| IDMapOwnPointer>;
|
| + using NavigationPreloadRequestsMap =
|
| + IDMap<ServiceWorkerContextClient::NavigationPreloadRequest,
|
| + IDMapOwnPointer>;
|
|
|
| explicit WorkerContextData(ServiceWorkerContextClient* owner)
|
| : weak_factory(owner), proxy_weak_factory(owner->proxy_) {}
|
| @@ -215,6 +220,9 @@ struct ServiceWorkerContextClient::WorkerContextData {
|
| // Pending callbacks for Fetch Events.
|
| FetchEventCallbacksMap fetch_event_callbacks;
|
|
|
| + // Pending navigation preload requests.
|
| + NavigationPreloadRequestsMap preload_requests;
|
| +
|
| service_manager::InterfaceRegistry interface_registry;
|
| // This is not used when mojo for the service workers is enabled. At that
|
| // time, remote interfaces are stored in EmbeddedWorkerInstanceClientImpl.
|
| @@ -225,6 +233,93 @@ struct ServiceWorkerContextClient::WorkerContextData {
|
| base::WeakPtrFactory<blink::WebServiceWorkerContextProxy> proxy_weak_factory;
|
| };
|
|
|
| +class ServiceWorkerContextClient::NavigationPreloadRequest final
|
| + : public mojom::URLLoaderClient {
|
| + public:
|
| + NavigationPreloadRequest(int fetch_event_id,
|
| + const GURL& url,
|
| + mojom::FetchEventPreloadHandlePtr preload_handle)
|
| + : fetch_event_id_(fetch_event_id),
|
| + url_loader_(std::move(preload_handle->url_loader)),
|
| + binding_(this, std::move(preload_handle->url_loader_client_request)),
|
| + response_(base::MakeUnique<blink::WebServiceWorkerResponse>()) {
|
| + response_->setURL(url);
|
| + }
|
| +
|
| + ~NavigationPreloadRequest() override {
|
| + if (result_reported_)
|
| + return;
|
| + ServiceWorkerContextClient* client =
|
| + ServiceWorkerContextClient::ThreadSpecificInstance();
|
| + if (!client)
|
| + return;
|
| + client->OnNavigationPreloadError(
|
| + fetch_event_id_,
|
| + base::MakeUnique<blink::WebServiceWorkerError>(
|
| + blink::WebServiceWorkerError::ErrorTypeAbort,
|
| + blink::WebString::fromUTF8(
|
| + "Service Worker navigation preload aborted. Need to guard with "
|
| + "respondWith or waitUntil.")));
|
| + }
|
| +
|
| + void OnReceiveResponse(const ResourceResponseHead& response_head) override {
|
| + DCHECK(response_);
|
| + DCHECK(response_head.headers);
|
| + response_->setStatus(response_head.headers->response_code());
|
| + response_->setStatusText(
|
| + blink::WebString::fromUTF8(response_head.headers->GetStatusText()));
|
| + response_->setResponseType(blink::WebServiceWorkerResponseTypeBasic);
|
| + size_t iter = 0;
|
| + std::string header_name;
|
| + std::string header_value;
|
| + while (response_head.headers->EnumerateHeaderLines(&iter, &header_name,
|
| + &header_value)) {
|
| + response_->appendHeader(blink::WebString::fromUTF8(header_name),
|
| + blink::WebString::fromUTF8(header_value));
|
| + }
|
| + response_->setResponseTime(response_head.response_time.ToInternalValue());
|
| + }
|
| +
|
| + void OnStartLoadingResponseBody(
|
| + mojo::ScopedDataPipeConsumerHandle body) override {
|
| + DCHECK(!result_reported_);
|
| + ServiceWorkerContextClient* client =
|
| + ServiceWorkerContextClient::ThreadSpecificInstance();
|
| + if (!client)
|
| + return;
|
| + client->OnNavigationPreloadResponse(
|
| + fetch_event_id_, std::move(response_),
|
| + base::MakeUnique<WebDataConsumerHandleImpl>(std::move(body)));
|
| + result_reported_ = true;
|
| + }
|
| +
|
| + void OnComplete(const ResourceRequestCompletionStatus& status) override {
|
| + // We don't report to |client| if OnStartLoadingResponseBody() has already
|
| + // called OnNavigationPreloadResponse().
|
| + if (result_reported_)
|
| + return;
|
| + DCHECK_NE(0, status.error_code);
|
| + ServiceWorkerContextClient* client =
|
| + ServiceWorkerContextClient::ThreadSpecificInstance();
|
| + if (!client)
|
| + return;
|
| + client->OnNavigationPreloadError(
|
| + fetch_event_id_,
|
| + base::MakeUnique<blink::WebServiceWorkerError>(
|
| + blink::WebServiceWorkerError::ErrorTypeNetwork,
|
| + blink::WebString::fromUTF8(
|
| + "Service Worker navigation preload network error.")));
|
| + result_reported_ = true;
|
| + }
|
| +
|
| + private:
|
| + const int fetch_event_id_;
|
| + mojom::URLLoaderPtr url_loader_;
|
| + mojo::Binding<mojom::URLLoaderClient> binding_;
|
| + std::unique_ptr<blink::WebServiceWorkerResponse> response_;
|
| + bool result_reported_ = false;
|
| +};
|
| +
|
| class ServiceWorkerContextClient::FetchEventDispatcherImpl
|
| : public NON_EXPORTED_BASE(mojom::FetchEventDispatcher) {
|
| public:
|
| @@ -247,12 +342,13 @@ class ServiceWorkerContextClient::FetchEventDispatcherImpl
|
| callback.Run(SERVICE_WORKER_ERROR_ABORT, base::Time::Now());
|
| return;
|
| }
|
| - if (preload_handle) {
|
| - // TODO(horo): Implement this to pass |preload_handle| to FetchEvent.
|
| - NOTIMPLEMENTED();
|
| - return;
|
| - }
|
| - client->DispatchFetchEvent(fetch_event_id, request, callback);
|
| + client->DispatchFetchEvent(
|
| + fetch_event_id, request,
|
| + preload_handle
|
| + ? base::MakeUnique<NavigationPreloadRequest>(
|
| + fetch_event_id, request.url, std::move(preload_handle))
|
| + : nullptr,
|
| + callback);
|
| }
|
|
|
| private:
|
| @@ -635,6 +731,12 @@ void ServiceWorkerContextClient::didHandleFetchEvent(
|
| int fetch_event_id,
|
| blink::WebServiceWorkerEventResult result,
|
| double event_dispatch_time) {
|
| + if (context_->preload_requests.Lookup(fetch_event_id)) {
|
| + // Deletes NavigationPreloadRequest. If the network request is ongoing, it
|
| + // will be canceled by deleting the mojom::URLLoaderPtr in the
|
| + // NavigationPreloadRequest.
|
| + context_->preload_requests.Remove(fetch_event_id);
|
| + }
|
| const FetchCallback* callback =
|
| context_->fetch_event_callbacks.Lookup(fetch_event_id);
|
| if (!callback)
|
| @@ -887,12 +989,18 @@ void ServiceWorkerContextClient::OnInstallEvent(int request_id) {
|
| void ServiceWorkerContextClient::DispatchFetchEvent(
|
| int fetch_event_id,
|
| const ServiceWorkerFetchRequest& request,
|
| + std::unique_ptr<NavigationPreloadRequest> preload_request,
|
| const FetchCallback& callback) {
|
| + const bool navigation_preload_sent = !!preload_request;
|
| blink::WebServiceWorkerRequest webRequest;
|
| TRACE_EVENT0("ServiceWorker",
|
| "ServiceWorkerContextClient::DispatchFetchEvent");
|
| context_->fetch_event_callbacks.AddWithID(new FetchCallback(callback),
|
| fetch_event_id);
|
| + if (preload_request) {
|
| + context_->preload_requests.AddWithID(std::move(preload_request),
|
| + fetch_event_id);
|
| + }
|
|
|
| webRequest.setURL(blink::WebURL(request.url));
|
| webRequest.setMethod(blink::WebString::fromUTF8(request.method));
|
| @@ -922,7 +1030,8 @@ void ServiceWorkerContextClient::DispatchFetchEvent(
|
| if (request.fetch_type == ServiceWorkerFetchType::FOREIGN_FETCH) {
|
| proxy_->dispatchForeignFetchEvent(fetch_event_id, webRequest);
|
| } else {
|
| - proxy_->dispatchFetchEvent(fetch_event_id, webRequest);
|
| + proxy_->dispatchFetchEvent(fetch_event_id, webRequest,
|
| + navigation_preload_sent);
|
| }
|
| }
|
|
|
| @@ -1149,6 +1258,20 @@ void ServiceWorkerContextClient::OnPing() {
|
| Send(new ServiceWorkerHostMsg_Pong(GetRoutingID()));
|
| }
|
|
|
| +void ServiceWorkerContextClient::OnNavigationPreloadResponse(
|
| + int fetch_event_id,
|
| + std::unique_ptr<blink::WebServiceWorkerResponse> response,
|
| + std::unique_ptr<blink::WebDataConsumerHandle> data_consumer_handle) {
|
| + proxy_->onNavigationPreloadResponse(fetch_event_id, std::move(response),
|
| + std::move(data_consumer_handle));
|
| +}
|
| +
|
| +void ServiceWorkerContextClient::OnNavigationPreloadError(
|
| + int fetch_event_id,
|
| + std::unique_ptr<blink::WebServiceWorkerError> error) {
|
| + proxy_->onNavigationPreloadError(fetch_event_id, std::move(error));
|
| +}
|
| +
|
| base::WeakPtr<ServiceWorkerContextClient>
|
| ServiceWorkerContextClient::GetWeakPtr() {
|
| DCHECK(worker_task_runner_->RunsTasksOnCurrentThread());
|
|
|