summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
diff options
context:
space:
mode:
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.cc121
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