| 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..59f0cf5154e95834f60b4a767f29ef40fd23a472 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"
|
| @@ -189,6 +190,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 +219,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 +232,82 @@ struct ServiceWorkerContextClient::WorkerContextData {
|
| base::WeakPtrFactory<blink::WebServiceWorkerContextProxy> proxy_weak_factory;
|
| };
|
|
|
| +class ServiceWorkerContextClient::NavigationPreloadRequest final
|
| + : public mojom::URLLoaderClient {
|
| + public:
|
| + NavigationPreloadRequest(const GURL& url,
|
| + mojom::FetchEventPreloadHandlePtr preload_handle)
|
| + : 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 (callback_) {
|
| + callback_->onError(blink::WebServiceWorkerError(
|
| + blink::WebServiceWorkerError::ErrorTypeAbort,
|
| + blink::WebString::fromUTF8(
|
| + "Service Worker navigation preload aborted. Need to guard with "
|
| + "respondWith or waitUntil.")));
|
| + }
|
| + }
|
| +
|
| + void RegisterCallback(
|
| + std::unique_ptr<blink::WebServiceWorkerPreloadResponseCallbacks>
|
| + callback) {
|
| + callback_ = std::move(callback);
|
| + }
|
| +
|
| + 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 {
|
| + std::unique_ptr<blink::WebServiceWorkerPreloadResponseCallbacks> callback(
|
| + std::move(callback_));
|
| + DCHECK(callback);
|
| + blink::WebServiceWorkerPreloadResponseCallbacksResult result;
|
| + result.handle =
|
| + base::MakeUnique<WebDataConsumerHandleImpl>(std::move(body));
|
| + result.response = std::move(response_);
|
| + callback->onSuccess(&result);
|
| + }
|
| +
|
| + void OnComplete(const ResourceRequestCompletionStatus& status) override {
|
| + if (!callback_)
|
| + return;
|
| + DCHECK_NE(0, status.error_code);
|
| + std::unique_ptr<blink::WebServiceWorkerPreloadResponseCallbacks> callback(
|
| + std::move(callback_));
|
| + callback->onError(blink::WebServiceWorkerError(
|
| + blink::WebServiceWorkerError::ErrorTypeNetwork,
|
| + blink::WebString::fromUTF8(
|
| + "Service Worker navigation preload network error.")));
|
| + }
|
| +
|
| + private:
|
| + mojom::URLLoaderPtr url_loader_;
|
| + mojo::Binding<mojom::URLLoaderClient> binding_;
|
| + std::unique_ptr<blink::WebServiceWorkerResponse> response_;
|
| + std::unique_ptr<blink::WebServiceWorkerPreloadResponseCallbacks> callback_;
|
| +};
|
| +
|
| class ServiceWorkerContextClient::FetchEventDispatcherImpl
|
| : public NON_EXPORTED_BASE(mojom::FetchEventDispatcher) {
|
| public:
|
| @@ -247,12 +330,12 @@ 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>(
|
| + request.url, std::move(preload_handle))
|
| + : nullptr,
|
| + callback);
|
| }
|
|
|
| private:
|
| @@ -635,6 +718,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)
|
| @@ -797,6 +886,14 @@ void ServiceWorkerContextClient::registerForeignFetchScopes(
|
| std::vector<url::Origin>(origins.begin(), origins.end())));
|
| }
|
|
|
| +void ServiceWorkerContextClient::registerPreloadResponseCallback(
|
| + int eventID,
|
| + std::unique_ptr<blink::WebServiceWorkerPreloadResponseCallbacks> callback) {
|
| + ServiceWorkerContextClient::NavigationPreloadRequest* preload_request =
|
| + context_->preload_requests.Lookup(eventID);
|
| + preload_request->RegisterCallback(std::move(callback));
|
| +}
|
| +
|
| void ServiceWorkerContextClient::DispatchSyncEvent(
|
| const std::string& tag,
|
| blink::WebServiceWorkerContextProxy::LastChanceOption last_chance,
|
| @@ -887,12 +984,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 +1025,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);
|
| }
|
| }
|
|
|
|
|