Chromium Code Reviews| Index: content/browser/service_worker/service_worker_database.cc |
| diff --git a/content/browser/service_worker/service_worker_database.cc b/content/browser/service_worker/service_worker_database.cc |
| index 153be6e50261c2b59765fe82433e43bce0374e7d..966e1eab5889851aa32e3f17ec4b845f750bb881 100644 |
| --- a/content/browser/service_worker/service_worker_database.cc |
| +++ b/content/browser/service_worker/service_worker_database.cc |
| @@ -83,6 +83,9 @@ |
| // value: <empty> |
| // - This entry represents that the old BlockFile diskcache was deleted |
| // after diskcache migration (http://crbug.com/487482). |
| +// |
| +// key: "INITDATA_FOREIGN_FETCH_ORIGIN:" + <GURL 'origin'> |
| +// value: <empty> |
| namespace content { |
| namespace { |
| @@ -96,6 +99,7 @@ const char kDiskCacheMigrationNotNeededKey[] = |
| "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED"; |
| const char kOldDiskCacheDeletionNotNeededKey[] = |
| "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED"; |
| +const char kForeignFetchOriginKey[] = "INITDATA_FOREIGN_FETCH_ORIGIN:"; |
| const char kRegKeyPrefix[] = "REG:"; |
| const char kRegUserDataKeyPrefix[] = "REG_USER_DATA:"; |
| @@ -158,6 +162,11 @@ std::string CreateUniqueOriginKey(const GURL& origin) { |
| origin.GetOrigin().spec().c_str()); |
| } |
| +std::string CreateForeignFetchOriginKey(const GURL& origin) { |
| + return base::StringPrintf("%s%s", kForeignFetchOriginKey, |
| + origin.GetOrigin().spec().c_str()); |
| +} |
| + |
| std::string CreateResourceIdKey(const char* key_prefix, int64 resource_id) { |
| return base::StringPrintf( |
| "%s%s", key_prefix, base::Int64ToString(resource_id).c_str()); |
| @@ -206,6 +215,9 @@ void PutRegistrationDataToBatch( |
| data.set_has_fetch_handler(input.has_fetch_handler); |
| data.set_last_update_check_time(input.last_update_check.ToInternalValue()); |
| data.set_resources_total_size_bytes(input.resources_total_size_bytes); |
| + for (const GURL& url : input.foreign_fetch_scopes) { |
|
nhiroki
2015/10/21 05:42:54
Can you add DCHECK to check if |url| is a subscope
Marijn Kruisselbrink
2015/10/21 20:33:46
Done
|
| + data.add_foreign_fetch_scope(url.spec()); |
| + } |
| std::string value; |
| bool success = data.SerializeToString(&value); |
| @@ -245,6 +257,12 @@ void PutPurgeableResourceIdToBatch(int64 resource_id, |
| batch->Put(CreateResourceIdKey(kPurgeableResIdKeyPrefix, resource_id), ""); |
| } |
| +void PutForeignFetchOriginToBatch(const GURL& origin, |
| + leveldb::WriteBatch* batch) { |
| + // Value should be empty. |
| + batch->Put(CreateForeignFetchOriginKey(origin), ""); |
| +} |
| + |
| ServiceWorkerDatabase::Status ParseId( |
| const std::string& serialized, |
| int64* out) { |
| @@ -305,6 +323,9 @@ ServiceWorkerDatabase::Status ParseRegistrationData( |
| out->last_update_check = |
| base::Time::FromInternalValue(data.last_update_check_time()); |
| out->resources_total_size_bytes = data.resources_total_size_bytes(); |
| + for (int i = 0; i < data.foreign_fetch_scope_size(); ++i) { |
| + out->foreign_fetch_scopes.push_back(GURL(data.foreign_fetch_scope(i))); |
|
nhiroki
2015/10/21 05:42:54
Can you check if |foreign_fetch_scope| is a subsco
Marijn Kruisselbrink
2015/10/21 20:33:46
Done
|
| + } |
| return ServiceWorkerDatabase::STATUS_OK; |
| } |
| @@ -559,6 +580,47 @@ ServiceWorkerDatabase::GetOriginsWithRegistrations(std::set<GURL>* origins) { |
| return status; |
| } |
| +ServiceWorkerDatabase::Status |
| +ServiceWorkerDatabase::GetOriginsWithForeignFetchRegistrations( |
| + std::set<GURL>* origins) { |
| + DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| + DCHECK(origins->empty()); |
| + |
| + Status status = LazyOpen(false); |
| + if (IsNewOrNonexistentDatabase(status)) |
| + return STATUS_OK; |
| + if (status != STATUS_OK) |
| + return status; |
| + |
| + scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); |
| + for (itr->Seek(kForeignFetchOriginKey); itr->Valid(); itr->Next()) { |
| + status = LevelDBStatusToStatus(itr->status()); |
| + if (status != STATUS_OK) { |
| + HandleReadResult(FROM_HERE, status); |
| + origins->clear(); |
| + return status; |
| + } |
| + |
| + std::string origin_str; |
| + if (!RemovePrefix(itr->key().ToString(), kForeignFetchOriginKey, |
| + &origin_str)) |
| + break; |
| + |
| + GURL origin(origin_str); |
| + if (!origin.is_valid()) { |
| + status = STATUS_ERROR_CORRUPTED; |
| + HandleReadResult(FROM_HERE, status); |
| + origins->clear(); |
| + return status; |
| + } |
| + |
| + origins->insert(origin); |
| + } |
| + |
| + HandleReadResult(FROM_HERE, status); |
| + return status; |
| +} |
| + |
| ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetRegistrationsForOrigin( |
| const GURL& origin, |
| std::vector<RegistrationData>* registrations, |
| @@ -737,6 +799,9 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration( |
| PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch); |
| + if (!registration.foreign_fetch_scopes.empty()) |
| + PutForeignFetchOriginToBatch(registration.scope.GetOrigin(), &batch); |
| + |
| DCHECK_EQ(AccumulateResourceSizeInBytes(resources), |
| registration.resources_total_size_bytes) |
| << "The total size in the registration must match the cumulative " |
| @@ -788,6 +853,31 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration( |
| newly_purgeable_resources->end()); |
| DCHECK(base::STLSetIntersection<std::set<int64> >( |
| pushed_resources, deleted_resources).empty()); |
| + |
| + // If old registration had foreign fetch scopes, but new registration |
| + // doesn't, the origin might have to be removed from the list of origins |
| + // with foreign fetch scopes. |
| + // TODO(mek): Like the similar check in DeleteRegistration, ideally this |
| + // could be done more efficiently. |
| + if (!old_registration->foreign_fetch_scopes.empty() && |
| + registration.foreign_fetch_scopes.empty()) { |
| + std::vector<RegistrationData> registrations; |
| + status = GetRegistrationsForOrigin(registration.scope.GetOrigin(), |
| + ®istrations, nullptr); |
| + if (status != STATUS_OK) |
| + return status; |
| + bool remaining_ff_scopes = false; |
| + for (const auto& existing_reg : registrations) { |
| + if (existing_reg.registration_id != registration.registration_id && |
| + !existing_reg.foreign_fetch_scopes.empty()) { |
| + remaining_ff_scopes = true; |
| + break; |
| + } |
| + } |
| + if (!remaining_ff_scopes) |
| + batch.Delete( |
| + CreateForeignFetchOriginKey(registration.scope.GetOrigin())); |
| + } |
| } |
| return WriteBatch(&batch); |
| @@ -873,6 +963,19 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration( |
| batch.Delete(CreateUniqueOriginKey(origin)); |
| } |
| + // Remove |origin| from foreign fetch origins if a registration specified by |
| + // |registration_id| is the only one with foreign fetch scopes for |origin|. |
| + bool remaining_ff_scopes = false; |
| + for (const auto& registration : registrations) { |
| + if (registration.registration_id != registration_id && |
| + !registration.foreign_fetch_scopes.empty()) { |
| + remaining_ff_scopes = true; |
| + break; |
| + } |
| + } |
| + if (!remaining_ff_scopes) |
| + batch.Delete(CreateForeignFetchOriginKey(origin)); |
| + |
| // Delete a registration specified by |registration_id|. |
| batch.Delete(CreateRegistrationKey(registration_id, origin)); |
| batch.Delete(CreateRegistrationIdToOriginKey(registration_id)); |
| @@ -1080,6 +1183,9 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteAllDataForOrigins( |
| // Delete from the unique origin list. |
| batch.Delete(CreateUniqueOriginKey(origin)); |
| + // Delete from the foreign fetch origin list. |
| + batch.Delete(CreateForeignFetchOriginKey(origin)); |
| + |
| std::vector<RegistrationData> registrations; |
| status = GetRegistrationsForOrigin(origin, ®istrations, nullptr); |
| if (status != STATUS_OK) |