chromium/components/services/storage/service_worker/service_worker_database.cc

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/services/storage/service_worker/service_worker_database.h"

#include <optional>

#include "base/command_line.h"
#include "base/debug/crash_logging.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "components/services/storage/filesystem_proxy_factory.h"
#include "components/services/storage/public/mojom/service_worker_database.mojom-forward.h"
#include "components/services/storage/service_worker/service_worker_database.pb.h"
#include "services/network/public/cpp/web_sandbox_flags.h"
#include "services/network/public/mojom/ip_address_space.mojom-shared.h"
#include "services/network/public/mojom/referrer_policy.mojom.h"
#include "services/network/public/mojom/service_worker_router_info.mojom-shared.h"
#include "services/network/public/mojom/web_sandbox_flags.mojom-shared.h"
#include "third_party/blink/public/common/service_worker/service_worker_router_rule.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_ancestor_frame_type.mojom.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/leveldb_chrome.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
#include "url/origin.h"

// LevelDB database schema
// =======================
//
// NOTE
// - int64_t value is serialized as a string by base::NumberToString().
// - GURL value is serialized as a string by GURL::spec().
//
// Version 1 (in sorted order)
//   key: "INITDATA_DB_VERSION"
//   value: "1"
//
//   key: "INITDATA_NEXT_REGISTRATION_ID"
//   value: <int64_t 'next_available_registration_id'>
//
//   key: "INITDATA_NEXT_RESOURCE_ID"
//   value: <int64_t 'next_available_resource_id'>
//
//   key: "INITDATA_NEXT_VERSION_ID"
//   value: <int64_t 'next_available_version_id'>
//
//   Note: This has changed from `GURL origin` to StorageKey but the name will
//   be updated in the future to avoid a migration.
//   TODO(crbug.com/40177656): Update name during a migration to Version 3.
//   See StorageKey::Deserialize() for more information on the format.
//   key: "INITDATA_UNIQUE_ORIGIN:" + <StorageKey>
//   value: <empty>
//
//   key: "PRES:" + <int64_t 'purgeable_resource_id'>
//   value: <empty>
//
//   Note: This has changed from `GURL origin` to StorageKey but the name will
//   be updated in the future to avoid a migration.
//   TODO(crbug.com/40177656): Update name during a migration to Version 3.
//   See StorageKey::Deserialize() for more information on the format.
//   key: "REG:" + <StorageKey> + '\x00' + <int64_t 'registration_id'>
//    (ex. "REG:https://example.com/\x00123456")
//   value: <ServiceWorkerRegistrationData (except for the StorageKey)
//   serialized as a string>
//
//   key: "REG_HAS_USER_DATA:" + <std::string 'user_data_name'> + '\x00'
//            + <int64_t 'registration_id'>
//   value: <empty>
//
//   key: "REG_USER_DATA:" + <int64_t 'registration_id'> + '\x00'
//            + <std::string user_data_name>
//     (ex. "REG_USER_DATA:123456\x00foo_bar")
//   value: <std::string user_data>
//
//   key: "RES:" + <int64_t 'version_id'> + '\x00' + <int64_t 'resource_id'>
//     (ex. "RES:123456\x00654321")
//   value: <ServiceWorkerResourceRecord serialized as a string>
//
//   key: "URES:" + <int64_t 'uncommitted_resource_id'>
//   value: <empty>
//
// Version 2
//
//   Note: This has changed from `GURL origin` to StorageKey but the name will
//   be updated in the future to avoid a migration.
//   TODO(crbug.com/40177656): Update name during a migration to Version 3.
//   See StorageKey::Deserialize() for more information on the format.
//   key: "REGID_TO_ORIGIN:" + <int64_t 'registration_id'>
//   value: <StorageKey>
//
//   OBSOLETE: https://crbug.com/539713
//   key: "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED"
//   value: <empty>
//     - This entry represents that the diskcache uses the Simple backend and
//       does not have to do diskcache migration (http://crbug.com/487482).
//
//   OBSOLETE: https://crbug.com/539713
//   key: "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED"
//   value: <empty>
//     - This entry represents that the old BlockFile diskcache was deleted
//       after diskcache migration (http://crbug.com/487482).
//
//   OBSOLETE: https://crbug.com/788604
//   key: "INITDATA_FOREIGN_FETCH_ORIGIN:" + <GURL 'origin'>
//   value: <empty>

