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 <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/debug/crash_logging.h" | 9 #include "base/debug/crash_logging.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 #include "content/browser/service_worker/service_worker_registration_handle.h" | 28 #include "content/browser/service_worker/service_worker_registration_handle.h" |
| 29 #include "content/common/service_worker/embedded_worker_messages.h" | 29 #include "content/common/service_worker/embedded_worker_messages.h" |
| 30 #include "content/common/service_worker/service_worker_messages.h" | 30 #include "content/common/service_worker/service_worker_messages.h" |
| 31 #include "content/common/service_worker/service_worker_types.h" | 31 #include "content/common/service_worker/service_worker_types.h" |
| 32 #include "content/common/service_worker/service_worker_utils.h" | 32 #include "content/common/service_worker/service_worker_utils.h" |
| 33 #include "content/public/browser/content_browser_client.h" | 33 #include "content/public/browser/content_browser_client.h" |
| 34 #include "content/public/common/browser_side_navigation_policy.h" | 34 #include "content/public/common/browser_side_navigation_policy.h" |
| 35 #include "content/public/common/content_client.h" | 35 #include "content/public/common/content_client.h" |
| 36 #include "content/public/common/origin_util.h" | 36 #include "content/public/common/origin_util.h" |
| 37 #include "ipc/ipc_message_macros.h" | 37 #include "ipc/ipc_message_macros.h" |
| 38 #include "net/http/http_util.h" | |
| 38 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWor kerError.h" | 39 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWor kerError.h" |
| 39 #include "url/gurl.h" | 40 #include "url/gurl.h" |
| 40 | 41 |
| 41 using blink::WebServiceWorkerError; | 42 using blink::WebServiceWorkerError; |
| 42 | 43 |
| 43 namespace content { | 44 namespace content { |
| 44 | 45 |
| 45 namespace { | 46 namespace { |
| 46 | 47 |
| 47 const char kNoDocumentURLErrorMessage[] = | 48 const char kNoDocumentURLErrorMessage[] = |
| 48 "No URL is associated with the caller's document."; | 49 "No URL is associated with the caller's document."; |
| 49 const char kShutdownErrorMessage[] = | 50 const char kShutdownErrorMessage[] = |
| 50 "The Service Worker system has shutdown."; | 51 "The Service Worker system has shutdown."; |
| 51 const char kUserDeniedPermissionMessage[] = | 52 const char kUserDeniedPermissionMessage[] = |
| 52 "The user denied permission to use Service Worker."; | 53 "The user denied permission to use Service Worker."; |
| 53 const char kInvalidStateErrorMessage[] = "The object is in an invalid state."; | 54 const char kInvalidStateErrorMessage[] = "The object is in an invalid state."; |
| 54 const char kEnableNavigationPreloadErrorPrefix[] = | 55 const char kEnableNavigationPreloadErrorPrefix[] = |
| 55 "Failed to enable or disable navigation preload: "; | 56 "Failed to enable or disable navigation preload: "; |
| 56 const char kGetNavigationPreloadStateErrorPrefix[] = | 57 const char kGetNavigationPreloadStateErrorPrefix[] = |
| 57 "Failed to get navigation preload state: "; | 58 "Failed to get navigation preload state: "; |
| 59 const char kSetNavigationPreloadHeaderErrorPrefix[] = | |
| 60 "Failed to set navigation preload header: "; | |
| 58 | 61 |
| 59 const uint32_t kFilteredMessageClasses[] = { | 62 const uint32_t kFilteredMessageClasses[] = { |
| 60 ServiceWorkerMsgStart, EmbeddedWorkerMsgStart, | 63 ServiceWorkerMsgStart, EmbeddedWorkerMsgStart, |
| 61 }; | 64 }; |
| 62 | 65 |
| 63 void RunSoon(const base::Closure& callback) { | 66 void RunSoon(const base::Closure& callback) { |
| 64 if (!callback.is_null()) | 67 if (!callback.is_null()) |
| 65 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); | 68 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); |
| 66 } | 69 } |
| 67 | 70 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 OnDecrementServiceWorkerRefCount) | 188 OnDecrementServiceWorkerRefCount) |
| 186 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount, | 189 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount, |
| 187 OnIncrementRegistrationRefCount) | 190 OnIncrementRegistrationRefCount) |
| 188 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount, | 191 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount, |
| 189 OnDecrementRegistrationRefCount) | 192 OnDecrementRegistrationRefCount) |
| 190 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_TerminateWorker, OnTerminateWorker) | 193 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_TerminateWorker, OnTerminateWorker) |
| 191 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_EnableNavigationPreload, | 194 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_EnableNavigationPreload, |
| 192 OnEnableNavigationPreload) | 195 OnEnableNavigationPreload) |
| 193 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetNavigationPreloadState, | 196 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetNavigationPreloadState, |
| 194 OnGetNavigationPreloadState) | 197 OnGetNavigationPreloadState) |
| 198 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetNavigationPreloadHeader, | |
| 199 OnSetNavigationPreloadHeader) | |
| 195 IPC_MESSAGE_UNHANDLED(handled = false) | 200 IPC_MESSAGE_UNHANDLED(handled = false) |
| 196 IPC_END_MESSAGE_MAP() | 201 IPC_END_MESSAGE_MAP() |
| 197 | 202 |
| 198 if (!handled && GetContext()) { | 203 if (!handled && GetContext()) { |
| 199 handled = GetContext()->embedded_worker_registry()->OnMessageReceived( | 204 handled = GetContext()->embedded_worker_registry()->OnMessageReceived( |
| 200 message, render_process_id_); | 205 message, render_process_id_); |
| 201 if (!handled) | 206 if (!handled) |
| 202 bad_message::ReceivedBadMessage(this, bad_message::SWDH_NOT_HANDLED); | 207 bad_message::ReceivedBadMessage(this, bad_message::SWDH_NOT_HANDLED); |
| 203 } | 208 } |
| 204 | 209 |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 781 registration->pattern(), provider_host->topmost_frame_url(), | 786 registration->pattern(), provider_host->topmost_frame_url(), |
| 782 resource_context_, render_process_id_, provider_host->frame_id())) { | 787 resource_context_, render_process_id_, provider_host->frame_id())) { |
| 783 Send(new ServiceWorkerMsg_GetNavigationPreloadStateError( | 788 Send(new ServiceWorkerMsg_GetNavigationPreloadStateError( |
| 784 thread_id, request_id, WebServiceWorkerError::ErrorTypeDisabled, | 789 thread_id, request_id, WebServiceWorkerError::ErrorTypeDisabled, |
| 785 std::string(kGetNavigationPreloadStateErrorPrefix) + | 790 std::string(kGetNavigationPreloadStateErrorPrefix) + |
| 786 std::string(kUserDeniedPermissionMessage))); | 791 std::string(kUserDeniedPermissionMessage))); |
| 787 return; | 792 return; |
| 788 } | 793 } |
| 789 | 794 |
| 790 Send(new ServiceWorkerMsg_DidGetNavigationPreloadState( | 795 Send(new ServiceWorkerMsg_DidGetNavigationPreloadState( |
| 791 thread_id, request_id, registration->is_navigation_preload_enabled())); | 796 thread_id, request_id, |
| 797 NavigationPreloadState(registration->is_navigation_preload_enabled(), | |
| 798 registration->navigation_preload_header()))); | |
| 799 } | |
| 800 | |
| 801 void ServiceWorkerDispatcherHost::OnSetNavigationPreloadHeader( | |
| 802 int thread_id, | |
| 803 int request_id, | |
| 804 int provider_id, | |
| 805 int64_t registration_id, | |
| 806 const std::string& value) { | |
| 807 ProviderStatus provider_status; | |
| 808 ServiceWorkerProviderHost* provider_host = | |
| 809 GetProviderHostForRequest(&provider_status, provider_id); | |
| 810 switch (provider_status) { | |
| 811 case ProviderStatus::NO_CONTEXT: // fallthrough | |
| 812 case ProviderStatus::DEAD_HOST: | |
| 813 Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError( | |
| 814 thread_id, request_id, WebServiceWorkerError::ErrorTypeAbort, | |
| 815 std::string(kSetNavigationPreloadHeaderErrorPrefix) + | |
| 816 std::string(kShutdownErrorMessage))); | |
| 817 return; | |
| 818 case ProviderStatus::NO_HOST: | |
| 819 bad_message::ReceivedBadMessage( | |
| 820 this, bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_NO_HOST); | |
| 821 return; | |
| 822 case ProviderStatus::NO_URL: | |
| 823 Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError( | |
| 824 thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity, | |
| 825 std::string(kSetNavigationPreloadHeaderErrorPrefix) + | |
| 826 std::string(kNoDocumentURLErrorMessage))); | |
| 827 return; | |
| 828 case ProviderStatus::OK: | |
| 829 break; | |
| 830 } | |
| 831 | |
| 832 ServiceWorkerRegistration* registration = | |
| 833 GetContext()->GetLiveRegistration(registration_id); | |
| 834 if (!registration) { | |
| 835 // |registration| must be alive because a renderer retains a registration | |
| 836 // reference at this point. | |
| 837 bad_message::ReceivedBadMessage( | |
| 838 this, | |
| 839 bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_REGISTRATION_ID); | |
|
ncarter (slow)
2016/10/31 18:35:36
FYI: from some recent experience with bad_message:
falken
2016/11/01 00:35:28
Thanks, that's good to know.
| |
| 840 return; | |
| 841 } | |
| 842 | |
| 843 std::vector<GURL> urls = {provider_host->document_url(), | |
| 844 registration->pattern()}; | |
| 845 if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) { | |
| 846 bad_message::ReceivedBadMessage( | |
| 847 this, bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_INVALID_ORIGIN); | |
| 848 return; | |
| 849 } | |
| 850 | |
| 851 // TODO(falken): Ideally this would match Blink's isValidHTTPHeaderValue. | |
| 852 // Chrome's check is less restrictive: it allows non-latin1 characters. | |
| 853 if (!net::HttpUtil::IsValidHeaderValue(value)) { | |
| 854 bad_message::ReceivedBadMessage( | |
| 855 this, bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_VALUE); | |
| 856 return; | |
| 857 } | |
| 858 | |
| 859 if (!GetContentClient()->browser()->AllowServiceWorker( | |
| 860 registration->pattern(), provider_host->topmost_frame_url(), | |
| 861 resource_context_, render_process_id_, provider_host->frame_id())) { | |
| 862 Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError( | |
| 863 thread_id, request_id, WebServiceWorkerError::ErrorTypeDisabled, | |
| 864 std::string(kSetNavigationPreloadHeaderErrorPrefix) + | |
| 865 std::string(kUserDeniedPermissionMessage))); | |
| 866 return; | |
| 867 } | |
| 868 | |
| 869 // TODO(falken): Write to disk before resolving the promise. | |
| 870 registration->SetNavigationPreloadHeader(value); | |
| 871 Send(new ServiceWorkerMsg_DidSetNavigationPreloadHeader(thread_id, | |
| 872 request_id)); | |
| 792 } | 873 } |
| 793 | 874 |
| 794 void ServiceWorkerDispatcherHost::OnPostMessageToWorker( | 875 void ServiceWorkerDispatcherHost::OnPostMessageToWorker( |
| 795 int handle_id, | 876 int handle_id, |
| 796 int provider_id, | 877 int provider_id, |
| 797 const base::string16& message, | 878 const base::string16& message, |
| 798 const url::Origin& source_origin, | 879 const url::Origin& source_origin, |
| 799 const std::vector<int>& sent_message_ports) { | 880 const std::vector<int>& sent_message_ports) { |
| 800 TRACE_EVENT0("ServiceWorker", | 881 TRACE_EVENT0("ServiceWorker", |
| 801 "ServiceWorkerDispatcherHost::OnPostMessageToWorker"); | 882 "ServiceWorkerDispatcherHost::OnPostMessageToWorker"); |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1577 if (!handle) { | 1658 if (!handle) { |
| 1578 bad_message::ReceivedBadMessage(this, | 1659 bad_message::ReceivedBadMessage(this, |
| 1579 bad_message::SWDH_TERMINATE_BAD_HANDLE); | 1660 bad_message::SWDH_TERMINATE_BAD_HANDLE); |
| 1580 return; | 1661 return; |
| 1581 } | 1662 } |
| 1582 handle->version()->StopWorker( | 1663 handle->version()->StopWorker( |
| 1583 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 1664 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
| 1584 } | 1665 } |
| 1585 | 1666 |
| 1586 } // namespace content | 1667 } // namespace content |
| OLD | NEW |