| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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 | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 #include "content/browser/service_worker/service_worker_storage.h" | 
|  | 6 | 
|  | 7 #include <string> | 
|  | 8 | 
|  | 9 #include "base/strings/string_util.h" | 
|  | 10 #include "content/browser/service_worker/service_worker_register_job.h" | 
|  | 11 #include "content/browser/service_worker/service_worker_registration.h" | 
|  | 12 #include "content/public/browser/browser_thread.h" | 
|  | 13 #include "webkit/browser/quota/quota_manager.h" | 
|  | 14 | 
|  | 15 namespace { | 
|  | 16 // This is temporary until we figure out how registration ids will be | 
|  | 17 // calculated. | 
|  | 18 int64 NextRegistrationId() { | 
|  | 19   static int64 worker_id = 0; | 
|  | 20   return worker_id++; | 
|  | 21 } | 
|  | 22 }  // namespace | 
|  | 23 | 
|  | 24 namespace content { | 
|  | 25 | 
|  | 26 const base::FilePath::CharType kServiceWorkerDirectory[] = | 
|  | 27     FILE_PATH_LITERAL("ServiceWorker"); | 
|  | 28 | 
|  | 29 ServiceWorkerStorage::ServiceWorkerStorage( | 
|  | 30     const base::FilePath& path, | 
|  | 31     quota::QuotaManagerProxy* quota_manager_proxy) | 
|  | 32     : quota_manager_proxy_(quota_manager_proxy), weak_factory_(this) { | 
|  | 33   if (!path.empty()) | 
|  | 34     path_ = path.Append(kServiceWorkerDirectory); | 
|  | 35 } | 
|  | 36 | 
|  | 37 ServiceWorkerStorage::~ServiceWorkerStorage() { | 
|  | 38   for (PatternToRegistrationMap::const_iterator iter = | 
|  | 39            registration_by_pattern_.begin(); | 
|  | 40        iter != registration_by_pattern_.end(); | 
|  | 41        ++iter) { | 
|  | 42     iter->second->Shutdown(); | 
|  | 43   } | 
|  | 44   registration_by_pattern_.clear(); | 
|  | 45 } | 
|  | 46 | 
|  | 47 void ServiceWorkerStorage::FindRegistrationForPattern( | 
|  | 48     const GURL& pattern, | 
|  | 49     const RegistrationCallback& callback) { | 
|  | 50   PatternToRegistrationMap::const_iterator match = | 
|  | 51       registration_by_pattern_.find(pattern); | 
|  | 52   if (match == registration_by_pattern_.end()) { | 
|  | 53     BrowserThread::PostTask( | 
|  | 54         BrowserThread::IO, | 
|  | 55         FROM_HERE, | 
|  | 56         base::Bind(callback, | 
|  | 57                    REGISTRATION_NOT_FOUND, | 
|  | 58                    scoped_refptr<ServiceWorkerRegistration>())); | 
|  | 59     return; | 
|  | 60   } | 
|  | 61   BrowserThread::PostTask(BrowserThread::IO, | 
|  | 62                           FROM_HERE, | 
|  | 63                           base::Bind(callback, REGISTRATION_OK, match->second)); | 
|  | 64 } | 
|  | 65 | 
|  | 66 void ServiceWorkerStorage::FindRegistrationForDocument( | 
|  | 67     const GURL& document_url, | 
|  | 68     const RegistrationCallback& callback) { | 
|  | 69   // TODO(alecflett): This needs to be synchronous in the fast path, | 
|  | 70   // but asynchronous in the slow path (when the patterns have to be | 
|  | 71   // loaded from disk). For now it is always pessimistically async. | 
|  | 72   for (PatternToRegistrationMap::const_iterator it = | 
|  | 73            registration_by_pattern_.begin(); | 
|  | 74        it != registration_by_pattern_.end(); | 
|  | 75        ++it) { | 
|  | 76     if (PatternMatches(it->first, document_url)) { | 
|  | 77       BrowserThread::PostTask( | 
|  | 78           BrowserThread::IO, | 
|  | 79           FROM_HERE, | 
|  | 80           base::Bind(callback, | 
|  | 81                      REGISTRATION_OK, | 
|  | 82                      scoped_refptr<ServiceWorkerRegistration>(it->second))); | 
|  | 83       return; | 
|  | 84     } | 
|  | 85   } | 
|  | 86   BrowserThread::PostTask( | 
|  | 87       BrowserThread::IO, | 
|  | 88       FROM_HERE, | 
|  | 89       base::Bind(callback, | 
|  | 90                  REGISTRATION_NOT_FOUND, | 
|  | 91                  scoped_refptr<ServiceWorkerRegistration>())); | 
|  | 92 } | 
|  | 93 | 
|  | 94 void ServiceWorkerStorage::Register(const GURL& pattern, | 
|  | 95                                     const GURL& script_url, | 
|  | 96                                     const RegistrationCallback& callback) { | 
|  | 97   scoped_ptr<ServiceWorkerRegisterJob> job(new ServiceWorkerRegisterJob( | 
|  | 98       weak_factory_.GetWeakPtr(), | 
|  | 99       base::Bind(&ServiceWorkerStorage::RegisterComplete, | 
|  | 100                  weak_factory_.GetWeakPtr(), | 
|  | 101                  callback))); | 
|  | 102   job->StartRegister(pattern, script_url); | 
|  | 103   registration_jobs_.push_back(job.release()); | 
|  | 104 } | 
|  | 105 | 
|  | 106 void ServiceWorkerStorage::Unregister(const GURL& pattern, | 
|  | 107                                       const UnregistrationCallback& callback) { | 
|  | 108   scoped_ptr<ServiceWorkerRegisterJob> job(new ServiceWorkerRegisterJob( | 
|  | 109       weak_factory_.GetWeakPtr(), | 
|  | 110       base::Bind(&ServiceWorkerStorage::UnregisterComplete, | 
|  | 111                  weak_factory_.GetWeakPtr(), | 
|  | 112                  callback))); | 
|  | 113   job->StartUnregister(pattern); | 
|  | 114   registration_jobs_.push_back(job.release()); | 
|  | 115 } | 
|  | 116 | 
|  | 117 scoped_refptr<ServiceWorkerRegistration> ServiceWorkerStorage::RegisterInternal( | 
|  | 118     const GURL& pattern, | 
|  | 119     const GURL& script_url) { | 
|  | 120 | 
|  | 121   PatternToRegistrationMap::const_iterator current( | 
|  | 122       registration_by_pattern_.find(pattern)); | 
|  | 123   DCHECK(current == registration_by_pattern_.end() || | 
|  | 124          current->second->script_url() == script_url); | 
|  | 125 | 
|  | 126   if (current == registration_by_pattern_.end()) { | 
|  | 127     scoped_refptr<ServiceWorkerRegistration> registration( | 
|  | 128         new ServiceWorkerRegistration( | 
|  | 129             pattern, script_url, NextRegistrationId())); | 
|  | 130     // TODO(alecflett): version upgrade path. | 
|  | 131     registration_by_pattern_[pattern] = registration; | 
|  | 132     return registration; | 
|  | 133   } | 
|  | 134 | 
|  | 135   return current->second; | 
|  | 136 } | 
|  | 137 | 
|  | 138 void ServiceWorkerStorage::UnregisterInternal(const GURL& pattern) { | 
|  | 139   PatternToRegistrationMap::iterator match = | 
|  | 140       registration_by_pattern_.find(pattern); | 
|  | 141   if (match != registration_by_pattern_.end()) { | 
|  | 142     match->second->Shutdown(); | 
|  | 143     registration_by_pattern_.erase(match); | 
|  | 144   } | 
|  | 145 } | 
|  | 146 | 
|  | 147 bool ServiceWorkerStorage::PatternMatches(const GURL& pattern, | 
|  | 148                                           const GURL& url) { | 
|  | 149   // This is a really basic, naive | 
|  | 150   // TODO(alecflett): Formalize what pattern matches mean. | 
|  | 151   // Temporarily borrowed directly from appcache::Namespace::IsMatch(). | 
|  | 152   // We have to escape '?' characters since MatchPattern also treats those | 
|  | 153   // as wildcards which we don't want here, we only do '*'s. | 
|  | 154   std::string pattern_spec(pattern.spec()); | 
|  | 155   if (pattern.has_query()) | 
|  | 156     ReplaceSubstringsAfterOffset(&pattern_spec, 0, "?", "\\?"); | 
|  | 157   return MatchPattern(url.spec(), pattern_spec); | 
|  | 158 } | 
|  | 159 | 
|  | 160 void ServiceWorkerStorage::EraseJob(ServiceWorkerRegisterJob* job) { | 
|  | 161   ScopedVector<ServiceWorkerRegisterJob>::iterator job_position = | 
|  | 162       registration_jobs_.begin(); | 
|  | 163   for (; job_position != registration_jobs_.end(); ++job_position) { | 
|  | 164     if (*job_position == job) { | 
|  | 165       registration_jobs_.erase(job_position); | 
|  | 166       return; | 
|  | 167     } | 
|  | 168   } | 
|  | 169   NOTREACHED() << "Deleting non-existent job. "; | 
|  | 170 } | 
|  | 171 | 
|  | 172 void ServiceWorkerStorage::UnregisterComplete( | 
|  | 173     const UnregistrationCallback& callback, | 
|  | 174     ServiceWorkerRegisterJob* job, | 
|  | 175     ServiceWorkerRegistrationStatus status, | 
|  | 176     ServiceWorkerRegistration* previous_registration) { | 
|  | 177   callback.Run(status); | 
|  | 178   EraseJob(job); | 
|  | 179 } | 
|  | 180 | 
|  | 181 void ServiceWorkerStorage::RegisterComplete( | 
|  | 182     const RegistrationCallback& callback, | 
|  | 183     ServiceWorkerRegisterJob* job, | 
|  | 184     ServiceWorkerRegistrationStatus status, | 
|  | 185     ServiceWorkerRegistration* registration) { | 
|  | 186   callback.Run(status, registration); | 
|  | 187   EraseJob(job); | 
|  | 188 } | 
|  | 189 | 
|  | 190 }  // namespace content | 
| OLD | NEW | 
|---|