namespace storage {

namespace service_worker_internals {

const char kDatabaseVersionKey[] =;
const char kNextRegIdKey[] =;
const char kNextResIdKey[] =;
const char kNextVerIdKey[] =;
const char kUniqueOriginKey[] =;

const char kRegKeyPrefix[] =;
const char kRegUserDataKeyPrefix[] =;
const char kRegHasUserDataKeyPrefix[] =;
const char kRegIdToOriginKeyPrefix[] =;
const char kResKeyPrefix[] =;
const char kKeySeparator =;

const char kUncommittedResIdKeyPrefix[] =;
const char kPurgeableResIdKeyPrefix[] =;

const int64_t kCurrentSchemaVersion =;

const int kRouterRuleVersion =;

}  // namespace service_worker_internals

namespace {

// The data size is usually small, but the values are changed frequently. So,
// set a low write buffer size to trigger compaction more often.
constexpr size_t kWriteBufferSize =;

class ServiceWorkerEnv : public leveldb_env::ChromiumEnv {};

bool RemovePrefix(const std::string& str,
                  const std::string& prefix,
                  std::string* out) {}

std::string CreateRegistrationKeyPrefix(const blink::StorageKey& key) {}

std::string CreateRegistrationKey(int64_t registration_id,
                                  const blink::StorageKey& key) {}

std::string CreateResourceRecordKeyPrefix(int64_t version_id) {}

std::string CreateResourceRecordKey(int64_t version_id, int64_t resource_id) {}

std::string CreateUniqueOriginKey(const blink::StorageKey& key) {}

std::string CreateResourceIdKey(const char* key_prefix, int64_t resource_id) {}

std::string CreateUserDataKeyPrefix(int64_t registration_id) {}

std::string CreateUserDataKey(int64_t registration_id,
                              const std::string& user_data_name) {}

std::string CreateHasUserDataKeyPrefix(const std::string& user_data_name) {}

std::string CreateHasUserDataKey(int64_t registration_id,
                                 const std::string& user_data_name) {}

std::string CreateRegistrationIdToStorageKey(int64_t registration_id) {}

void PutUniqueOriginToBatch(const blink::StorageKey& key,
                            leveldb::WriteBatch* batch) {}

void PutPurgeableResourceIdToBatch(int64_t resource_id,
                                   leveldb::WriteBatch* batch) {}

ServiceWorkerDatabase::Status ParseId(const std::string& serialized,
                                      int64_t* out) {}

ServiceWorkerDatabase::Status LevelDBStatusToServiceWorkerDBStatus(
    const leveldb::Status& status) {}

int64_t AccumulateResourceSizeInBytes(
    const std::vector<mojom::ServiceWorkerResourceRecordPtr>& resources) {}

std::optional<std::vector<liburlpattern::Part>> ConvertToBlinkParts(
    const google::protobuf::RepeatedPtrField<
        storage::ServiceWorkerRegistrationData::RouterRules::RuleV1::Condition::
            URLPattern::Part>& parts) {}

void ConvertToProtoParts(
    const std::vector<liburlpattern::Part> parts,
    google::protobuf::RepeatedPtrField<
        storage::ServiceWorkerRegistrationData::RouterRules::RuleV1::Condition::
            URLPattern::Part>* out_parts) {}

// Returns whether the write operation succeeds
bool WriteToBlinkCondition(
    const ServiceWorkerRegistrationData::RouterRules::RuleV1::Condition&
        condition,
    blink::ServiceWorkerRouterCondition& out) {}

// Helper class to uniformly add conditions to both `ConditionObject` and
// `RuleV1` in the DB. This uses simple dynamic dispatch to avoid template
// functions.
class AddConditionHelper {};

// Write
void WriteConditionToProtoWithHelper(
    const blink::ServiceWorkerRouterCondition& condition,
    AddConditionHelper& out) {}

void WriteConditionToProto(
    const blink::ServiceWorkerRouterCondition& condition,
    ServiceWorkerRegistrationData::RouterRules::RuleV1* out) {}

}  // namespace

const char* ServiceWorkerDatabase::StatusToString(
    ServiceWorkerDatabase::Status status) {}

ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path)
    :{}

