Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3452)

Side by Side Diff: content/browser/service_worker/service_worker_fetch_dispatcher.cc

Issue 2645493002: Increase the lifetime of Navigation Preload related objects. (Closed)
Patch Set: fix broken-chunked-encoding-worker.js Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" 5 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 DISALLOW_COPY_AND_ASSIGN(DelegatingURLLoader); 68 DISALLOW_COPY_AND_ASSIGN(DelegatingURLLoader);
69 }; 69 };
70 70
71 // This class wraps a mojo::InterfacePtr<URLLoaderClient>. It also is a 71 // This class wraps a mojo::InterfacePtr<URLLoaderClient>. It also is a
72 // URLLoaderClient implementation and delegates URLLoaderClient calls to the 72 // URLLoaderClient implementation and delegates URLLoaderClient calls to the
73 // wrapped client. 73 // wrapped client.
74 class DelegatingURLLoaderClient final : public mojom::URLLoaderClient { 74 class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
75 public: 75 public:
76 explicit DelegatingURLLoaderClient(mojom::URLLoaderClientPtr client) 76 explicit DelegatingURLLoaderClient(mojom::URLLoaderClientPtr client)
77 : binding_(this), client_(std::move(client)) {} 77 : binding_(this), client_(std::move(client)) {}
78 ~DelegatingURLLoaderClient() override {} 78 ~DelegatingURLLoaderClient() override {
79 if (!completed_) {
80 // Let the service worker know that the request has been canceled.
81 ResourceRequestCompletionStatus status;
82 status.error_code = net::ERR_ABORTED;
83 client_->OnComplete(status);
84 }
85 }
79 86
80 void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override { 87 void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {
81 client_->OnDataDownloaded(data_length, encoded_length); 88 client_->OnDataDownloaded(data_length, encoded_length);
82 } 89 }
83 void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override { 90 void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {
84 client_->OnReceiveCachedMetadata(data); 91 client_->OnReceiveCachedMetadata(data);
85 } 92 }
86 void OnTransferSizeUpdated(int32_t transfer_size_diff) override { 93 void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
87 client_->OnTransferSizeUpdated(transfer_size_diff); 94 client_->OnTransferSizeUpdated(transfer_size_diff);
88 } 95 }
89 void OnReceiveResponse( 96 void OnReceiveResponse(
90 const ResourceResponseHead& head, 97 const ResourceResponseHead& head,
91 mojom::DownloadedTempFilePtr downloaded_file) override { 98 mojom::DownloadedTempFilePtr downloaded_file) override {
92 client_->OnReceiveResponse(head, std::move(downloaded_file)); 99 client_->OnReceiveResponse(head, std::move(downloaded_file));
93 } 100 }
94 void OnReceiveRedirect(const net::RedirectInfo& redirect_info, 101 void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
95 const ResourceResponseHead& head) override { 102 const ResourceResponseHead& head) override {
96 client_->OnReceiveRedirect(redirect_info, head); 103 client_->OnReceiveRedirect(redirect_info, head);
97 } 104 }
98 void OnStartLoadingResponseBody( 105 void OnStartLoadingResponseBody(
99 mojo::ScopedDataPipeConsumerHandle body) override { 106 mojo::ScopedDataPipeConsumerHandle body) override {
100 client_->OnStartLoadingResponseBody(std::move(body)); 107 client_->OnStartLoadingResponseBody(std::move(body));
101 } 108 }
102 void OnComplete( 109 void OnComplete(
103 const ResourceRequestCompletionStatus& completion_status) override { 110 const ResourceRequestCompletionStatus& completion_status) override {
104 client_->OnComplete(completion_status); 111 client_->OnComplete(completion_status);
112 completed_ = true;
105 } 113 }
106 114
107 void Bind(mojom::URLLoaderClientAssociatedPtrInfo* ptr_info, 115 void Bind(mojom::URLLoaderClientAssociatedPtrInfo* ptr_info,
108 mojo::AssociatedGroup* associated_group) { 116 mojo::AssociatedGroup* associated_group) {
109 binding_.Bind(ptr_info, associated_group); 117 binding_.Bind(ptr_info, associated_group);
110 } 118 }
111 119
112 private: 120 private:
113 mojo::AssociatedBinding<mojom::URLLoaderClient> binding_; 121 mojo::AssociatedBinding<mojom::URLLoaderClient> binding_;
114 mojom::URLLoaderClientPtr client_; 122 mojom::URLLoaderClientPtr client_;
123 bool completed_ = false;
115 124
116 DISALLOW_COPY_AND_ASSIGN(DelegatingURLLoaderClient); 125 DISALLOW_COPY_AND_ASSIGN(DelegatingURLLoaderClient);
117 }; 126 };
118 127
119 using EventType = ServiceWorkerMetrics::EventType; 128 using EventType = ServiceWorkerMetrics::EventType;
120 EventType ResourceTypeToEventType(ResourceType resource_type) { 129 EventType ResourceTypeToEventType(ResourceType resource_type) {
121 switch (resource_type) { 130 switch (resource_type) {
122 case RESOURCE_TYPE_MAIN_FRAME: 131 case RESOURCE_TYPE_MAIN_FRAME:
123 return EventType::FETCH_MAIN_FRAME; 132 return EventType::FETCH_MAIN_FRAME;
124 case RESOURCE_TYPE_SUB_FRAME: 133 case RESOURCE_TYPE_SUB_FRAME:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 base::Bind(&NetLogServiceWorkerStatusCallback, status)); 169 base::Bind(&NetLogServiceWorkerStatusCallback, status));
161 } 170 }
162 171
163 ServiceWorkerMetrics::EventType FetchTypeToWaitUntilEventType( 172 ServiceWorkerMetrics::EventType FetchTypeToWaitUntilEventType(
164 ServiceWorkerFetchType type) { 173 ServiceWorkerFetchType type) {
165 if (type == ServiceWorkerFetchType::FOREIGN_FETCH) 174 if (type == ServiceWorkerFetchType::FOREIGN_FETCH)
166 return ServiceWorkerMetrics::EventType::FOREIGN_FETCH_WAITUNTIL; 175 return ServiceWorkerMetrics::EventType::FOREIGN_FETCH_WAITUNTIL;
167 return ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL; 176 return ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL;
168 } 177 }
169 178
170 void OnFetchEventFinished(
171 ServiceWorkerVersion* version,
172 int event_finish_id,
173 mojom::URLLoaderFactoryPtr url_loader_factory,
174 std::unique_ptr<mojom::URLLoader> url_loader,
175 std::unique_ptr<mojom::URLLoaderClient> url_loader_client,
176 ServiceWorkerStatusCode status,
177 base::Time dispatch_event_time) {
178 version->FinishRequest(event_finish_id, status != SERVICE_WORKER_ERROR_ABORT,
179 dispatch_event_time);
180 }
181
182 } // namespace 179 } // namespace
183 180
184 // Helper to receive the fetch event response even if 181 // Helper to receive the fetch event response even if
185 // ServiceWorkerFetchDispatcher has been destroyed. 182 // ServiceWorkerFetchDispatcher has been destroyed.
186 class ServiceWorkerFetchDispatcher::ResponseCallback { 183 class ServiceWorkerFetchDispatcher::ResponseCallback {
187 public: 184 public:
188 ResponseCallback(base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher, 185 ResponseCallback(base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher,
189 ServiceWorkerVersion* version) 186 ServiceWorkerVersion* version)
190 : fetch_dispatcher_(fetch_dispatcher), version_(version) {} 187 : fetch_dispatcher_(fetch_dispatcher), version_(version) {}
191 188
(...skipping 12 matching lines...) Expand all
204 } 201 }
205 202
206 private: 203 private:
207 base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher_; 204 base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher_;
208 // Owns |this|. 205 // Owns |this|.
209 ServiceWorkerVersion* version_; 206 ServiceWorkerVersion* version_;
210 207
211 DISALLOW_COPY_AND_ASSIGN(ResponseCallback); 208 DISALLOW_COPY_AND_ASSIGN(ResponseCallback);
212 }; 209 };
213 210
211 // This class keeps the URL loader related assets alive while the FetchEvent is
212 // ongoing in the service worker.
213 class ServiceWorkerFetchDispatcher::URLLoaderAssets
214 : public base::RefCounted<ServiceWorkerFetchDispatcher::URLLoaderAssets> {
215 public:
216 URLLoaderAssets(mojom::URLLoaderFactoryPtr url_loader_factory,
217 std::unique_ptr<mojom::URLLoader> url_loader,
218 std::unique_ptr<mojom::URLLoaderClient> url_loader_client)
219 : url_loader_factory_(std::move(url_loader_factory)),
220 url_loader_(std::move(url_loader)),
221 url_loader_client_(std::move(url_loader_client)) {}
222
223 private:
224 friend class base::RefCounted<URLLoaderAssets>;
225 virtual ~URLLoaderAssets() {}
226
227 mojom::URLLoaderFactoryPtr url_loader_factory_;
228 std::unique_ptr<mojom::URLLoader> url_loader_;
229 std::unique_ptr<mojom::URLLoaderClient> url_loader_client_;
230
231 DISALLOW_COPY_AND_ASSIGN(URLLoaderAssets);
232 };
233
214 ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher( 234 ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
215 std::unique_ptr<ServiceWorkerFetchRequest> request, 235 std::unique_ptr<ServiceWorkerFetchRequest> request,
216 ServiceWorkerVersion* version, 236 ServiceWorkerVersion* version,
217 ResourceType resource_type, 237 ResourceType resource_type,
218 const base::Optional<base::TimeDelta>& timeout, 238 const base::Optional<base::TimeDelta>& timeout,
219 const net::NetLogWithSource& net_log, 239 const net::NetLogWithSource& net_log,
220 const base::Closure& prepare_callback, 240 const base::Closure& prepare_callback,
221 const FetchCallback& fetch_callback) 241 const FetchCallback& fetch_callback)
222 : version_(version), 242 : version_(version),
223 net_log_(net_log), 243 net_log_(net_log),
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 348
329 ResponseCallback* response_callback = 349 ResponseCallback* response_callback =
330 new ResponseCallback(weak_factory_.GetWeakPtr(), version_.get()); 350 new ResponseCallback(weak_factory_.GetWeakPtr(), version_.get());
331 version_->RegisterRequestCallback<ServiceWorkerHostMsg_FetchEventResponse>( 351 version_->RegisterRequestCallback<ServiceWorkerHostMsg_FetchEventResponse>(
332 fetch_event_id, 352 fetch_event_id,
333 base::Bind(&ServiceWorkerFetchDispatcher::ResponseCallback::Run, 353 base::Bind(&ServiceWorkerFetchDispatcher::ResponseCallback::Run,
334 base::Owned(response_callback))); 354 base::Owned(response_callback)));
335 355
336 // |event_dispatcher| is owned by |version_|. So it is safe to pass the 356 // |event_dispatcher| is owned by |version_|. So it is safe to pass the
337 // unretained raw pointer of |version_| to OnFetchEventFinished callback. 357 // unretained raw pointer of |version_| to OnFetchEventFinished callback.
338 // Pass |url_loader_factory_|, |url_Loader_| and |url_loader_client_| to the 358 // Pass |url_loader_assets_| to the callback to keep the URL loader related
339 // callback to keep them alive while the FetchEvent is onging in the service 359 // assets alive while the FetchEvent is ongoing in the service worker.
340 // worker.
341 version_->event_dispatcher()->DispatchFetchEvent( 360 version_->event_dispatcher()->DispatchFetchEvent(
342 fetch_event_id, *request_, std::move(preload_handle_), 361 fetch_event_id, *request_, std::move(preload_handle_),
343 base::Bind(&OnFetchEventFinished, base::Unretained(version_.get()), 362 base::Bind(&ServiceWorkerFetchDispatcher::OnFetchEventFinished,
344 event_finish_id, base::Passed(std::move(url_loader_factory_)), 363 base::Unretained(version_.get()), event_finish_id,
345 base::Passed(std::move(url_loader_)), 364 url_loader_assets_));
346 base::Passed(std::move(url_loader_client_))));
347 } 365 }
348 366
349 void ServiceWorkerFetchDispatcher::DidFailToDispatch( 367 void ServiceWorkerFetchDispatcher::DidFailToDispatch(
350 ServiceWorkerStatusCode status) { 368 ServiceWorkerStatusCode status) {
351 EndNetLogEventWithServiceWorkerStatus( 369 EndNetLogEventWithServiceWorkerStatus(
352 net_log_, net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT, status); 370 net_log_, net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT, status);
353 DidFail(status); 371 DidFail(status);
354 } 372 }
355 373
356 void ServiceWorkerFetchDispatcher::DidFail(ServiceWorkerStatusCode status) { 374 void ServiceWorkerFetchDispatcher::DidFail(ServiceWorkerStatusCode status) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 ResourceRequestInfoImpl::ForRequest(original_request); 424 ResourceRequestInfoImpl::ForRequest(original_request);
407 ResourceRequesterInfo* requester_info = original_info->requester_info(); 425 ResourceRequesterInfo* requester_info = original_info->requester_info();
408 if (IsBrowserSideNavigationEnabled()) { 426 if (IsBrowserSideNavigationEnabled()) {
409 DCHECK(requester_info->IsBrowserSideNavigation()); 427 DCHECK(requester_info->IsBrowserSideNavigation());
410 } else { 428 } else {
411 DCHECK(requester_info->IsRenderer()); 429 DCHECK(requester_info->IsRenderer());
412 if (!requester_info->filter()) 430 if (!requester_info->filter())
413 return false; 431 return false;
414 } 432 }
415 433
416 DCHECK(!url_loader_factory_); 434 DCHECK(!url_loader_assets_);
417 mojom::URLLoaderFactoryPtr factory; 435
436 mojom::URLLoaderFactoryPtr url_loader_factory;
418 URLLoaderFactoryImpl::Create( 437 URLLoaderFactoryImpl::Create(
419 ResourceRequesterInfo::CreateForNavigationPreload(requester_info), 438 ResourceRequesterInfo::CreateForNavigationPreload(requester_info),
420 mojo::MakeRequest(&url_loader_factory_)); 439 mojo::MakeRequest(&url_loader_factory));
421 440
422 preload_handle_ = mojom::FetchEventPreloadHandle::New(); 441 preload_handle_ = mojom::FetchEventPreloadHandle::New();
423 442
424 ResourceRequest request; 443 ResourceRequest request;
425 request.method = original_request->method(); 444 request.method = original_request->method();
426 request.url = original_request->url(); 445 request.url = original_request->url();
427 // TODO(horo): Set first_party_for_cookies to support Same-site Cookies. 446 // TODO(horo): Set first_party_for_cookies to support Same-site Cookies.
428 request.request_initiator = original_request->initiator().has_value() 447 request.request_initiator = original_request->initiator().has_value()
429 ? original_request->initiator() 448 ? original_request->initiator()
430 : url::Origin(original_request->url()); 449 : url::Origin(original_request->url());
(...skipping 22 matching lines...) Expand all
453 DCHECK_LT(request_id, -1); 472 DCHECK_LT(request_id, -1);
454 473
455 preload_handle_ = mojom::FetchEventPreloadHandle::New(); 474 preload_handle_ = mojom::FetchEventPreloadHandle::New();
456 mojom::URLLoaderClientPtr url_loader_client_ptr; 475 mojom::URLLoaderClientPtr url_loader_client_ptr;
457 preload_handle_->url_loader_client_request = 476 preload_handle_->url_loader_client_request =
458 mojo::MakeRequest(&url_loader_client_ptr); 477 mojo::MakeRequest(&url_loader_client_ptr);
459 auto url_loader_client = base::MakeUnique<DelegatingURLLoaderClient>( 478 auto url_loader_client = base::MakeUnique<DelegatingURLLoaderClient>(
460 std::move(url_loader_client_ptr)); 479 std::move(url_loader_client_ptr));
461 mojom::URLLoaderClientAssociatedPtrInfo url_loader_client_associated_ptr_info; 480 mojom::URLLoaderClientAssociatedPtrInfo url_loader_client_associated_ptr_info;
462 url_loader_client->Bind(&url_loader_client_associated_ptr_info, 481 url_loader_client->Bind(&url_loader_client_associated_ptr_info,
463 url_loader_factory_.associated_group()); 482 url_loader_factory.associated_group());
464 mojom::URLLoaderAssociatedPtr url_loader_associated_ptr; 483 mojom::URLLoaderAssociatedPtr url_loader_associated_ptr;
465 484
466 url_loader_factory_->CreateLoaderAndStart( 485 url_loader_factory->CreateLoaderAndStart(
467 mojo::MakeRequest(&url_loader_associated_ptr, 486 mojo::MakeRequest(&url_loader_associated_ptr,
468 url_loader_factory_.associated_group()), 487 url_loader_factory.associated_group()),
469 original_info->GetRouteID(), request_id, request, 488 original_info->GetRouteID(), request_id, request,
470 std::move(url_loader_client_associated_ptr_info)); 489 std::move(url_loader_client_associated_ptr_info));
471 490
472 std::unique_ptr<DelegatingURLLoader> url_loader( 491 std::unique_ptr<DelegatingURLLoader> url_loader(
473 new DelegatingURLLoader(std::move(url_loader_associated_ptr))); 492 base::MakeUnique<DelegatingURLLoader>(
493 std::move(url_loader_associated_ptr)));
474 preload_handle_->url_loader = url_loader->CreateInterfacePtrAndBind(); 494 preload_handle_->url_loader = url_loader->CreateInterfacePtrAndBind();
475 url_loader_ = std::move(url_loader); 495 url_loader_assets_ =
476 url_loader_client_ = std::move(url_loader_client); 496 new URLLoaderAssets(std::move(url_loader_factory), std::move(url_loader),
497 std::move(url_loader_client));
477 return true; 498 return true;
478 } 499 }
479 500
480 ServiceWorkerMetrics::EventType ServiceWorkerFetchDispatcher::GetEventType() 501 ServiceWorkerMetrics::EventType ServiceWorkerFetchDispatcher::GetEventType()
481 const { 502 const {
482 if (request_->fetch_type == ServiceWorkerFetchType::FOREIGN_FETCH) 503 if (request_->fetch_type == ServiceWorkerFetchType::FOREIGN_FETCH)
483 return ServiceWorkerMetrics::EventType::FOREIGN_FETCH; 504 return ServiceWorkerMetrics::EventType::FOREIGN_FETCH;
484 return ResourceTypeToEventType(resource_type_); 505 return ResourceTypeToEventType(resource_type_);
485 } 506 }
486 507
508 // static
509 void ServiceWorkerFetchDispatcher::OnFetchEventFinished(
510 ServiceWorkerVersion* version,
511 int event_finish_id,
512 scoped_refptr<URLLoaderAssets> url_loader_assets,
513 ServiceWorkerStatusCode status,
514 base::Time dispatch_event_time) {
515 version->FinishRequest(event_finish_id, status != SERVICE_WORKER_ERROR_ABORT,
516 dispatch_event_time);
517 }
518
487 } // namespace content 519 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698