| Index: content/browser/service_worker/service_worker_fetch_dispatcher.cc
|
| diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
|
| index ded2b794e4ed0cad9bae7954a4bc69530098b243..85cf9d7db3ad27aae10f29f51f41cb6f0955f03d 100644
|
| --- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
|
| +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
|
| @@ -75,7 +75,14 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
|
| public:
|
| explicit DelegatingURLLoaderClient(mojom::URLLoaderClientPtr client)
|
| : binding_(this), client_(std::move(client)) {}
|
| - ~DelegatingURLLoaderClient() override {}
|
| + ~DelegatingURLLoaderClient() override {
|
| + if (!completed_) {
|
| + // Let the service worker know that the request has been canceled.
|
| + ResourceRequestCompletionStatus status;
|
| + status.error_code = net::ERR_ABORTED;
|
| + client_->OnComplete(status);
|
| + }
|
| + }
|
|
|
| void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {
|
| client_->OnDataDownloaded(data_length, encoded_length);
|
| @@ -102,6 +109,7 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
|
| void OnComplete(
|
| const ResourceRequestCompletionStatus& completion_status) override {
|
| client_->OnComplete(completion_status);
|
| + completed_ = true;
|
| }
|
|
|
| void Bind(mojom::URLLoaderClientAssociatedPtrInfo* ptr_info,
|
| @@ -112,6 +120,7 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
|
| private:
|
| mojo::AssociatedBinding<mojom::URLLoaderClient> binding_;
|
| mojom::URLLoaderClientPtr client_;
|
| + bool completed_ = false;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(DelegatingURLLoaderClient);
|
| };
|
| @@ -167,18 +176,6 @@ ServiceWorkerMetrics::EventType FetchTypeToWaitUntilEventType(
|
| return ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL;
|
| }
|
|
|
| -void OnFetchEventFinished(
|
| - ServiceWorkerVersion* version,
|
| - int event_finish_id,
|
| - mojom::URLLoaderFactoryPtr url_loader_factory,
|
| - std::unique_ptr<mojom::URLLoader> url_loader,
|
| - std::unique_ptr<mojom::URLLoaderClient> url_loader_client,
|
| - ServiceWorkerStatusCode status,
|
| - base::Time dispatch_event_time) {
|
| - version->FinishRequest(event_finish_id, status != SERVICE_WORKER_ERROR_ABORT,
|
| - dispatch_event_time);
|
| -}
|
| -
|
| } // namespace
|
|
|
| // Helper to receive the fetch event response even if
|
| @@ -211,6 +208,29 @@ class ServiceWorkerFetchDispatcher::ResponseCallback {
|
| DISALLOW_COPY_AND_ASSIGN(ResponseCallback);
|
| };
|
|
|
| +// This class keeps the URL loader related assets alive while the FetchEvent is
|
| +// ongoing in the service worker.
|
| +class ServiceWorkerFetchDispatcher::URLLoaderAssets
|
| + : public base::RefCounted<ServiceWorkerFetchDispatcher::URLLoaderAssets> {
|
| + public:
|
| + URLLoaderAssets(mojom::URLLoaderFactoryPtr url_loader_factory,
|
| + std::unique_ptr<mojom::URLLoader> url_loader,
|
| + std::unique_ptr<mojom::URLLoaderClient> url_loader_client)
|
| + : url_loader_factory_(std::move(url_loader_factory)),
|
| + url_loader_(std::move(url_loader)),
|
| + url_loader_client_(std::move(url_loader_client)) {}
|
| +
|
| + private:
|
| + friend class base::RefCounted<URLLoaderAssets>;
|
| + virtual ~URLLoaderAssets() {}
|
| +
|
| + mojom::URLLoaderFactoryPtr url_loader_factory_;
|
| + std::unique_ptr<mojom::URLLoader> url_loader_;
|
| + std::unique_ptr<mojom::URLLoaderClient> url_loader_client_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(URLLoaderAssets);
|
| +};
|
| +
|
| ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
|
| std::unique_ptr<ServiceWorkerFetchRequest> request,
|
| ServiceWorkerVersion* version,
|
| @@ -335,15 +355,13 @@ void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
|
|
|
| // |event_dispatcher| is owned by |version_|. So it is safe to pass the
|
| // unretained raw pointer of |version_| to OnFetchEventFinished callback.
|
| - // Pass |url_loader_factory_|, |url_Loader_| and |url_loader_client_| to the
|
| - // callback to keep them alive while the FetchEvent is onging in the service
|
| - // worker.
|
| + // Pass |url_loader_assets_| to the callback to keep the URL loader related
|
| + // assets alive while the FetchEvent is ongoing in the service worker.
|
| version_->event_dispatcher()->DispatchFetchEvent(
|
| fetch_event_id, *request_, std::move(preload_handle_),
|
| - base::Bind(&OnFetchEventFinished, base::Unretained(version_.get()),
|
| - event_finish_id, base::Passed(std::move(url_loader_factory_)),
|
| - base::Passed(std::move(url_loader_)),
|
| - base::Passed(std::move(url_loader_client_))));
|
| + base::Bind(&ServiceWorkerFetchDispatcher::OnFetchEventFinished,
|
| + base::Unretained(version_.get()), event_finish_id,
|
| + url_loader_assets_));
|
| }
|
|
|
| void ServiceWorkerFetchDispatcher::DidFailToDispatch(
|
| @@ -413,11 +431,12 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
|
| return false;
|
| }
|
|
|
| - DCHECK(!url_loader_factory_);
|
| - mojom::URLLoaderFactoryPtr factory;
|
| + DCHECK(!url_loader_assets_);
|
| +
|
| + mojom::URLLoaderFactoryPtr url_loader_factory;
|
| URLLoaderFactoryImpl::Create(
|
| ResourceRequesterInfo::CreateForNavigationPreload(requester_info),
|
| - mojo::MakeRequest(&url_loader_factory_));
|
| + mojo::MakeRequest(&url_loader_factory));
|
|
|
| preload_handle_ = mojom::FetchEventPreloadHandle::New();
|
|
|
| @@ -460,20 +479,22 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
|
| std::move(url_loader_client_ptr));
|
| mojom::URLLoaderClientAssociatedPtrInfo url_loader_client_associated_ptr_info;
|
| url_loader_client->Bind(&url_loader_client_associated_ptr_info,
|
| - url_loader_factory_.associated_group());
|
| + url_loader_factory.associated_group());
|
| mojom::URLLoaderAssociatedPtr url_loader_associated_ptr;
|
|
|
| - url_loader_factory_->CreateLoaderAndStart(
|
| + url_loader_factory->CreateLoaderAndStart(
|
| mojo::MakeRequest(&url_loader_associated_ptr,
|
| - url_loader_factory_.associated_group()),
|
| + url_loader_factory.associated_group()),
|
| original_info->GetRouteID(), request_id, request,
|
| std::move(url_loader_client_associated_ptr_info));
|
|
|
| std::unique_ptr<DelegatingURLLoader> url_loader(
|
| - new DelegatingURLLoader(std::move(url_loader_associated_ptr)));
|
| + base::MakeUnique<DelegatingURLLoader>(
|
| + std::move(url_loader_associated_ptr)));
|
| preload_handle_->url_loader = url_loader->CreateInterfacePtrAndBind();
|
| - url_loader_ = std::move(url_loader);
|
| - url_loader_client_ = std::move(url_loader_client);
|
| + url_loader_assets_ =
|
| + new URLLoaderAssets(std::move(url_loader_factory), std::move(url_loader),
|
| + std::move(url_loader_client));
|
| return true;
|
| }
|
|
|
| @@ -484,4 +505,15 @@ ServiceWorkerMetrics::EventType ServiceWorkerFetchDispatcher::GetEventType()
|
| return ResourceTypeToEventType(resource_type_);
|
| }
|
|
|
| +// static
|
| +void ServiceWorkerFetchDispatcher::OnFetchEventFinished(
|
| + ServiceWorkerVersion* version,
|
| + int event_finish_id,
|
| + scoped_refptr<URLLoaderAssets> url_loader_assets,
|
| + ServiceWorkerStatusCode status,
|
| + base::Time dispatch_event_time) {
|
| + version->FinishRequest(event_finish_id, status != SERVICE_WORKER_ERROR_ABORT,
|
| + dispatch_event_time);
|
| +}
|
| +
|
| } // namespace content
|
|
|