Chromium Code Reviews| 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_controllee_request_handl er.h" | 5 #include "content/browser/service_worker/service_worker_controllee_request_handl er.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
| 12 #include "content/browser/service_worker/service_worker_context_core.h" | 12 #include "content/browser/service_worker/service_worker_context_core.h" |
| 13 #include "content/browser/service_worker/service_worker_metrics.h" | 13 #include "content/browser/service_worker/service_worker_metrics.h" |
| 14 #include "content/browser/service_worker/service_worker_provider_host.h" | 14 #include "content/browser/service_worker/service_worker_provider_host.h" |
| 15 #include "content/browser/service_worker/service_worker_registration.h" | 15 #include "content/browser/service_worker/service_worker_registration.h" |
| 16 #include "content/browser/service_worker/service_worker_response_info.h" | 16 #include "content/browser/service_worker/service_worker_response_info.h" |
| 17 #include "content/browser/service_worker/service_worker_url_job_wrapper.h" | |
| 17 #include "content/browser/service_worker/service_worker_url_request_job.h" | 18 #include "content/browser/service_worker/service_worker_url_request_job.h" |
| 18 #include "content/common/resource_request_body_impl.h" | 19 #include "content/common/resource_request_body_impl.h" |
| 19 #include "content/common/service_worker/service_worker_types.h" | 20 #include "content/common/service_worker/service_worker_types.h" |
| 20 #include "content/common/service_worker/service_worker_utils.h" | 21 #include "content/common/service_worker/service_worker_utils.h" |
| 21 #include "content/public/browser/content_browser_client.h" | 22 #include "content/public/browser/content_browser_client.h" |
| 22 #include "content/public/browser/render_frame_host.h" | 23 #include "content/public/browser/render_frame_host.h" |
| 23 #include "content/public/browser/resource_request_info.h" | 24 #include "content/public/browser/resource_request_info.h" |
| 24 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
| 25 #include "content/public/common/browser_side_navigation_policy.h" | 26 #include "content/public/common/browser_side_navigation_policy.h" |
| 26 #include "content/public/common/content_client.h" | 27 #include "content/public/common/content_client.h" |
| 27 #include "content/public/common/resource_response_info.h" | 28 #include "content/public/common/resource_response_info.h" |
| 28 #include "net/base/load_flags.h" | 29 #include "net/base/load_flags.h" |
| 29 #include "net/base/url_util.h" | 30 #include "net/base/url_util.h" |
| 30 #include "net/url_request/url_request.h" | 31 #include "net/url_request/url_request.h" |
| 31 #include "ui/base/page_transition_types.h" | 32 #include "ui/base/page_transition_types.h" |
| 32 | 33 |
| 33 namespace content { | 34 namespace content { |
| 34 | 35 |
| 35 namespace { | 36 namespace { |
| 36 | 37 |
| 37 bool MaybeForwardToServiceWorker(ServiceWorkerURLRequestJob* job, | 38 bool MaybeForwardToServiceWorker(ServiceWorkerURLJobWrapper* job, |
| 38 const ServiceWorkerVersion* version) { | 39 const ServiceWorkerVersion* version) { |
| 39 DCHECK(job); | 40 DCHECK(job); |
| 40 DCHECK(version); | 41 DCHECK(version); |
| 41 DCHECK_NE(version->fetch_handler_existence(), | 42 DCHECK_NE(version->fetch_handler_existence(), |
| 42 ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN); | 43 ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN); |
| 43 if (version->fetch_handler_existence() == | 44 if (version->fetch_handler_existence() == |
| 44 ServiceWorkerVersion::FetchHandlerExistence::EXISTS) { | 45 ServiceWorkerVersion::FetchHandlerExistence::EXISTS) { |
| 45 job->ForwardToServiceWorker(); | 46 job->ForwardToServiceWorker(); |
| 46 return true; | 47 return true; |
| 47 } | 48 } |
| 48 | 49 |
| 49 job->FallbackToNetworkOrRenderer(); | 50 job->FallbackToNetworkOrRenderer(); |
| 50 return false; | 51 return false; |
| 51 } | 52 } |
| 52 | 53 |
| 53 ui::PageTransition GetPageTransition(net::URLRequest* request) { | |
| 54 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); | |
| 55 // ResourceRequestInfo may not be set in some tests. | |
| 56 if (!info) | |
| 57 return ui::PAGE_TRANSITION_LINK; | |
| 58 return info->GetPageTransition(); | |
| 59 } | |
| 60 | |
| 61 } // namespace | 54 } // namespace |
| 62 | 55 |
| 63 ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler( | 56 ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler( |
| 64 base::WeakPtr<ServiceWorkerContextCore> context, | 57 base::WeakPtr<ServiceWorkerContextCore> context, |
| 65 base::WeakPtr<ServiceWorkerProviderHost> provider_host, | 58 base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
| 66 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, | 59 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, |
| 67 FetchRequestMode request_mode, | 60 FetchRequestMode request_mode, |
| 68 FetchCredentialsMode credentials_mode, | 61 FetchCredentialsMode credentials_mode, |
| 69 FetchRedirectMode redirect_mode, | 62 FetchRedirectMode redirect_mode, |
| 70 ResourceType resource_type, | 63 ResourceType resource_type, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 } | 126 } |
| 134 | 127 |
| 135 // It's for original request (A) or redirect case (B-a or B-b). | 128 // It's for original request (A) or redirect case (B-a or B-b). |
| 136 std::unique_ptr<ServiceWorkerURLRequestJob> job( | 129 std::unique_ptr<ServiceWorkerURLRequestJob> job( |
| 137 new ServiceWorkerURLRequestJob( | 130 new ServiceWorkerURLRequestJob( |
| 138 request, network_delegate, provider_host_->client_uuid(), | 131 request, network_delegate, provider_host_->client_uuid(), |
| 139 blob_storage_context_, resource_context, request_mode_, | 132 blob_storage_context_, resource_context, request_mode_, |
| 140 credentials_mode_, redirect_mode_, resource_type_, | 133 credentials_mode_, redirect_mode_, resource_type_, |
| 141 request_context_type_, frame_type_, body_, | 134 request_context_type_, frame_type_, body_, |
| 142 ServiceWorkerFetchType::FETCH, base::nullopt, this)); | 135 ServiceWorkerFetchType::FETCH, base::nullopt, this)); |
| 143 job_ = job->GetWeakPtr(); | 136 url_job_ = base::MakeUnique<ServiceWorkerURLJobWrapper>(job->GetWeakPtr()); |
| 144 | 137 |
| 145 resource_context_ = resource_context; | 138 resource_context_ = resource_context; |
| 146 | 139 |
| 147 if (is_main_resource_load_) | 140 if (is_main_resource_load_) |
| 148 PrepareForMainResource(request); | 141 PrepareForMainResource(request->url(), request->first_party_for_cookies()); |
| 149 else | 142 else |
| 150 PrepareForSubResource(); | 143 PrepareForSubResource(); |
| 151 | 144 |
| 152 if (job_->ShouldFallbackToNetwork()) { | 145 if (url_job_->ShouldFallbackToNetwork()) { |
| 153 // If we know we can fallback to network at this point (in case | 146 // If we know we can fallback to network at this point (in case |
| 154 // the storage lookup returned immediately), just destroy the job and return | 147 // the storage lookup returned immediately), just destroy the job and return |
| 155 // NULL here to fallback to network. | 148 // NULL here to fallback to network. |
| 156 | 149 |
| 157 // If this is a subresource request, all subsequent requests should also use | 150 // If this is a subresource request, all subsequent requests should also use |
| 158 // the network. | 151 // the network. |
| 159 if (!is_main_resource_load_) | 152 if (!is_main_resource_load_) |
| 160 use_network_ = true; | 153 use_network_ = true; |
| 161 | 154 |
| 162 job.reset(); | 155 job.reset(); |
| 163 ClearJob(); | 156 ClearJob(); |
| 164 } | 157 } |
| 165 | 158 |
| 166 return job.release(); | 159 return job.release(); |
| 167 } | 160 } |
| 168 | 161 |
| 169 void ServiceWorkerControlleeRequestHandler::PrepareForMainResource( | 162 void ServiceWorkerControlleeRequestHandler::PrepareForMainResource( |
| 170 const net::URLRequest* request) { | 163 const GURL& url, |
| 171 DCHECK(job_.get()); | 164 const GURL& first_party_for_cookies) { |
| 165 DCHECK(url_job_.get()); | |
| 172 DCHECK(context_); | 166 DCHECK(context_); |
| 173 DCHECK(provider_host_); | 167 DCHECK(provider_host_); |
| 174 TRACE_EVENT_ASYNC_BEGIN1( | 168 TRACE_EVENT_ASYNC_BEGIN1( |
| 175 "ServiceWorker", | 169 "ServiceWorker", |
| 176 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", | 170 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", |
| 177 job_.get(), | 171 url_job_.get(), "URL", url.spec()); |
| 178 "URL", request->url().spec()); | |
| 179 // The corresponding provider_host may already have associated a registration | 172 // The corresponding provider_host may already have associated a registration |
| 180 // in redirect case, unassociate it now. | 173 // in redirect case, unassociate it now. |
| 181 provider_host_->DisassociateRegistration(); | 174 provider_host_->DisassociateRegistration(); |
| 182 | 175 |
| 183 // Also prevent a registrater job for establishing an association to a new | 176 // Also prevent a registrater job for establishing an association to a new |
| 184 // registration while we're finding an existing registration. | 177 // registration while we're finding an existing registration. |
| 185 provider_host_->SetAllowAssociation(false); | 178 provider_host_->SetAllowAssociation(false); |
| 186 | 179 |
| 187 stripped_url_ = net::SimplifyUrlForRequest(request->url()); | 180 stripped_url_ = net::SimplifyUrlForRequest(url); |
| 188 provider_host_->SetDocumentUrl(stripped_url_); | 181 provider_host_->SetDocumentUrl(stripped_url_); |
| 189 provider_host_->SetTopmostFrameUrl(request->first_party_for_cookies()); | 182 provider_host_->SetTopmostFrameUrl(first_party_for_cookies); |
| 190 context_->storage()->FindRegistrationForDocument( | 183 context_->storage()->FindRegistrationForDocument( |
| 191 stripped_url_, base::Bind(&self::DidLookupRegistrationForMainResource, | 184 stripped_url_, base::Bind(&self::DidLookupRegistrationForMainResource, |
| 192 weak_factory_.GetWeakPtr())); | 185 weak_factory_.GetWeakPtr())); |
| 193 } | 186 } |
| 194 | 187 |
| 195 void ServiceWorkerControlleeRequestHandler:: | 188 void ServiceWorkerControlleeRequestHandler:: |
| 196 DidLookupRegistrationForMainResource( | 189 DidLookupRegistrationForMainResource( |
| 197 ServiceWorkerStatusCode status, | 190 ServiceWorkerStatusCode status, |
| 198 scoped_refptr<ServiceWorkerRegistration> registration) { | 191 scoped_refptr<ServiceWorkerRegistration> registration) { |
| 199 // The job may have been canceled and then destroyed before this was invoked. | 192 // The job may have been canceled before this was invoked. |
| 200 if (!job_) | 193 if (JobWasCanceled()) |
| 201 return; | 194 return; |
| 202 | 195 |
| 203 const bool need_to_update = !force_update_started_ && registration && | 196 const bool need_to_update = !force_update_started_ && registration && |
| 204 context_->force_update_on_page_load(); | 197 context_->force_update_on_page_load(); |
| 205 | 198 |
| 206 if (provider_host_ && !need_to_update) | 199 if (provider_host_ && !need_to_update) |
| 207 provider_host_->SetAllowAssociation(true); | 200 provider_host_->SetAllowAssociation(true); |
| 208 if (status != SERVICE_WORKER_OK || !provider_host_ || !context_) { | 201 if (status != SERVICE_WORKER_OK || !provider_host_ || !context_) { |
| 209 job_->FallbackToNetwork(); | 202 url_job_->FallbackToNetwork(); |
| 210 TRACE_EVENT_ASYNC_END1( | 203 TRACE_EVENT_ASYNC_END1( |
| 211 "ServiceWorker", | 204 "ServiceWorker", |
| 212 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", | 205 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", |
| 213 job_.get(), | 206 url_job_.get(), "Status", status); |
| 214 "Status", status); | |
| 215 return; | 207 return; |
| 216 } | 208 } |
| 217 DCHECK(registration.get()); | 209 DCHECK(registration.get()); |
| 218 | 210 |
| 219 base::Callback<WebContents*(void)> web_contents_getter; | 211 base::Callback<WebContents*(void)> web_contents_getter; |
| 220 if (IsBrowserSideNavigationEnabled()) { | 212 if (IsBrowserSideNavigationEnabled()) { |
| 221 web_contents_getter = provider_host_->web_contents_getter(); | 213 web_contents_getter = provider_host_->web_contents_getter(); |
| 222 } else if (provider_host_->process_id() != -1 && | 214 } else if (provider_host_->process_id() != -1 && |
| 223 provider_host_->frame_id() != -1) { | 215 provider_host_->frame_id() != -1) { |
| 224 web_contents_getter = base::Bind( | 216 web_contents_getter = base::Bind( |
| 225 [](int render_process_id, int render_frame_id) { | 217 [](int render_process_id, int render_frame_id) { |
| 226 RenderFrameHost* rfh = | 218 RenderFrameHost* rfh = |
| 227 RenderFrameHost::FromID(render_process_id, render_frame_id); | 219 RenderFrameHost::FromID(render_process_id, render_frame_id); |
| 228 return WebContents::FromRenderFrameHost(rfh); | 220 return WebContents::FromRenderFrameHost(rfh); |
| 229 }, | 221 }, |
| 230 provider_host_->process_id(), provider_host_->frame_id()); | 222 provider_host_->process_id(), provider_host_->frame_id()); |
| 231 } | 223 } |
| 232 if (!GetContentClient()->browser()->AllowServiceWorker( | 224 if (!GetContentClient()->browser()->AllowServiceWorker( |
| 233 registration->pattern(), provider_host_->topmost_frame_url(), | 225 registration->pattern(), provider_host_->topmost_frame_url(), |
| 234 resource_context_, web_contents_getter)) { | 226 resource_context_, web_contents_getter)) { |
| 235 job_->FallbackToNetwork(); | 227 url_job_->FallbackToNetwork(); |
| 236 TRACE_EVENT_ASYNC_END2( | 228 TRACE_EVENT_ASYNC_END2( |
| 237 "ServiceWorker", | 229 "ServiceWorker", |
| 238 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", | 230 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", |
| 239 job_.get(), | 231 url_job_.get(), "Status", status, "Info", "ServiceWorker is blocked"); |
| 240 "Status", status, | |
| 241 "Info", "ServiceWorker is blocked"); | |
| 242 return; | 232 return; |
| 243 } | 233 } |
| 244 | 234 |
| 245 if (!provider_host_->IsContextSecureForServiceWorker()) { | 235 if (!provider_host_->IsContextSecureForServiceWorker()) { |
| 246 // TODO(falken): Figure out a way to surface in the page's DevTools | 236 // TODO(falken): Figure out a way to surface in the page's DevTools |
| 247 // console that the service worker was blocked for security. | 237 // console that the service worker was blocked for security. |
| 248 job_->FallbackToNetwork(); | 238 url_job_->FallbackToNetwork(); |
| 249 TRACE_EVENT_ASYNC_END1( | 239 TRACE_EVENT_ASYNC_END1( |
| 250 "ServiceWorker", | 240 "ServiceWorker", |
| 251 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", | 241 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", |
| 252 job_.get(), "Info", "Insecure context"); | 242 url_job_.get(), "Info", "Insecure context"); |
| 253 return; | 243 return; |
| 254 } | 244 } |
| 255 | 245 |
| 256 if (need_to_update) { | 246 if (need_to_update) { |
| 257 force_update_started_ = true; | 247 force_update_started_ = true; |
| 258 context_->UpdateServiceWorker( | 248 context_->UpdateServiceWorker( |
| 259 registration.get(), true /* force_bypass_cache */, | 249 registration.get(), true /* force_bypass_cache */, |
| 260 true /* skip_script_comparison */, provider_host_.get(), | 250 true /* skip_script_comparison */, provider_host_.get(), |
| 261 base::Bind(&self::DidUpdateRegistration, weak_factory_.GetWeakPtr(), | 251 base::Bind(&self::DidUpdateRegistration, weak_factory_.GetWeakPtr(), |
| 262 registration)); | 252 registration)); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 276 // Wait until it's activated before firing fetch events. | 266 // Wait until it's activated before firing fetch events. |
| 277 if (active_version.get() && | 267 if (active_version.get() && |
| 278 active_version->status() == ServiceWorkerVersion::ACTIVATING) { | 268 active_version->status() == ServiceWorkerVersion::ACTIVATING) { |
| 279 provider_host_->SetAllowAssociation(false); | 269 provider_host_->SetAllowAssociation(false); |
| 280 registration->active_version()->RegisterStatusChangeCallback(base::Bind( | 270 registration->active_version()->RegisterStatusChangeCallback(base::Bind( |
| 281 &self::OnVersionStatusChanged, weak_factory_.GetWeakPtr(), | 271 &self::OnVersionStatusChanged, weak_factory_.GetWeakPtr(), |
| 282 base::RetainedRef(registration), base::RetainedRef(active_version))); | 272 base::RetainedRef(registration), base::RetainedRef(active_version))); |
| 283 TRACE_EVENT_ASYNC_END2( | 273 TRACE_EVENT_ASYNC_END2( |
| 284 "ServiceWorker", | 274 "ServiceWorker", |
| 285 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", | 275 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", |
| 286 job_.get(), | 276 url_job_.get(), "Status", status, "Info", |
| 287 "Status", status, | 277 "Wait until finished SW activation"); |
| 288 "Info", "Wait until finished SW activation"); | |
| 289 return; | 278 return; |
| 290 } | 279 } |
| 291 | 280 |
| 292 // A registration exists, so associate it. Note that the controller is only | 281 // A registration exists, so associate it. Note that the controller is only |
| 293 // set if there's an active version. If there's no active version, we should | 282 // set if there's an active version. If there's no active version, we should |
| 294 // still associate so the provider host can use .ready. | 283 // still associate so the provider host can use .ready. |
| 295 provider_host_->AssociateRegistration(registration.get(), | 284 provider_host_->AssociateRegistration(registration.get(), |
| 296 false /* notify_controllerchange */); | 285 false /* notify_controllerchange */); |
| 297 | 286 |
| 298 if (!active_version.get() || | 287 if (!active_version.get() || |
| 299 active_version->status() != ServiceWorkerVersion::ACTIVATED) { | 288 active_version->status() != ServiceWorkerVersion::ACTIVATED) { |
| 300 job_->FallbackToNetwork(); | 289 url_job_->FallbackToNetwork(); |
| 301 TRACE_EVENT_ASYNC_END2( | 290 TRACE_EVENT_ASYNC_END2( |
| 302 "ServiceWorker", | 291 "ServiceWorker", |
| 303 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", | 292 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", |
| 304 job_.get(), | 293 url_job_.get(), "Status", status, "Info", |
| 305 "Status", status, | |
| 306 "Info", | |
| 307 "ServiceWorkerVersion is not available, so falling back to network"); | 294 "ServiceWorkerVersion is not available, so falling back to network"); |
| 308 return; | 295 return; |
| 309 } | 296 } |
| 310 | 297 |
| 311 DCHECK_NE(active_version->fetch_handler_existence(), | 298 DCHECK_NE(active_version->fetch_handler_existence(), |
| 312 ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN); | 299 ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN); |
| 313 ServiceWorkerMetrics::CountControlledPageLoad( | 300 ServiceWorkerMetrics::CountControlledPageLoad( |
| 314 active_version->site_for_uma(), stripped_url_, is_main_frame_load_, | 301 active_version->site_for_uma(), stripped_url_, is_main_frame_load_, |
| 315 GetPageTransition(job_->request()), job_->request()->url_chain().size()); | 302 url_job_->GetPageTransition(), url_job_->GetURLChainSize()); |
| 316 | 303 |
| 317 bool is_forwarded = | 304 bool is_forwarded = |
| 318 MaybeForwardToServiceWorker(job_.get(), active_version.get()); | 305 MaybeForwardToServiceWorker(url_job_.get(), active_version.get()); |
| 319 | 306 |
| 320 TRACE_EVENT_ASYNC_END2( | 307 TRACE_EVENT_ASYNC_END2( |
| 321 "ServiceWorker", | 308 "ServiceWorker", |
| 322 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", | 309 "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", |
| 323 job_.get(), "Status", status, "Info", | 310 url_job_.get(), "Status", status, "Info", |
| 324 (is_forwarded) ? "Forwarded to the ServiceWorker" | 311 (is_forwarded) ? "Forwarded to the ServiceWorker" |
| 325 : "Skipped the ServiceWorker which has no fetch handler"); | 312 : "Skipped the ServiceWorker which has no fetch handler"); |
| 326 } | 313 } |
| 327 | 314 |
| 328 void ServiceWorkerControlleeRequestHandler::OnVersionStatusChanged( | 315 void ServiceWorkerControlleeRequestHandler::OnVersionStatusChanged( |
| 329 ServiceWorkerRegistration* registration, | 316 ServiceWorkerRegistration* registration, |
| 330 ServiceWorkerVersion* version) { | 317 ServiceWorkerVersion* version) { |
| 331 // The job may have been canceled and then destroyed before this was invoked. | 318 // The job may have been canceled before this was invoked. |
| 332 if (!job_) | 319 if (JobWasCanceled()) |
| 333 return; | 320 return; |
| 334 | 321 |
| 335 if (provider_host_) | 322 if (provider_host_) |
| 336 provider_host_->SetAllowAssociation(true); | 323 provider_host_->SetAllowAssociation(true); |
| 337 if (version != registration->active_version() || | 324 if (version != registration->active_version() || |
| 338 version->status() != ServiceWorkerVersion::ACTIVATED || | 325 version->status() != ServiceWorkerVersion::ACTIVATED || |
| 339 !provider_host_) { | 326 !provider_host_) { |
| 340 job_->FallbackToNetwork(); | 327 url_job_->FallbackToNetwork(); |
| 341 return; | 328 return; |
| 342 } | 329 } |
| 343 | 330 |
| 344 DCHECK_NE(version->fetch_handler_existence(), | 331 DCHECK_NE(version->fetch_handler_existence(), |
| 345 ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN); | 332 ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN); |
| 346 ServiceWorkerMetrics::CountControlledPageLoad( | 333 ServiceWorkerMetrics::CountControlledPageLoad( |
| 347 version->site_for_uma(), stripped_url_, is_main_frame_load_, | 334 version->site_for_uma(), stripped_url_, is_main_frame_load_, |
| 348 GetPageTransition(job_->request()), job_->request()->url_chain().size()); | 335 url_job_->GetPageTransition(), url_job_->GetURLChainSize()); |
| 349 | 336 |
| 350 provider_host_->AssociateRegistration(registration, | 337 provider_host_->AssociateRegistration(registration, |
| 351 false /* notify_controllerchange */); | 338 false /* notify_controllerchange */); |
| 352 | 339 |
| 353 MaybeForwardToServiceWorker(job_.get(), version); | 340 MaybeForwardToServiceWorker(url_job_.get(), version); |
| 354 } | 341 } |
| 355 | 342 |
| 356 void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration( | 343 void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration( |
| 357 const scoped_refptr<ServiceWorkerRegistration>& original_registration, | 344 const scoped_refptr<ServiceWorkerRegistration>& original_registration, |
| 358 ServiceWorkerStatusCode status, | 345 ServiceWorkerStatusCode status, |
| 359 const std::string& status_message, | 346 const std::string& status_message, |
| 360 int64_t registration_id) { | 347 int64_t registration_id) { |
| 361 DCHECK(force_update_started_); | 348 DCHECK(force_update_started_); |
| 362 | 349 |
| 363 // The job may have been canceled and then destroyed before this was invoked. | 350 // The job may have been canceled before this was invoked. |
| 364 if (!job_) | 351 if (JobWasCanceled()) |
| 365 return; | 352 return; |
| 366 | 353 |
| 367 if (!context_) { | 354 if (!context_) { |
| 368 job_->FallbackToNetwork(); | 355 url_job_->FallbackToNetwork(); |
| 369 return; | 356 return; |
| 370 } | 357 } |
| 371 if (status != SERVICE_WORKER_OK || | 358 if (status != SERVICE_WORKER_OK || |
| 372 !original_registration->installing_version()) { | 359 !original_registration->installing_version()) { |
| 373 // Update failed. Look up the registration again since the original | 360 // Update failed. Look up the registration again since the original |
| 374 // registration was possibly unregistered in the meantime. | 361 // registration was possibly unregistered in the meantime. |
| 375 context_->storage()->FindRegistrationForDocument( | 362 context_->storage()->FindRegistrationForDocument( |
| 376 stripped_url_, base::Bind(&self::DidLookupRegistrationForMainResource, | 363 stripped_url_, base::Bind(&self::DidLookupRegistrationForMainResource, |
| 377 weak_factory_.GetWeakPtr())); | 364 weak_factory_.GetWeakPtr())); |
| 378 return; | 365 return; |
| 379 } | 366 } |
| 380 DCHECK_EQ(original_registration->id(), registration_id); | 367 DCHECK_EQ(original_registration->id(), registration_id); |
| 381 scoped_refptr<ServiceWorkerVersion> new_version = | 368 scoped_refptr<ServiceWorkerVersion> new_version = |
| 382 original_registration->installing_version(); | 369 original_registration->installing_version(); |
| 383 new_version->ReportForceUpdateToDevTools(); | 370 new_version->ReportForceUpdateToDevTools(); |
| 384 new_version->set_skip_waiting(true); | 371 new_version->set_skip_waiting(true); |
| 385 new_version->RegisterStatusChangeCallback(base::Bind( | 372 new_version->RegisterStatusChangeCallback(base::Bind( |
| 386 &self::OnUpdatedVersionStatusChanged, weak_factory_.GetWeakPtr(), | 373 &self::OnUpdatedVersionStatusChanged, weak_factory_.GetWeakPtr(), |
| 387 original_registration, new_version)); | 374 original_registration, new_version)); |
| 388 } | 375 } |
| 389 | 376 |
| 390 void ServiceWorkerControlleeRequestHandler::OnUpdatedVersionStatusChanged( | 377 void ServiceWorkerControlleeRequestHandler::OnUpdatedVersionStatusChanged( |
| 391 const scoped_refptr<ServiceWorkerRegistration>& registration, | 378 const scoped_refptr<ServiceWorkerRegistration>& registration, |
| 392 const scoped_refptr<ServiceWorkerVersion>& version) { | 379 const scoped_refptr<ServiceWorkerVersion>& version) { |
| 393 // The job may have been canceled and then destroyed before this was invoked. | 380 // The job may have been canceled before this was invoked. |
| 394 if (!job_) | 381 if (JobWasCanceled()) |
| 395 return; | 382 return; |
| 396 | 383 |
| 397 if (!context_) { | 384 if (!context_) { |
| 398 job_->FallbackToNetwork(); | 385 url_job_->FallbackToNetwork(); |
| 399 return; | 386 return; |
| 400 } | 387 } |
| 401 if (version->status() == ServiceWorkerVersion::ACTIVATED || | 388 if (version->status() == ServiceWorkerVersion::ACTIVATED || |
| 402 version->status() == ServiceWorkerVersion::REDUNDANT) { | 389 version->status() == ServiceWorkerVersion::REDUNDANT) { |
| 403 // When the status is REDUNDANT, the update failed (eg: script error), we | 390 // When the status is REDUNDANT, the update failed (eg: script error), we |
| 404 // continue with the incumbent version. | 391 // continue with the incumbent version. |
| 405 // In case unregister job may have run, look up the registration again. | 392 // In case unregister job may have run, look up the registration again. |
| 406 context_->storage()->FindRegistrationForDocument( | 393 context_->storage()->FindRegistrationForDocument( |
| 407 stripped_url_, base::Bind(&self::DidLookupRegistrationForMainResource, | 394 stripped_url_, base::Bind(&self::DidLookupRegistrationForMainResource, |
| 408 weak_factory_.GetWeakPtr())); | 395 weak_factory_.GetWeakPtr())); |
| 409 return; | 396 return; |
| 410 } | 397 } |
| 411 version->RegisterStatusChangeCallback( | 398 version->RegisterStatusChangeCallback( |
| 412 base::Bind(&self::OnUpdatedVersionStatusChanged, | 399 base::Bind(&self::OnUpdatedVersionStatusChanged, |
| 413 weak_factory_.GetWeakPtr(), registration, version)); | 400 weak_factory_.GetWeakPtr(), registration, version)); |
| 414 } | 401 } |
| 415 | 402 |
| 416 void ServiceWorkerControlleeRequestHandler::PrepareForSubResource() { | 403 void ServiceWorkerControlleeRequestHandler::PrepareForSubResource() { |
| 417 DCHECK(job_.get()); | 404 DCHECK(url_job_.get()); |
|
kinuko
2017/05/18 01:59:29
This needs to be DCHECK(!JobWasCanceled()) I think
scottmg
2017/05/18 03:25:59
Thank you! Done.
| |
| 418 DCHECK(context_); | 405 DCHECK(context_); |
| 419 | 406 |
| 420 // When this request handler was created, the provider host had a controller | 407 // When this request handler was created, the provider host had a controller |
| 421 // and hence an active version, but by the time MaybeCreateJob() is called | 408 // and hence an active version, but by the time MaybeCreateJob() is called |
| 422 // the active version may have been lost. This happens when | 409 // the active version may have been lost. This happens when |
| 423 // ServiceWorkerRegistration::DeleteVersion() was called to delete the worker | 410 // ServiceWorkerRegistration::DeleteVersion() was called to delete the worker |
| 424 // because a permanent failure occurred when trying to start it. | 411 // because a permanent failure occurred when trying to start it. |
| 425 // | 412 // |
| 426 // As this is an exceptional case, just error out. | 413 // As this is an exceptional case, just error out. |
| 427 // TODO(falken): Figure out if |active_version| can change to | 414 // TODO(falken): Figure out if |active_version| can change to |
| 428 // |controlling_version| and do it or document the findings. | 415 // |controlling_version| and do it or document the findings. |
| 429 if (!provider_host_->active_version()) { | 416 if (!provider_host_->active_version()) { |
| 430 job_->FailDueToLostController(); | 417 url_job_->FailDueToLostController(); |
| 431 return; | 418 return; |
| 432 } | 419 } |
| 433 | 420 |
| 434 MaybeForwardToServiceWorker(job_.get(), provider_host_->active_version()); | 421 MaybeForwardToServiceWorker(url_job_.get(), provider_host_->active_version()); |
| 435 } | 422 } |
| 436 | 423 |
| 437 void ServiceWorkerControlleeRequestHandler::OnPrepareToRestart() { | 424 void ServiceWorkerControlleeRequestHandler::OnPrepareToRestart() { |
| 438 use_network_ = true; | 425 use_network_ = true; |
| 439 ClearJob(); | 426 ClearJob(); |
| 440 } | 427 } |
| 441 | 428 |
| 442 ServiceWorkerVersion* | 429 ServiceWorkerVersion* |
| 443 ServiceWorkerControlleeRequestHandler::GetServiceWorkerVersion( | 430 ServiceWorkerControlleeRequestHandler::GetServiceWorkerVersion( |
| 444 ServiceWorkerMetrics::URLRequestJobResult* result) { | 431 ServiceWorkerMetrics::URLRequestJobResult* result) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 464 return true; | 451 return true; |
| 465 } | 452 } |
| 466 | 453 |
| 467 void ServiceWorkerControlleeRequestHandler::MainResourceLoadFailed() { | 454 void ServiceWorkerControlleeRequestHandler::MainResourceLoadFailed() { |
| 468 DCHECK(provider_host_); | 455 DCHECK(provider_host_); |
| 469 // Detach the controller so subresource requests also skip the worker. | 456 // Detach the controller so subresource requests also skip the worker. |
| 470 provider_host_->NotifyControllerLost(); | 457 provider_host_->NotifyControllerLost(); |
| 471 } | 458 } |
| 472 | 459 |
| 473 void ServiceWorkerControlleeRequestHandler::ClearJob() { | 460 void ServiceWorkerControlleeRequestHandler::ClearJob() { |
| 474 job_.reset(); | 461 url_job_.reset(); |
| 462 } | |
| 463 | |
| 464 bool ServiceWorkerControlleeRequestHandler::JobWasCanceled() const { | |
| 465 return !url_job_ || url_job_->WasCanceled(); | |
| 475 } | 466 } |
| 476 | 467 |
| 477 } // namespace content | 468 } // namespace content |
| OLD | NEW |