OLD | NEW |
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 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 ServiceWorkerFetchType type) { | 273 ServiceWorkerFetchType type) { |
274 if (type == ServiceWorkerFetchType::FOREIGN_FETCH) | 274 if (type == ServiceWorkerFetchType::FOREIGN_FETCH) |
275 return ServiceWorkerMetrics::EventType::FOREIGN_FETCH_WAITUNTIL; | 275 return ServiceWorkerMetrics::EventType::FOREIGN_FETCH_WAITUNTIL; |
276 return ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL; | 276 return ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL; |
277 } | 277 } |
278 | 278 |
279 } // namespace | 279 } // namespace |
280 | 280 |
281 // Helper to receive the fetch event response even if | 281 // Helper to receive the fetch event response even if |
282 // ServiceWorkerFetchDispatcher has been destroyed. | 282 // ServiceWorkerFetchDispatcher has been destroyed. |
283 class ServiceWorkerFetchDispatcher::ResponseCallback { | 283 class ServiceWorkerFetchDispatcher::ResponseCallback |
| 284 : public mojom::ServiceWorkerFetchResponseReceiver { |
284 public: | 285 public: |
285 ResponseCallback(base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher, | 286 ResponseCallback(base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher, |
286 ServiceWorkerVersion* version) | 287 ServiceWorkerVersion* version, |
287 : fetch_dispatcher_(fetch_dispatcher), version_(version) {} | 288 int fetch_event_id) |
| 289 : fetch_dispatcher_(fetch_dispatcher), |
| 290 version_(version), |
| 291 fetch_event_id_(fetch_event_id), |
| 292 binding_(this) { |
| 293 // LOG(ERROR) << "ResponseCallback " << this; |
| 294 } |
| 295 ~ResponseCallback() override { |
| 296 // LOG(ERROR) << "~ResponseCallback " << this; |
| 297 } |
288 | 298 |
289 void Run(int request_id, | 299 void Run(int request_id, |
290 ServiceWorkerFetchEventResult fetch_result, | |
291 const ServiceWorkerResponse& response, | 300 const ServiceWorkerResponse& response, |
292 base::Time dispatch_event_time) { | 301 base::Time dispatch_event_time) { |
293 const bool handled = | 302 // Legacy IPC callback for blob handling. |
294 (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE); | 303 // LOG(ERROR) << "ResponseCallback::Run() " << this; |
295 if (!version_->FinishRequest(request_id, handled, dispatch_event_time)) | 304 DCHECK_EQ(fetch_event_id_, request_id); |
| 305 DCHECK(response.blob_uuid.size()); |
| 306 if (!version_->FinishRequest(request_id, true, dispatch_event_time)) |
296 NOTREACHED() << "Should only receive one reply per event"; | 307 NOTREACHED() << "Should only receive one reply per event"; |
297 | 308 |
298 // |fetch_dispatcher| is null if the URLRequest was killed. | 309 // |fetch_dispatcher| is null if the URLRequest was killed. |
299 if (fetch_dispatcher_) | 310 if (fetch_dispatcher_) |
300 fetch_dispatcher_->DidFinish(request_id, fetch_result, response); | 311 fetch_dispatcher_->DidFinish( |
| 312 request_id, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, response, |
| 313 mojo::ScopedDataPipeConsumerHandle()); |
| 314 } |
| 315 |
| 316 void OnResponse(const ServiceWorkerResponse& response, |
| 317 base::Time dispatch_event_time) override { |
| 318 // LOG(ERROR) << "ResponseCallback::OnResponse() " << this; |
| 319 // Protects |fetch_dispatcher_|. |
| 320 base::WeakPtr<ServiceWorkerFetchDispatcher> dispatcher(fetch_dispatcher_); |
| 321 const int event_id(fetch_event_id_); |
| 322 // FinishRequest() will delete |this|. |
| 323 if (!version_->FinishRequest(fetch_event_id_, true, dispatch_event_time)) |
| 324 NOTREACHED() << "Should only receive one reply per event"; |
| 325 // |dispatcher| is null if the URLRequest was killed. |
| 326 if (!dispatcher) |
| 327 return; |
| 328 dispatcher->DidFinish(event_id, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, |
| 329 response, mojo::ScopedDataPipeConsumerHandle()); |
| 330 } |
| 331 void OnResponseStream(const ServiceWorkerResponse& response, |
| 332 mojo::ScopedDataPipeConsumerHandle stream, |
| 333 base::Time dispatch_event_time) override { |
| 334 // LOG(ERROR) << "ResponseCallback::OnResponseStream() " << this; |
| 335 // TODO(horo): Pass stream. |
| 336 // Protects |fetch_dispatcher_|. |
| 337 base::WeakPtr<ServiceWorkerFetchDispatcher> dispatcher(fetch_dispatcher_); |
| 338 const int event_id(fetch_event_id_); |
| 339 // FinishRequest() will delete |this|. |
| 340 if (!version_->FinishRequest(fetch_event_id_, true, dispatch_event_time)) |
| 341 NOTREACHED() << "Should only receive one reply per event"; |
| 342 // |dispatcher| is null if the URLRequest was killed. |
| 343 if (!dispatcher) |
| 344 return; |
| 345 dispatcher->DidFinish(event_id, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, |
| 346 response, std::move(stream)); |
| 347 } |
| 348 void OnFallback(base::Time dispatch_event_time) override { |
| 349 // LOG(ERROR) << "ResponseCallback::OnFallback() " << this; |
| 350 // Protects |fetch_dispatcher_|. |
| 351 base::WeakPtr<ServiceWorkerFetchDispatcher> dispatcher(fetch_dispatcher_); |
| 352 const int event_id(fetch_event_id_); |
| 353 // FinishRequest() will delete |this|. |
| 354 if (!version_->FinishRequest(fetch_event_id_, false, dispatch_event_time)) |
| 355 NOTREACHED() << "Should only receive one reply per event"; |
| 356 ServiceWorkerResponse response; |
| 357 // |dispatcher| is null if the URLRequest was killed. |
| 358 if (!dispatcher) |
| 359 return; |
| 360 dispatcher->DidFinish(event_id, SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
| 361 response, mojo::ScopedDataPipeConsumerHandle()); |
| 362 } |
| 363 mojom::ServiceWorkerFetchResponseReceiverPtr Bind() { |
| 364 return binding_.CreateInterfacePtrAndBind(); |
301 } | 365 } |
302 | 366 |
303 private: | 367 private: |
304 base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher_; | 368 base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher_; |
305 // Owns |this|. | 369 // Owns |this|. |
306 ServiceWorkerVersion* version_; | 370 ServiceWorkerVersion* version_; |
| 371 const int fetch_event_id_; |
| 372 mojo::Binding<mojom::ServiceWorkerFetchResponseReceiver> binding_; |
307 | 373 |
308 DISALLOW_COPY_AND_ASSIGN(ResponseCallback); | 374 DISALLOW_COPY_AND_ASSIGN(ResponseCallback); |
309 }; | 375 }; |
310 | 376 |
311 // This class keeps the URL loader related assets alive while the FetchEvent is | 377 // This class keeps the URL loader related assets alive while the FetchEvent is |
312 // ongoing in the service worker. | 378 // ongoing in the service worker. |
313 class ServiceWorkerFetchDispatcher::URLLoaderAssets | 379 class ServiceWorkerFetchDispatcher::URLLoaderAssets |
314 : public base::RefCounted<ServiceWorkerFetchDispatcher::URLLoaderAssets> { | 380 : public base::RefCounted<ServiceWorkerFetchDispatcher::URLLoaderAssets> { |
315 public: | 381 public: |
316 URLLoaderAssets(mojom::URLLoaderFactoryPtr url_loader_factory, | 382 URLLoaderAssets(mojom::URLLoaderFactoryPtr url_loader_factory, |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 } else { | 510 } else { |
445 fetch_event_id = version_->StartRequest( | 511 fetch_event_id = version_->StartRequest( |
446 GetEventType(), | 512 GetEventType(), |
447 base::Bind(&ServiceWorkerFetchDispatcher::DidFailToDispatch, | 513 base::Bind(&ServiceWorkerFetchDispatcher::DidFailToDispatch, |
448 weak_factory_.GetWeakPtr())); | 514 weak_factory_.GetWeakPtr())); |
449 event_finish_id = version_->StartRequest( | 515 event_finish_id = version_->StartRequest( |
450 FetchTypeToWaitUntilEventType(request_->fetch_type), | 516 FetchTypeToWaitUntilEventType(request_->fetch_type), |
451 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 517 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
452 } | 518 } |
453 | 519 |
454 ResponseCallback* response_callback = | 520 ResponseCallback* response_callback = new ResponseCallback( |
455 new ResponseCallback(weak_factory_.GetWeakPtr(), version_.get()); | 521 weak_factory_.GetWeakPtr(), version_.get(), fetch_event_id); |
| 522 mojom::ServiceWorkerFetchResponseReceiverPtr receiver( |
| 523 response_callback->Bind()); |
456 version_->RegisterRequestCallback<ServiceWorkerHostMsg_FetchEventResponse>( | 524 version_->RegisterRequestCallback<ServiceWorkerHostMsg_FetchEventResponse>( |
457 fetch_event_id, | 525 fetch_event_id, |
458 base::Bind(&ServiceWorkerFetchDispatcher::ResponseCallback::Run, | 526 base::Bind(&ServiceWorkerFetchDispatcher::ResponseCallback::Run, |
459 base::Owned(response_callback))); | 527 base::Owned(response_callback))); |
460 | 528 |
461 if (url_loader_assets_) { | 529 if (url_loader_assets_) { |
462 url_loader_assets_->MayBeReportToDevTools( | 530 url_loader_assets_->MayBeReportToDevTools( |
463 std::make_pair( | 531 std::make_pair( |
464 version_->embedded_worker()->process_id(), | 532 version_->embedded_worker()->process_id(), |
465 version_->embedded_worker()->worker_devtools_agent_route_id()), | 533 version_->embedded_worker()->worker_devtools_agent_route_id()), |
466 fetch_event_id); | 534 fetch_event_id); |
467 } | 535 } |
468 | 536 |
469 // |event_dispatcher| is owned by |version_|. So it is safe to pass the | 537 // |event_dispatcher| is owned by |version_|. So it is safe to pass the |
470 // unretained raw pointer of |version_| to OnFetchEventFinished callback. | 538 // unretained raw pointer of |version_| to OnFetchEventFinished callback. |
471 // Pass |url_loader_assets_| to the callback to keep the URL loader related | 539 // Pass |url_loader_assets_| to the callback to keep the URL loader related |
472 // assets alive while the FetchEvent is ongoing in the service worker. | 540 // assets alive while the FetchEvent is ongoing in the service worker. |
473 version_->event_dispatcher()->DispatchFetchEvent( | 541 version_->event_dispatcher()->DispatchFetchEvent( |
474 fetch_event_id, *request_, std::move(preload_handle_), | 542 fetch_event_id, *request_, std::move(preload_handle_), |
| 543 std::move(receiver), |
475 base::Bind(&ServiceWorkerFetchDispatcher::OnFetchEventFinished, | 544 base::Bind(&ServiceWorkerFetchDispatcher::OnFetchEventFinished, |
476 base::Unretained(version_.get()), event_finish_id, | 545 base::Unretained(version_.get()), event_finish_id, |
477 url_loader_assets_)); | 546 url_loader_assets_)); |
478 } | 547 } |
479 | 548 |
480 void ServiceWorkerFetchDispatcher::DidFailToDispatch( | 549 void ServiceWorkerFetchDispatcher::DidFailToDispatch( |
481 ServiceWorkerStatusCode status) { | 550 ServiceWorkerStatusCode status) { |
482 EndNetLogEventWithServiceWorkerStatus( | 551 EndNetLogEventWithServiceWorkerStatus( |
483 net_log_, net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT, status); | 552 net_log_, net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT, status); |
484 DidFail(status); | 553 DidFail(status); |
485 } | 554 } |
486 | 555 |
487 void ServiceWorkerFetchDispatcher::DidFail(ServiceWorkerStatusCode status) { | 556 void ServiceWorkerFetchDispatcher::DidFail(ServiceWorkerStatusCode status) { |
488 DCHECK_NE(SERVICE_WORKER_OK, status); | 557 DCHECK_NE(SERVICE_WORKER_OK, status); |
489 Complete(status, SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, | 558 Complete(status, SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
490 ServiceWorkerResponse()); | 559 ServiceWorkerResponse(), mojo::ScopedDataPipeConsumerHandle()); |
491 } | 560 } |
492 | 561 |
493 void ServiceWorkerFetchDispatcher::DidFinish( | 562 void ServiceWorkerFetchDispatcher::DidFinish( |
494 int request_id, | 563 int request_id, |
495 ServiceWorkerFetchEventResult fetch_result, | 564 ServiceWorkerFetchEventResult fetch_result, |
496 const ServiceWorkerResponse& response) { | 565 const ServiceWorkerResponse& response, |
| 566 mojo::ScopedDataPipeConsumerHandle stream) { |
497 net_log_.EndEvent(net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT); | 567 net_log_.EndEvent(net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT); |
498 Complete(SERVICE_WORKER_OK, fetch_result, response); | 568 Complete(SERVICE_WORKER_OK, fetch_result, response, std::move(stream)); |
499 } | 569 } |
500 | 570 |
501 void ServiceWorkerFetchDispatcher::Complete( | 571 void ServiceWorkerFetchDispatcher::Complete( |
502 ServiceWorkerStatusCode status, | 572 ServiceWorkerStatusCode status, |
503 ServiceWorkerFetchEventResult fetch_result, | 573 ServiceWorkerFetchEventResult fetch_result, |
504 const ServiceWorkerResponse& response) { | 574 const ServiceWorkerResponse& response, |
| 575 mojo::ScopedDataPipeConsumerHandle stream) { |
505 DCHECK(!fetch_callback_.is_null()); | 576 DCHECK(!fetch_callback_.is_null()); |
506 | 577 |
507 did_complete_ = true; | 578 did_complete_ = true; |
508 net_log_.EndEvent( | 579 net_log_.EndEvent( |
509 net::NetLogEventType::SERVICE_WORKER_DISPATCH_FETCH_EVENT, | 580 net::NetLogEventType::SERVICE_WORKER_DISPATCH_FETCH_EVENT, |
510 base::Bind(&NetLogFetchEventCallback, status, fetch_result)); | 581 base::Bind(&NetLogFetchEventCallback, status, fetch_result)); |
511 | 582 |
512 FetchCallback fetch_callback = fetch_callback_; | 583 FetchCallback fetch_callback = fetch_callback_; |
513 scoped_refptr<ServiceWorkerVersion> version = version_; | 584 scoped_refptr<ServiceWorkerVersion> version = version_; |
514 fetch_callback.Run(status, fetch_result, response, version); | 585 fetch_callback.Run(status, fetch_result, response, std::move(stream), |
| 586 version); |
515 } | 587 } |
516 | 588 |
517 bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload( | 589 bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload( |
518 net::URLRequest* original_request, | 590 net::URLRequest* original_request, |
519 base::OnceClosure on_response) { | 591 base::OnceClosure on_response) { |
520 if (resource_type_ != RESOURCE_TYPE_MAIN_FRAME && | 592 if (resource_type_ != RESOURCE_TYPE_MAIN_FRAME && |
521 resource_type_ != RESOURCE_TYPE_SUB_FRAME) { | 593 resource_type_ != RESOURCE_TYPE_SUB_FRAME) { |
522 return false; | 594 return false; |
523 } | 595 } |
524 if (!version_->navigation_preload_state().enabled) | 596 if (!version_->navigation_preload_state().enabled) |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 ServiceWorkerVersion* version, | 696 ServiceWorkerVersion* version, |
625 int event_finish_id, | 697 int event_finish_id, |
626 scoped_refptr<URLLoaderAssets> url_loader_assets, | 698 scoped_refptr<URLLoaderAssets> url_loader_assets, |
627 ServiceWorkerStatusCode status, | 699 ServiceWorkerStatusCode status, |
628 base::Time dispatch_event_time) { | 700 base::Time dispatch_event_time) { |
629 version->FinishRequest(event_finish_id, status != SERVICE_WORKER_ERROR_ABORT, | 701 version->FinishRequest(event_finish_id, status != SERVICE_WORKER_ERROR_ABORT, |
630 dispatch_event_time); | 702 dispatch_event_time); |
631 } | 703 } |
632 | 704 |
633 } // namespace content | 705 } // namespace content |
OLD | NEW |