| 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_provider_host.h" | 5 #include "content/browser/service_worker/service_worker_provider_host.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/feature_list.h" | 9 #include "base/feature_list.h" |
| 10 #include "base/guid.h" | 10 #include "base/guid.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "content/browser/service_worker/embedded_worker_status.h" | 14 #include "content/browser/service_worker/embedded_worker_status.h" |
| 15 #include "content/browser/service_worker/service_worker_context_core.h" | 15 #include "content/browser/service_worker/service_worker_context_core.h" |
| 16 #include "content/browser/service_worker/service_worker_context_request_handler.
h" | 16 #include "content/browser/service_worker/service_worker_context_request_handler.
h" |
| 17 #include "content/browser/service_worker/service_worker_controllee_request_handl
er.h" | 17 #include "content/browser/service_worker/service_worker_controllee_request_handl
er.h" |
| 18 #include "content/browser/service_worker/service_worker_dispatcher_host.h" | 18 #include "content/browser/service_worker/service_worker_dispatcher_host.h" |
| 19 #include "content/browser/service_worker/service_worker_handle.h" | 19 #include "content/browser/service_worker/service_worker_handle.h" |
| 20 #include "content/browser/service_worker/service_worker_registration_handle.h" | 20 #include "content/browser/service_worker/service_worker_registration_handle.h" |
| 21 #include "content/browser/service_worker/service_worker_version.h" | 21 #include "content/browser/service_worker/service_worker_version.h" |
| 22 #include "content/browser/url_loader_factory_getter.h" |
| 22 #include "content/common/resource_request_body_impl.h" | 23 #include "content/common/resource_request_body_impl.h" |
| 23 #include "content/common/service_worker/service_worker_messages.h" | 24 #include "content/common/service_worker/service_worker_messages.h" |
| 24 #include "content/common/service_worker/service_worker_types.h" | 25 #include "content/common/service_worker/service_worker_types.h" |
| 25 #include "content/common/service_worker/service_worker_utils.h" | 26 #include "content/common/service_worker/service_worker_utils.h" |
| 26 #include "content/public/browser/content_browser_client.h" | 27 #include "content/public/browser/content_browser_client.h" |
| 27 #include "content/public/common/browser_side_navigation_policy.h" | 28 #include "content/public/common/browser_side_navigation_policy.h" |
| 28 #include "content/public/common/child_process_host.h" | 29 #include "content/public/common/child_process_host.h" |
| 29 #include "content/public/common/content_client.h" | 30 #include "content/public/common/content_client.h" |
| 30 #include "content/public/common/content_features.h" | 31 #include "content/public/common/content_features.h" |
| 31 #include "content/public/common/origin_util.h" | 32 #include "content/public/common/origin_util.h" |
| 32 #include "mojo/public/cpp/bindings/strong_associated_binding.h" | 33 #include "mojo/public/cpp/bindings/strong_associated_binding.h" |
| 33 #include "net/base/url_util.h" | 34 #include "net/base/url_util.h" |
| 35 #include "storage/browser/blob/blob_storage_context.h" |
| 34 | 36 |
| 35 namespace content { | 37 namespace content { |
| 36 | 38 |
| 37 namespace { | 39 namespace { |
| 38 | 40 |
| 39 // Provider host for navigation with PlzNavigate or service worker's context is | 41 // Provider host for navigation with PlzNavigate or service worker's context is |
| 40 // created on the browser side. This function provides the next | 42 // created on the browser side. This function provides the next |
| 41 // ServiceWorkerProviderHost ID for them, starts at -2 and keeps going down. | 43 // ServiceWorkerProviderHost ID for them, starts at -2 and keeps going down. |
| 42 int NextBrowserProvidedProviderId() { | 44 int NextBrowserProvidedProviderId() { |
| 43 static int g_next_browser_provided_provider_id = -2; | 45 static int g_next_browser_provided_provider_id = -2; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 // process, to have been destroyed before being claimed by the renderer. The | 93 // process, to have been destroyed before being claimed by the renderer. The |
| 92 // provider is then destroyed in the renderer, and no matching host will be | 94 // provider is then destroyed in the renderer, and no matching host will be |
| 93 // found. | 95 // found. |
| 94 DCHECK(IsBrowserSideNavigationEnabled() && | 96 DCHECK(IsBrowserSideNavigationEnabled() && |
| 95 ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id)); | 97 ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id)); |
| 96 return; | 98 return; |
| 97 } | 99 } |
| 98 context->RemoveProviderHost(process_id, provider_id); | 100 context->RemoveProviderHost(process_id, provider_id); |
| 99 } | 101 } |
| 100 | 102 |
| 103 // Used by a Service Worker for script loading (for all script loading for now, |
| 104 // but to be used only during installation once script streaming lands). |
| 105 // For now this is just a proxy loader for the network loader. |
| 106 // TODO(kinuko): Implement this. Hook up the existing code in |
| 107 // ServiceWorkerContextRequestHandler. |
| 108 class ScriptURLLoader : public mojom::URLLoader, public mojom::URLLoaderClient { |
| 109 public: |
| 110 ScriptURLLoader( |
| 111 int32_t routing_id, |
| 112 int32_t request_id, |
| 113 uint32_t options, |
| 114 const ResourceRequest& resource_request, |
| 115 mojom::URLLoaderClientPtr client, |
| 116 base::WeakPtr<ServiceWorkerContextCore> context, |
| 117 base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
| 118 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, |
| 119 scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter, |
| 120 const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) |
| 121 : network_client_binding_(this), |
| 122 forwarding_client_(std::move(client)), |
| 123 provider_host_(provider_host) { |
| 124 mojom::URLLoaderClientPtr network_client; |
| 125 network_client_binding_.Bind(mojo::MakeRequest(&network_client)); |
| 126 loader_factory_getter->GetNetworkFactory()->get()->CreateLoaderAndStart( |
| 127 mojo::MakeRequest(&network_loader_), routing_id, request_id, options, |
| 128 resource_request, std::move(network_client), traffic_annotation); |
| 129 } |
| 130 ~ScriptURLLoader() override {} |
| 131 |
| 132 // mojom::URLLoader: |
| 133 void FollowRedirect() override { network_loader_->FollowRedirect(); } |
| 134 void SetPriority(net::RequestPriority priority, |
| 135 int32_t intra_priority_value) override { |
| 136 network_loader_->SetPriority(priority, intra_priority_value); |
| 137 } |
| 138 |
| 139 // mojom::URLLoaderClient for simply proxying network: |
| 140 void OnReceiveResponse( |
| 141 const ResourceResponseHead& response_head, |
| 142 const base::Optional<net::SSLInfo>& ssl_info, |
| 143 mojom::DownloadedTempFilePtr downloaded_file) override { |
| 144 if (provider_host_) { |
| 145 // We don't have complete info here, but fill in what we have now. |
| 146 // At least we need headers and SSL info. |
| 147 net::HttpResponseInfo response_info; |
| 148 response_info.headers = response_head.headers; |
| 149 if (ssl_info.has_value()) |
| 150 response_info.ssl_info = *ssl_info; |
| 151 response_info.was_fetched_via_spdy = response_head.was_fetched_via_spdy; |
| 152 response_info.was_alpn_negotiated = response_head.was_alpn_negotiated; |
| 153 response_info.alpn_negotiated_protocol = |
| 154 response_head.alpn_negotiated_protocol; |
| 155 response_info.connection_info = response_head.connection_info; |
| 156 response_info.socket_address = response_head.socket_address; |
| 157 |
| 158 DCHECK(provider_host_->IsHostToRunningServiceWorker()); |
| 159 provider_host_->running_hosted_version()->SetMainScriptHttpResponseInfo( |
| 160 response_info); |
| 161 } |
| 162 forwarding_client_->OnReceiveResponse(response_head, ssl_info, |
| 163 std::move(downloaded_file)); |
| 164 } |
| 165 void OnReceiveRedirect(const net::RedirectInfo& redirect_info, |
| 166 const ResourceResponseHead& response_head) override { |
| 167 forwarding_client_->OnReceiveRedirect(redirect_info, response_head); |
| 168 } |
| 169 void OnDataDownloaded(int64_t data_len, int64_t encoded_data_len) override { |
| 170 forwarding_client_->OnDataDownloaded(data_len, encoded_data_len); |
| 171 } |
| 172 void OnUploadProgress(int64_t current_position, |
| 173 int64_t total_size, |
| 174 OnUploadProgressCallback ack_callback) override { |
| 175 forwarding_client_->OnUploadProgress(current_position, total_size, |
| 176 std::move(ack_callback)); |
| 177 } |
| 178 void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override { |
| 179 forwarding_client_->OnReceiveCachedMetadata(data); |
| 180 } |
| 181 void OnTransferSizeUpdated(int32_t transfer_size_diff) override { |
| 182 forwarding_client_->OnTransferSizeUpdated(transfer_size_diff); |
| 183 } |
| 184 void OnStartLoadingResponseBody( |
| 185 mojo::ScopedDataPipeConsumerHandle body) override { |
| 186 forwarding_client_->OnStartLoadingResponseBody(std::move(body)); |
| 187 } |
| 188 void OnComplete(const ResourceRequestCompletionStatus& status) override { |
| 189 forwarding_client_->OnComplete(status); |
| 190 } |
| 191 |
| 192 private: |
| 193 mojom::URLLoaderAssociatedPtr network_loader_; |
| 194 mojo::Binding<mojom::URLLoaderClient> network_client_binding_; |
| 195 mojom::URLLoaderClientPtr forwarding_client_; |
| 196 base::WeakPtr<ServiceWorkerProviderHost> provider_host_; |
| 197 |
| 198 DISALLOW_COPY_AND_ASSIGN(ScriptURLLoader); |
| 199 }; |
| 200 |
| 201 // Created per one controller worker for script loading (only during |
| 202 // installation, eventually). This is kept alive while |
| 203 // ServiceWorkerNetworkProvider in the renderer process is alive. |
| 204 // Used only when IsServicificationEnabled is true. |
| 205 class ScriptURLLoaderFactory : public mojom::URLLoaderFactory { |
| 206 public: |
| 207 ScriptURLLoaderFactory( |
| 208 base::WeakPtr<ServiceWorkerContextCore> context, |
| 209 base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
| 210 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, |
| 211 scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter) |
| 212 : context_(context), |
| 213 provider_host_(provider_host), |
| 214 blob_storage_context_(blob_storage_context), |
| 215 loader_factory_getter_(loader_factory_getter) {} |
| 216 ~ScriptURLLoaderFactory() override {} |
| 217 |
| 218 // mojom::URLLoaderFactory: |
| 219 void CreateLoaderAndStart(mojom::URLLoaderAssociatedRequest request, |
| 220 int32_t routing_id, |
| 221 int32_t request_id, |
| 222 uint32_t options, |
| 223 const ResourceRequest& resource_request, |
| 224 mojom::URLLoaderClientPtr client, |
| 225 const net::MutableNetworkTrafficAnnotationTag& |
| 226 traffic_annotation) override { |
| 227 mojo::MakeStrongAssociatedBinding( |
| 228 base::MakeUnique<ScriptURLLoader>( |
| 229 routing_id, request_id, options, resource_request, |
| 230 std::move(client), context_, provider_host_, blob_storage_context_, |
| 231 loader_factory_getter_, traffic_annotation), |
| 232 std::move(request)); |
| 233 } |
| 234 |
| 235 void SyncLoad(int32_t routing_id, |
| 236 int32_t request_id, |
| 237 const ResourceRequest& request, |
| 238 SyncLoadCallback callback) override { |
| 239 NOTREACHED(); |
| 240 } |
| 241 |
| 242 private: |
| 243 base::WeakPtr<ServiceWorkerContextCore> context_; |
| 244 base::WeakPtr<ServiceWorkerProviderHost> provider_host_; |
| 245 base::WeakPtr<storage::BlobStorageContext> blob_storage_context_; |
| 246 scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter_; |
| 247 DISALLOW_COPY_AND_ASSIGN(ScriptURLLoaderFactory); |
| 248 }; |
| 249 |
| 101 } // anonymous namespace | 250 } // anonymous namespace |
| 102 | 251 |
| 103 ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback( | 252 ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback( |
| 104 const GetRegistrationForReadyCallback& callback) | 253 const GetRegistrationForReadyCallback& callback) |
| 105 : callback(callback), | 254 : callback(callback), |
| 106 called(false) { | 255 called(false) { |
| 107 } | 256 } |
| 108 | 257 |
| 109 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() { | 258 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() { |
| 110 } | 259 } |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 if (get_ready_callback_) | 731 if (get_ready_callback_) |
| 583 return false; | 732 return false; |
| 584 get_ready_callback_.reset(new OneShotGetReadyCallback(callback)); | 733 get_ready_callback_.reset(new OneShotGetReadyCallback(callback)); |
| 585 ReturnRegistrationForReadyIfNeeded(); | 734 ReturnRegistrationForReadyIfNeeded(); |
| 586 return true; | 735 return true; |
| 587 } | 736 } |
| 588 | 737 |
| 589 std::unique_ptr<ServiceWorkerProviderHost> | 738 std::unique_ptr<ServiceWorkerProviderHost> |
| 590 ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { | 739 ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { |
| 591 DCHECK(!IsBrowserSideNavigationEnabled()); | 740 DCHECK(!IsBrowserSideNavigationEnabled()); |
| 741 DCHECK(!ServiceWorkerUtils::IsServicificationEnabled()); |
| 592 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); | 742 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
| 593 DCHECK_NE(MSG_ROUTING_NONE, info_.route_id); | 743 DCHECK_NE(MSG_ROUTING_NONE, info_.route_id); |
| 594 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); | 744 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); |
| 595 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type); | 745 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type); |
| 596 | 746 |
| 597 std::unique_ptr<ServiceWorkerProviderHost> provisional_host = | 747 std::unique_ptr<ServiceWorkerProviderHost> provisional_host = |
| 598 base::WrapUnique(new ServiceWorkerProviderHost( | 748 base::WrapUnique(new ServiceWorkerProviderHost( |
| 599 process_id(), | 749 process_id(), |
| 600 ServiceWorkerProviderHostInfo(std::move(info_), binding_.Unbind(), | 750 ServiceWorkerProviderHostInfo(std::move(info_), binding_.Unbind(), |
| 601 provider_.PassInterface()), | 751 provider_.PassInterface()), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 615 | 765 |
| 616 render_process_id_ = ChildProcessHost::kInvalidUniqueID; | 766 render_process_id_ = ChildProcessHost::kInvalidUniqueID; |
| 617 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; | 767 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
| 618 dispatcher_host_ = nullptr; | 768 dispatcher_host_ = nullptr; |
| 619 return provisional_host; | 769 return provisional_host; |
| 620 } | 770 } |
| 621 | 771 |
| 622 void ServiceWorkerProviderHost::CompleteCrossSiteTransfer( | 772 void ServiceWorkerProviderHost::CompleteCrossSiteTransfer( |
| 623 ServiceWorkerProviderHost* provisional_host) { | 773 ServiceWorkerProviderHost* provisional_host) { |
| 624 DCHECK(!IsBrowserSideNavigationEnabled()); | 774 DCHECK(!IsBrowserSideNavigationEnabled()); |
| 775 DCHECK(!ServiceWorkerUtils::IsServicificationEnabled()); |
| 625 DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_); | 776 DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
| 626 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, provisional_host->process_id()); | 777 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, provisional_host->process_id()); |
| 627 DCHECK_NE(MSG_ROUTING_NONE, provisional_host->frame_id()); | 778 DCHECK_NE(MSG_ROUTING_NONE, provisional_host->frame_id()); |
| 628 | 779 |
| 629 render_process_id_ = provisional_host->process_id(); | 780 render_process_id_ = provisional_host->process_id(); |
| 630 render_thread_id_ = kDocumentMainThreadId; | 781 render_thread_id_ = kDocumentMainThreadId; |
| 631 dispatcher_host_ = provisional_host->dispatcher_host(); | 782 dispatcher_host_ = provisional_host->dispatcher_host(); |
| 632 info_ = std::move(provisional_host->info_); | 783 info_ = std::move(provisional_host->info_); |
| 633 | 784 |
| 634 // Take the connection over from the provisional host. | 785 // Take the connection over from the provisional host. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 AsWeakPtr(), registration, &info, &attrs); | 862 AsWeakPtr(), registration, &info, &attrs); |
| 712 | 863 |
| 713 // Initialize provider_client_info. | 864 // Initialize provider_client_info. |
| 714 (*out_provider_client_info)->provider_id = provider_id(); | 865 (*out_provider_client_info)->provider_id = provider_id(); |
| 715 (*out_provider_client_info)->type = provider_type(); | 866 (*out_provider_client_info)->type = provider_type(); |
| 716 (*out_provider_client_info)->attributes = std::move(attrs); | 867 (*out_provider_client_info)->attributes = std::move(attrs); |
| 717 (*out_provider_client_info)->registration = std::move(info); | 868 (*out_provider_client_info)->registration = std::move(info); |
| 718 (*out_provider_client_info)->is_parent_frame_secure = | 869 (*out_provider_client_info)->is_parent_frame_secure = |
| 719 is_parent_frame_secure(); | 870 is_parent_frame_secure(); |
| 720 (*out_provider_client_info)->client_request = mojo::MakeRequest(&provider_); | 871 (*out_provider_client_info)->client_request = mojo::MakeRequest(&provider_); |
| 872 |
| 873 mojom::URLLoaderFactoryAssociatedPtrInfo loader_factory_ptr_info; |
| 874 if (ServiceWorkerUtils::IsServicificationEnabled()) { |
| 875 mojo::MakeStrongAssociatedBinding( |
| 876 base::MakeUnique<ScriptURLLoaderFactory>( |
| 877 context_, AsWeakPtr(), context_->blob_storage_context(), |
| 878 context_->loader_factory_getter()), |
| 879 mojo::MakeRequest(&loader_factory_ptr_info)); |
| 880 (*out_provider_client_info)->script_loader_factory_ptr_info = |
| 881 std::move(loader_factory_ptr_info); |
| 882 } |
| 883 |
| 721 auto* host_ptr_info_ptr = &(*out_provider_client_info)->host_ptr_info; | 884 auto* host_ptr_info_ptr = &(*out_provider_client_info)->host_ptr_info; |
| 722 binding_.Bind(mojo::MakeRequest(host_ptr_info_ptr)); | 885 binding_.Bind(mojo::MakeRequest(host_ptr_info_ptr)); |
| 723 binding_.set_connection_error_handler( | 886 binding_.set_connection_error_handler( |
| 724 base::Bind(&RemoveProviderHost, context_, process_id, provider_id())); | 887 base::Bind(&RemoveProviderHost, context_, process_id, provider_id())); |
| 725 | 888 |
| 726 // Set the document URL to the script url in order to allow | 889 // Set the document URL to the script url in order to allow |
| 727 // register/unregister/getRegistration on ServiceWorkerGlobalScope. | 890 // register/unregister/getRegistration on ServiceWorkerGlobalScope. |
| 728 SetDocumentUrl(running_hosted_version()->script_url()); | 891 SetDocumentUrl(running_hosted_version()->script_url()); |
| 729 } | 892 } |
| 730 | 893 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 render_thread_id_, provider_id(), | 1063 render_thread_id_, provider_id(), |
| 901 GetOrCreateServiceWorkerHandle( | 1064 GetOrCreateServiceWorkerHandle( |
| 902 associated_registration_->active_version()), | 1065 associated_registration_->active_version()), |
| 903 false /* shouldNotifyControllerChange */, | 1066 false /* shouldNotifyControllerChange */, |
| 904 associated_registration_->active_version()->used_features())); | 1067 associated_registration_->active_version()->used_features())); |
| 905 } | 1068 } |
| 906 } | 1069 } |
| 907 } | 1070 } |
| 908 | 1071 |
| 909 } // namespace content | 1072 } // namespace content |
| OLD | NEW |