Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_dispatcher_host.h" | 5 #include "content/browser/service_worker/service_worker_dispatcher_host.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/profiler/scoped_tracker.h" | 8 #include "base/profiler/scoped_tracker.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 namespace content { | 34 namespace content { |
| 35 | 35 |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 const char kNoDocumentURLErrorMessage[] = | 38 const char kNoDocumentURLErrorMessage[] = |
| 39 "No URL is associated with the caller's document."; | 39 "No URL is associated with the caller's document."; |
| 40 const char kShutdownErrorMessage[] = | 40 const char kShutdownErrorMessage[] = |
| 41 "The Service Worker system has shutdown."; | 41 "The Service Worker system has shutdown."; |
| 42 const char kUserDeniedPermissionMessage[] = | 42 const char kUserDeniedPermissionMessage[] = |
| 43 "The user denied permission to use Service Worker."; | 43 "The user denied permission to use Service Worker."; |
| 44 const char kInvalidStateErrorMessage[] = "The object is in an invalid state."; | |
| 44 | 45 |
| 45 const uint32 kFilteredMessageClasses[] = { | 46 const uint32 kFilteredMessageClasses[] = { |
| 46 ServiceWorkerMsgStart, | 47 ServiceWorkerMsgStart, |
| 47 EmbeddedWorkerMsgStart, | 48 EmbeddedWorkerMsgStart, |
| 48 }; | 49 }; |
| 49 | 50 |
| 50 bool AllOriginsMatch(const GURL& url_a, const GURL& url_b, const GURL& url_c) { | 51 bool AllOriginsMatch(const GURL& url_a, const GURL& url_b, const GURL& url_c) { |
| 51 return url_a.GetOrigin() == url_b.GetOrigin() && | 52 return url_a.GetOrigin() == url_b.GetOrigin() && |
| 52 url_a.GetOrigin() == url_c.GetOrigin(); | 53 url_a.GetOrigin() == url_c.GetOrigin(); |
| 53 } | 54 } |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 pattern, | 358 pattern, |
| 358 script_url, | 359 script_url, |
| 359 provider_host, | 360 provider_host, |
| 360 base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete, | 361 base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete, |
| 361 this, | 362 this, |
| 362 thread_id, | 363 thread_id, |
| 363 provider_id, | 364 provider_id, |
| 364 request_id)); | 365 request_id)); |
| 365 } | 366 } |
| 366 | 367 |
| 367 void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(int provider_id, | 368 void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(int thread_id, |
| 369 int request_id, | |
| 370 int provider_id, | |
| 368 int64 registration_id) { | 371 int64 registration_id) { |
| 369 TRACE_EVENT0("ServiceWorker", | 372 TRACE_EVENT0("ServiceWorker", |
| 370 "ServiceWorkerDispatcherHost::OnUpdateServiceWorker"); | 373 "ServiceWorkerDispatcherHost::OnUpdateServiceWorker"); |
| 371 if (!GetContext()) | 374 if (!GetContext()) { |
| 375 Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( | |
| 376 thread_id, request_id, WebServiceWorkerError::ErrorTypeAbort, | |
| 377 base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + | |
| 378 base::ASCIIToUTF16(kShutdownErrorMessage))); | |
| 372 return; | 379 return; |
| 380 } | |
| 373 | 381 |
| 374 ServiceWorkerProviderHost* provider_host = | 382 ServiceWorkerProviderHost* provider_host = |
| 375 GetContext()->GetProviderHost(render_process_id_, provider_id); | 383 GetContext()->GetProviderHost(render_process_id_, provider_id); |
| 376 if (!provider_host) { | 384 if (!provider_host) { |
| 377 bad_message::ReceivedBadMessage(this, bad_message::SWDH_UPDATE_NO_HOST); | 385 bad_message::ReceivedBadMessage(this, bad_message::SWDH_UPDATE_NO_HOST); |
| 378 return; | 386 return; |
| 379 } | 387 } |
| 380 if (!provider_host->IsContextAlive()) | 388 if (!provider_host->IsContextAlive()) { |
| 389 Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( | |
| 390 thread_id, request_id, WebServiceWorkerError::ErrorTypeAbort, | |
| 391 base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + | |
| 392 base::ASCIIToUTF16(kShutdownErrorMessage))); | |
| 381 return; | 393 return; |
| 394 } | |
| 382 | 395 |
| 383 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed. | 396 // TODO(jungkees): This check can be removed once crbug.com/439697 is fixed. |
| 384 if (provider_host->document_url().is_empty()) | 397 if (provider_host->document_url().is_empty()) { |
| 398 Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( | |
| 399 thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity, | |
| 400 base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + | |
| 401 base::ASCIIToUTF16(kNoDocumentURLErrorMessage))); | |
| 385 return; | 402 return; |
| 403 } | |
| 386 | 404 |
| 387 ServiceWorkerRegistration* registration = | 405 ServiceWorkerRegistration* registration = |
| 388 GetContext()->GetLiveRegistration(registration_id); | 406 GetContext()->GetLiveRegistration(registration_id); |
| 389 if (!registration) { | 407 if (!registration) { |
| 390 // |registration| must be alive because a renderer retains a registration | 408 // |registration| must be alive because a renderer retains a registration |
| 391 // reference at this point. | 409 // reference at this point. |
| 392 bad_message::ReceivedBadMessage( | 410 bad_message::ReceivedBadMessage( |
| 393 this, bad_message::SWDH_UPDATE_BAD_REGISTRATION_ID); | 411 this, bad_message::SWDH_UPDATE_BAD_REGISTRATION_ID); |
| 394 return; | 412 return; |
| 395 } | 413 } |
| 396 | 414 |
| 397 if (!CanUpdateServiceWorker(provider_host->document_url(), | 415 if (!CanUpdateServiceWorker(provider_host->document_url(), |
| 398 registration->pattern())) { | 416 registration->pattern())) { |
| 399 bad_message::ReceivedBadMessage(this, bad_message::SWDH_UPDATE_CANNOT); | 417 bad_message::ReceivedBadMessage(this, bad_message::SWDH_UPDATE_CANNOT); |
| 400 return; | 418 return; |
| 401 } | 419 } |
| 402 | 420 |
| 403 if (!GetContentClient()->browser()->AllowServiceWorker( | 421 if (!GetContentClient()->browser()->AllowServiceWorker( |
| 404 registration->pattern(), provider_host->topmost_frame_url(), | 422 registration->pattern(), provider_host->topmost_frame_url(), |
| 405 resource_context_, render_process_id_, provider_host->frame_id())) { | 423 resource_context_, render_process_id_, provider_host->frame_id())) { |
| 424 Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( | |
| 425 thread_id, request_id, WebServiceWorkerError::ErrorTypeUnknown, | |
| 426 base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + | |
| 427 base::ASCIIToUTF16(kUserDeniedPermissionMessage))); | |
| 406 return; | 428 return; |
| 407 } | 429 } |
| 408 | 430 |
| 409 if (!registration->GetNewestVersion()) { | 431 if (!registration->GetNewestVersion()) { |
| 410 // This can happen if update() is called during initial script evaluation. | 432 // This can happen if update() is called during initial script evaluation. |
| 411 // Abort the following steps according to the spec. | 433 // Abort the following steps according to the spec. |
| 434 Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( | |
| 435 thread_id, request_id, WebServiceWorkerError::ErrorTypeState, | |
| 436 base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + | |
| 437 base::ASCIIToUTF16(kInvalidStateErrorMessage))); | |
|
nhiroki
2015/07/31 06:49:11
We might need to change the update() algorithm in
jungkees
2015/07/31 07:09:58
I noticed that and was gonna change this. ;-) I wi
| |
| 412 return; | 438 return; |
| 413 } | 439 } |
| 414 | 440 |
| 415 // The spec says, "update() pings the server for an updated version of this | 441 // The spec says, "update() pings the server for an updated version of this |
| 416 // script without consulting caches", so set |force_bypass_cache| to true. | 442 // script without consulting caches", so set |force_bypass_cache| to true. |
| 417 GetContext()->UpdateServiceWorker(registration, | 443 GetContext()->UpdateServiceWorker( |
| 418 true /* force_bypass_cache */); | 444 registration, true, /* force_bypass_cache */ |
| 445 provider_host, base::Bind(&ServiceWorkerDispatcherHost::UpdateComplete, | |
| 446 this, thread_id, provider_id, request_id)); | |
| 419 } | 447 } |
| 420 | 448 |
| 421 void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker( | 449 void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker( |
| 422 int thread_id, | 450 int thread_id, |
| 423 int request_id, | 451 int request_id, |
| 424 int provider_id, | 452 int provider_id, |
| 425 int64 registration_id) { | 453 int64 registration_id) { |
| 426 TRACE_EVENT0("ServiceWorker", | 454 TRACE_EVENT0("ServiceWorker", |
| 427 "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker"); | 455 "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker"); |
| 428 if (!GetContext()) { | 456 if (!GetContext()) { |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 | 865 |
| 838 Send(new ServiceWorkerMsg_ServiceWorkerRegistered( | 866 Send(new ServiceWorkerMsg_ServiceWorkerRegistered( |
| 839 thread_id, request_id, info, attrs)); | 867 thread_id, request_id, info, attrs)); |
| 840 TRACE_EVENT_ASYNC_END1("ServiceWorker", | 868 TRACE_EVENT_ASYNC_END1("ServiceWorker", |
| 841 "ServiceWorkerDispatcherHost::RegisterServiceWorker", | 869 "ServiceWorkerDispatcherHost::RegisterServiceWorker", |
| 842 request_id, | 870 request_id, |
| 843 "Registration ID", | 871 "Registration ID", |
| 844 registration_id); | 872 registration_id); |
| 845 } | 873 } |
| 846 | 874 |
| 875 void ServiceWorkerDispatcherHost::UpdateComplete( | |
| 876 int thread_id, | |
| 877 int provider_id, | |
| 878 int request_id, | |
| 879 ServiceWorkerStatusCode status, | |
| 880 const std::string& status_message, | |
| 881 int64 registration_id) { | |
| 882 if (!GetContext()) | |
| 883 return; | |
| 884 | |
| 885 ServiceWorkerProviderHost* provider_host = | |
| 886 GetContext()->GetProviderHost(render_process_id_, provider_id); | |
| 887 if (!provider_host) | |
| 888 return; // The provider has already been destroyed. | |
| 889 | |
| 890 if (status != SERVICE_WORKER_OK) { | |
| 891 SendRegistrationError(thread_id, request_id, status, status_message); | |
| 892 return; | |
| 893 } | |
| 894 | |
| 895 ServiceWorkerRegistration* registration = | |
| 896 GetContext()->GetLiveRegistration(registration_id); | |
| 897 DCHECK(registration); | |
| 898 | |
| 899 ServiceWorkerRegistrationObjectInfo info; | |
| 900 ServiceWorkerVersionAttributes attrs; | |
| 901 GetRegistrationObjectInfoAndVersionAttributes(provider_host->AsWeakPtr(), | |
| 902 registration, &info, &attrs); | |
| 903 | |
| 904 Send(new ServiceWorkerMsg_ServiceWorkerUpdated(thread_id, request_id)); | |
| 905 TRACE_EVENT_ASYNC_END1("ServiceWorker", | |
| 906 "ServiceWorkerDispatcherHost::UpdateServiceWorker", | |
| 907 request_id, "Registration ID", registration_id); | |
| 908 } | |
| 909 | |
| 847 void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection( | 910 void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection( |
| 848 int embedded_worker_id) { | 911 int embedded_worker_id) { |
| 849 TRACE_EVENT0("ServiceWorker", | 912 TRACE_EVENT0("ServiceWorker", |
| 850 "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection"); | 913 "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection"); |
| 851 if (!GetContext()) | 914 if (!GetContext()) |
| 852 return; | 915 return; |
| 853 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry(); | 916 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry(); |
| 854 if (!registry->CanHandle(embedded_worker_id)) | 917 if (!registry->CanHandle(embedded_worker_id)) |
| 855 return; | 918 return; |
| 856 registry->OnWorkerReadyForInspection(render_process_id_, embedded_worker_id); | 919 registry->OnWorkerReadyForInspection(render_process_id_, embedded_worker_id); |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1212 if (!handle) { | 1275 if (!handle) { |
| 1213 bad_message::ReceivedBadMessage(this, | 1276 bad_message::ReceivedBadMessage(this, |
| 1214 bad_message::SWDH_TERMINATE_BAD_HANDLE); | 1277 bad_message::SWDH_TERMINATE_BAD_HANDLE); |
| 1215 return; | 1278 return; |
| 1216 } | 1279 } |
| 1217 handle->version()->StopWorker( | 1280 handle->version()->StopWorker( |
| 1218 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 1281 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
| 1219 } | 1282 } |
| 1220 | 1283 |
| 1221 } // namespace content | 1284 } // namespace content |
| OLD | NEW |