| Index: chrome/browser/push_messaging/push_messaging_app_identifier.cc
|
| diff --git a/chrome/browser/push_messaging/push_messaging_app_identifier.cc b/chrome/browser/push_messaging/push_messaging_app_identifier.cc
|
| index feb069a006cdea7024aaf665d1c6bc2b3091624a..0c431e17a6fc8ca549f1f8474ac196f53d30a4bc 100644
|
| --- a/chrome/browser/push_messaging/push_messaging_app_identifier.cc
|
| +++ b/chrome/browser/push_messaging/push_messaging_app_identifier.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
|
|
|
| +#include <string.h>
|
| +
|
| #include "base/guid.h"
|
| #include "base/logging.h"
|
| #include "base/prefs/pref_service.h"
|
| @@ -16,11 +18,38 @@
|
| #include "chrome/common/pref_names.h"
|
| #include "components/pref_registry/pref_registry_syncable.h"
|
|
|
| +const char kPushMessagingAppIdentifierPrefix[] = "wp:";
|
| +
|
| namespace {
|
| +
|
| +// sizeof is strlen + 1 since it's null-terminated.
|
| +const size_t kPrefixLength = sizeof(kPushMessagingAppIdentifierPrefix) - 1;
|
| +
|
| const char kSeparator = '#'; // Ok as only the origin of the url is used.
|
| -} // namespace
|
| +const size_t kGuidLength = 36; // "%08X-%04X-%04X-%04X-%012llX"
|
|
|
| -const char kPushMessagingAppIdentifierPrefix[] = "wp:";
|
| +std::string MakePrefValue(const GURL& origin,
|
| + int64_t service_worker_registration_id) {
|
| + return origin.spec() + kSeparator
|
| + + base::Int64ToString(service_worker_registration_id);
|
| +}
|
| +
|
| +bool GetOriginAndSWRFromPrefValue(
|
| + const std::string& pref_value, GURL* origin,
|
| + int64_t* service_worker_registration_id) {
|
| + std::vector<std::string> parts;
|
| + base::SplitString(pref_value, kSeparator, &parts);
|
| + if (parts.size() != 2)
|
| + return false;
|
| +
|
| + if (!base::StringToInt64(parts[1], service_worker_registration_id))
|
| + return false;
|
| +
|
| + *origin = GURL(parts[0]);
|
| + return origin->is_valid();
|
| +}
|
| +
|
| +} // namespace
|
|
|
| // static
|
| void PushMessagingAppIdentifier::RegisterProfilePrefs(
|
| @@ -34,7 +63,8 @@ PushMessagingAppIdentifier PushMessagingAppIdentifier::Generate(
|
| {
|
| std::string guid = base::GenerateGUID();
|
| CHECK(!guid.empty());
|
| - std::string app_id = kPushMessagingAppIdentifierPrefix + guid;
|
| + std::string app_id = kPushMessagingAppIdentifierPrefix + origin.spec()
|
| + + kSeparator + guid;
|
|
|
| PushMessagingAppIdentifier app_identifier(app_id, origin,
|
| service_worker_registration_id);
|
| @@ -43,55 +73,49 @@ PushMessagingAppIdentifier PushMessagingAppIdentifier::Generate(
|
| }
|
|
|
| // static
|
| -PushMessagingAppIdentifier PushMessagingAppIdentifier::Get(
|
| +PushMessagingAppIdentifier PushMessagingAppIdentifier::FindByAppId(
|
| Profile* profile, const std::string& app_id) {
|
| - // Workaround crbug.com/461867 in GCM where it converts subtypes to lowercase.
|
| - // TODO(johnme): Remove this when obsolete
|
| - const size_t prefix_len = strlen(kPushMessagingAppIdentifierPrefix);
|
| - if (app_id.size() < prefix_len)
|
| - return PushMessagingAppIdentifier();
|
| - std::string uppercase_app_id =
|
| - app_id.substr(0, prefix_len) +
|
| - StringToUpperASCII(app_id.substr(prefix_len, std::string::npos));
|
| + // Check case of app_id hasn't been mangled (crbug.com/461867).
|
| + DCHECK_GE(app_id.size(), kPrefixLength + kGuidLength);
|
| + DCHECK_EQ(kPushMessagingAppIdentifierPrefix, app_id.substr(0, kPrefixLength));
|
| + DCHECK_EQ(app_id.substr(app_id.size() - kGuidLength),
|
| + StringToUpperASCII(app_id.substr(app_id.size() - kGuidLength)));
|
|
|
| const base::DictionaryValue* map =
|
| profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
|
|
|
| - std::string origin_and_sw_id;
|
| - if (!map->GetStringWithoutPathExpansion(uppercase_app_id, &origin_and_sw_id))
|
| - return PushMessagingAppIdentifier();
|
| -
|
| - std::vector<std::string> parts;
|
| - base::SplitString(origin_and_sw_id, kSeparator, &parts);
|
| - if (parts.size() != 2)
|
| + std::string map_value;
|
| + if (!map->GetStringWithoutPathExpansion(app_id, &map_value))
|
| return PushMessagingAppIdentifier();
|
|
|
| - GURL origin = GURL(parts[0]);
|
| -
|
| + GURL origin;
|
| int64_t service_worker_registration_id;
|
| - if (!base::StringToInt64(parts[1], &service_worker_registration_id))
|
| + if (!GetOriginAndSWRFromPrefValue(map_value, &origin,
|
| + &service_worker_registration_id)) {
|
| + NOTREACHED();
|
| return PushMessagingAppIdentifier();
|
| + }
|
|
|
| - PushMessagingAppIdentifier app_identifier(uppercase_app_id, origin,
|
| + PushMessagingAppIdentifier app_identifier(app_id, origin,
|
| service_worker_registration_id);
|
| app_identifier.DCheckValid();
|
| return app_identifier;
|
| }
|
|
|
| // static
|
| -PushMessagingAppIdentifier PushMessagingAppIdentifier::Get(
|
| +PushMessagingAppIdentifier PushMessagingAppIdentifier::FindByServiceWorker(
|
| Profile* profile, const GURL& origin,
|
| int64_t service_worker_registration_id)
|
| {
|
| - base::StringValue origin_and_sw_id = base::StringValue(origin.spec() +
|
| - kSeparator + base::Int64ToString(service_worker_registration_id));
|
| + const base::StringValue pref_value =
|
| + base::StringValue(MakePrefValue(origin, service_worker_registration_id));
|
|
|
| const base::DictionaryValue* map =
|
| profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
|
| for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd();
|
| it.Advance()) {
|
| - if (it.value().Equals(&origin_and_sw_id))
|
| - return Get(profile, it.key());
|
| + if (it.value().Equals(&pref_value))
|
| + return FindByAppId(profile, it.key());
|
| }
|
| return PushMessagingAppIdentifier();
|
| }
|
| @@ -105,7 +129,7 @@ std::vector<PushMessagingAppIdentifier> PushMessagingAppIdentifier::GetAll(
|
| profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
|
| for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd();
|
| it.Advance()) {
|
| - result.push_back(Get(profile, it.key()));
|
| + result.push_back(FindByAppId(profile, it.key()));
|
| }
|
|
|
| return result;
|
| @@ -137,14 +161,13 @@ void PushMessagingAppIdentifier::PersistToPrefs(Profile* profile) const {
|
|
|
| // Delete any stale entry with the same origin and Service Worker
|
| // registration id (hence we ensure there is a 1:1 not 1:many mapping).
|
| - PushMessagingAppIdentifier old = Get(profile, origin_,
|
| - service_worker_registration_id_);
|
| + PushMessagingAppIdentifier old = FindByServiceWorker(
|
| + profile, origin_, service_worker_registration_id_);
|
| if (!old.is_null())
|
| - map->RemoveWithoutPathExpansion(old.app_id_, nullptr);
|
| + map->RemoveWithoutPathExpansion(old.app_id_, nullptr /* out_value */);
|
|
|
| - std::string origin_and_sw_id = origin_.spec() + kSeparator +
|
| - base::Int64ToString(service_worker_registration_id_);
|
| - map->SetStringWithoutPathExpansion(app_id_, origin_and_sw_id);
|
| + map->SetStringWithoutPathExpansion(
|
| + app_id_, MakePrefValue(origin_, service_worker_registration_id_));
|
| }
|
|
|
| void PushMessagingAppIdentifier::DeleteFromPrefs(Profile* profile) const {
|
| @@ -153,14 +176,27 @@ void PushMessagingAppIdentifier::DeleteFromPrefs(Profile* profile) const {
|
| DictionaryPrefUpdate update(profile->GetPrefs(),
|
| prefs::kPushMessagingAppIdentifierMap);
|
| base::DictionaryValue* map = update.Get();
|
| - map->RemoveWithoutPathExpansion(app_id_, nullptr);
|
| + map->RemoveWithoutPathExpansion(app_id_, nullptr /* out_value */);
|
| }
|
|
|
| void PushMessagingAppIdentifier::DCheckValid() const {
|
| - const size_t prefix_len = strlen(kPushMessagingAppIdentifierPrefix);
|
| DCHECK_GE(service_worker_registration_id_, 0);
|
| +
|
| DCHECK(origin_.is_valid());
|
| DCHECK_EQ(origin_.GetOrigin(), origin_);
|
| - DCHECK_EQ(app_id_.substr(0, prefix_len), kPushMessagingAppIdentifierPrefix);
|
| - DCHECK(base::IsValidGUID(app_id_.substr(prefix_len, std::string::npos)));
|
| +
|
| + // "wp:"
|
| + DCHECK_EQ(kPushMessagingAppIdentifierPrefix,
|
| + app_id_.substr(0, kPrefixLength));
|
| + // Optional (origin.spec() + '#')
|
| + if (app_id_.size() != kPrefixLength + kGuidLength) {
|
| + const size_t suffix_length = 1 /* kSeparator */ + kGuidLength;
|
| + DCHECK(app_id_.size() > kPrefixLength + suffix_length);
|
| + DCHECK_EQ(origin_, GURL(app_id_.substr(
|
| + kPrefixLength, app_id_.size() - kPrefixLength - suffix_length)));
|
| + DCHECK_EQ(std::string(1, kSeparator),
|
| + app_id_.substr(app_id_.size() - suffix_length, 1));
|
| + }
|
| + // GUID
|
| + DCHECK(base::IsValidGUID(app_id_.substr(app_id_.size() - kGuidLength)));
|
| }
|
|
|