diff options
Diffstat (limited to 'chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc')
-rw-r--r-- | chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc new file mode 100644 index 00000000000..14a707b62e8 --- /dev/null +++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc @@ -0,0 +1,121 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/service_worker/service_worker_controllee_request_handler.h" + +#include "content/browser/service_worker/service_worker_context_core.h" +#include "content/browser/service_worker/service_worker_provider_host.h" +#include "content/browser/service_worker/service_worker_registration.h" +#include "content/browser/service_worker/service_worker_url_request_job.h" +#include "content/browser/service_worker/service_worker_utils.h" +#include "content/common/service_worker/service_worker_types.h" +#include "net/base/net_util.h" +#include "net/url_request/url_request.h" + +namespace content { + +ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler( + base::WeakPtr<ServiceWorkerContextCore> context, + base::WeakPtr<ServiceWorkerProviderHost> provider_host, + base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context, + ResourceType::Type resource_type) + : ServiceWorkerRequestHandler(context, + provider_host, + blob_storage_context, + resource_type), + weak_factory_(this) { +} + +ServiceWorkerControlleeRequestHandler:: + ~ServiceWorkerControlleeRequestHandler() { +} + +net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob( + net::URLRequest* request, + net::NetworkDelegate* network_delegate) { + if (!context_ || !provider_host_) { + // We can't do anything other than to fall back to network. + job_ = NULL; + return NULL; + } + + // This may get called multiple times for original and redirect requests: + // A. original request case: job_ is null, no previous location info. + // B. redirect or restarted request case: + // a) job_ is non-null if the previous location was forwarded to SW. + // b) job_ is null if the previous location was fallback. + // c) job_ is non-null if additional restart was required to fall back. + + // We've come here by restart, we already have original request and it + // tells we should fallback to network. (Case B-c) + if (job_.get() && job_->ShouldFallbackToNetwork()) { + job_ = NULL; + return NULL; + } + + // It's for original request (A) or redirect case (B-a or B-b). + DCHECK(!job_.get() || job_->ShouldForwardToServiceWorker()); + + job_ = new ServiceWorkerURLRequestJob( + request, network_delegate, provider_host_, blob_storage_context_); + if (ServiceWorkerUtils::IsMainResourceType(resource_type_)) + PrepareForMainResource(request->url()); + else + PrepareForSubResource(); + + if (job_->ShouldFallbackToNetwork()) { + // If we know we can fallback to network at this point (in case + // the storage lookup returned immediately), just return NULL here to + // fallback to network. + job_ = NULL; + return NULL; + } + + return job_.get(); +} + +void ServiceWorkerControlleeRequestHandler::PrepareForMainResource( + const GURL& url) { + DCHECK(job_.get()); + DCHECK(context_); + // The corresponding provider_host may already have associate version in + // redirect case, unassociate it now. + provider_host_->SetActiveVersion(NULL); + provider_host_->SetWaitingVersion(NULL); + + GURL stripped_url = net::SimplifyUrlForRequest(url); + provider_host_->SetDocumentUrl(stripped_url); + context_->storage()->FindRegistrationForDocument( + stripped_url, + base::Bind(&self::DidLookupRegistrationForMainResource, + weak_factory_.GetWeakPtr())); +} + +void +ServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource( + ServiceWorkerStatusCode status, + const scoped_refptr<ServiceWorkerRegistration>& registration) { + DCHECK(job_.get()); + if (status != SERVICE_WORKER_OK || !registration->active_version()) { + // No registration, or no active version for the registration is available. + job_->FallbackToNetwork(); + return; + } + // TODO(michaeln): should SetWaitingVersion() even if no active version so + // so the versions in the pipeline (.installing, .waiting) show up in the + // attribute values. + DCHECK(registration); + provider_host_->SetActiveVersion(registration->active_version()); + provider_host_->SetWaitingVersion(registration->waiting_version()); + job_->ForwardToServiceWorker(); +} + +void ServiceWorkerControlleeRequestHandler::PrepareForSubResource() { + DCHECK(job_.get()); + DCHECK(context_); + DCHECK(provider_host_->active_version()); + job_->ForwardToServiceWorker(); +} + +} // namespace content |