ServiceWorkerDatabase::~ServiceWorkerDatabase() {}

ServiceWorkerDatabase::DeletedVersion::DeletedVersion() = default;
ServiceWorkerDatabase::DeletedVersion::DeletedVersion(const DeletedVersion&) =
    default;
ServiceWorkerDatabase::DeletedVersion::~DeletedVersion() = default;

ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetNextAvailableIds(
    int64_t* next_avail_registration_id,
    int64_t* next_avail_version_id,
    int64_t* next_avail_resource_id) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::GetStorageKeysWithRegistrations(
    std::set<blink::StorageKey>* keys) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::GetRegistrationsForStorageKey(
    const blink::StorageKey& key,
    std::vector<mojom::ServiceWorkerRegistrationDataPtr>* registrations,
    std::vector<std::vector<mojom::ServiceWorkerResourceRecordPtr>>*
        opt_resources_list) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetUsageForStorageKey(
    const blink::StorageKey& key,
    int64_t& out_usage) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetAllRegistrations(
    std::vector<mojom::ServiceWorkerRegistrationDataPtr>* registrations) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistration(
    int64_t registration_id,
    const blink::StorageKey& key,
    mojom::ServiceWorkerRegistrationDataPtr* registration,
    std::vector<mojom::ServiceWorkerResourceRecordPtr>* resources) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistrationStorageKey(
    int64_t registration_id,
    blink::StorageKey* key) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
    const mojom::ServiceWorkerRegistrationData& registration,
    const std::vector<mojom::ServiceWorkerResourceRecordPtr>& resources,
    DeletedVersion* deleted_version) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::UpdateVersionToActive(
    int64_t registration_id,
    const blink::StorageKey& key) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::UpdateLastCheckTime(
    int64_t registration_id,
    const blink::StorageKey& key,
    const base::Time& time) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::UpdateNavigationPreloadEnabled(
    int64_t registration_id,
    const blink::StorageKey& key,
    bool enable) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::UpdateNavigationPreloadHeader(
    int64_t registration_id,
    const blink::StorageKey& key,
    const std::string& value) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::UpdateFetchHandlerType(
    int64_t registration_id,
    const blink::StorageKey& key,
    const blink::mojom::ServiceWorkerFetchHandlerType type) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::UpdateResourceSha256Checksums(
    int64_t registration_id,
    const blink::StorageKey& key,
    const base::flat_map<int64_t, std::string>& updated_sha256_checksums) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration(
    int64_t registration_id,
    const blink::StorageKey& key,
    DeletedVersion* deleted_version) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadUserData(
    int64_t registration_id,
    const std::vector<std::string>& user_data_names,
    std::vector<std::string>* user_data_values) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadUserDataByKeyPrefix(
    int64_t registration_id,
    const std::string& user_data_name_prefix,
    std::vector<std::string>* user_data_values) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::ReadUserKeysAndDataByKeyPrefix(
    int64_t registration_id,
    const std::string& user_data_name_prefix,
    base::flat_map<std::string, std::string>* user_data_map) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteUserData(
    int64_t registration_id,
    const blink::StorageKey& key,
    const std::vector<mojom::ServiceWorkerUserDataPtr>& user_data) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteUserData(
    int64_t registration_id,
    const std::vector<std::string>& user_data_names) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::DeleteUserDataByKeyPrefixes(
    int64_t registration_id,
    const std::vector<std::string>& user_data_name_prefixes) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::RewriteDB() {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::ReadUserDataForAllRegistrations(
    const std::string& user_data_name,
    std::vector<mojom::ServiceWorkerUserDataPtr>* user_data) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::ReadUserDataForAllRegistrationsByKeyPrefix(
    const std::string& user_data_name_prefix,
    std::vector<mojom::ServiceWorkerUserDataPtr>* user_data) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::DeleteUserDataForAllRegistrationsByKeyPrefix(
    const std::string& user_data_name_prefix) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetUncommittedResourceIds(
    std::vector<int64_t>* ids) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::WriteUncommittedResourceIds(
    const std::vector<int64_t>& ids) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetPurgeableResourceIds(
    std::vector<int64_t>* ids) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ClearPurgeableResourceIds(
    const std::vector<int64_t>& ids) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::PurgeUncommittedResourceIds(
    const std::vector<int64_t>& ids) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteAllDataForOrigins(
    const std::set<url::Origin>& origins,
    std::vector<int64_t>* newly_purgeable_resources) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::DestroyDatabase() {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::LazyOpen(
    bool create_if_missing) {}

bool ServiceWorkerDatabase::IsNewOrNonexistentDatabase(
    ServiceWorkerDatabase::Status status) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadNextAvailableId(
    const char* id_key,
    int64_t* next_avail_id) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistrationData(
    int64_t registration_id,
    const blink::StorageKey& key,
    mojom::ServiceWorkerRegistrationDataPtr* registration) {}

network::mojom::ReferrerPolicy ConvertReferrerPolicyFromProtocolBufferToMojom(
    ServiceWorkerRegistrationData::ReferrerPolicyValue value) {}

network::mojom::IPAddressSpace ConvertIPAddressSpaceFromProtocolBufferToMojom(
    ServiceWorkerRegistrationData::IPAddressSpace value) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseRegistrationData(
    const std::string& serialized,
    const blink::StorageKey& key,
    mojom::ServiceWorkerRegistrationDataPtr* out) {}

ServiceWorkerRegistrationData::CrossOriginEmbedderPolicyValue
ConvertCrossOriginEmbedderPolicyValueFromMojomToProtocolBuffer(
    network::mojom::CrossOriginEmbedderPolicyValue value) {}

ServiceWorkerRegistrationData::ReferrerPolicyValue
ConvertReferrerPolicyFromMojomToProtocolBuffer(
    network::mojom::ReferrerPolicy value) {}

ServiceWorkerRegistrationData::IPAddressSpace
ConvertIPAddressSpaceFromMojomToProtocolBuffer(
    network::mojom::IPAddressSpace value) {}

void ServiceWorkerDatabase::WriteRegistrationDataInBatch(
    const mojom::ServiceWorkerRegistrationData& registration,
    leveldb::WriteBatch* batch) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceRecords(
    const mojom::ServiceWorkerRegistrationData& registration,
    std::vector<mojom::ServiceWorkerResourceRecordPtr>* resources) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseResourceRecord(
    const std::string& serialized,
    mojom::ServiceWorkerResourceRecordPtr* out) {}

void ServiceWorkerDatabase::WriteResourceRecordInBatch(
    const mojom::ServiceWorkerResourceRecord& resource,
    int64_t version_id,
    leveldb::WriteBatch* batch) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceRecords(
    int64_t version_id,
    std::vector<int64_t>* newly_purgeable_resources,
    leveldb::WriteBatch* batch) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceIds(
    const char* id_key_prefix,
    std::vector<int64_t>* ids) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteResourceIdsInBatch(
    const char* id_key_prefix,
    const std::vector<int64_t>& ids,
    leveldb::WriteBatch* batch) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceIdsInBatch(
    const char* id_key_prefix,
    const std::vector<int64_t>& ids,
    leveldb::WriteBatch* batch) {}

ServiceWorkerDatabase::Status
ServiceWorkerDatabase::DeleteUserDataForRegistration(
    int64_t registration_id,
    leveldb::WriteBatch* batch) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadDatabaseVersion(
    int64_t* db_version) {}

ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteBatch(
    leveldb::WriteBatch* batch) {}

void ServiceWorkerDatabase::BumpNextRegistrationIdIfNeeded(
    int64_t used_id,
    leveldb::WriteBatch* batch) {}

void ServiceWorkerDatabase::BumpNextResourceIdIfNeeded(
    int64_t used_id,
    leveldb::WriteBatch* batch) {}

void ServiceWorkerDatabase::BumpNextVersionIdIfNeeded(
    int64_t used_id,
    leveldb::WriteBatch* batch) {}

bool ServiceWorkerDatabase::IsOpen() {}

void ServiceWorkerDatabase::Disable(const base::Location& from_here,
                                    Status status) {}

void ServiceWorkerDatabase::HandleOpenResult(const base::Location& from_here,
                                             Status status) {}

void ServiceWorkerDatabase::HandleReadResult(const base::Location& from_here,
                                             Status status) {}

void ServiceWorkerDatabase::HandleWriteResult(const base::Location& from_here,
                                              Status status) {}

bool ServiceWorkerDatabase::IsDatabaseInMemory() const {}

}  // namespace storage