diff options
Diffstat (limited to 'dom/localstorage/LocalStorageCommon.cpp')
-rw-r--r-- | dom/localstorage/LocalStorageCommon.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/dom/localstorage/LocalStorageCommon.cpp b/dom/localstorage/LocalStorageCommon.cpp new file mode 100644 index 0000000000..a5b01e0146 --- /dev/null +++ b/dom/localstorage/LocalStorageCommon.cpp @@ -0,0 +1,160 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "LocalStorageCommon.h" + +#include <cstdint> +#include "MainThreadUtils.h" +#include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" +#include "mozilla/Logging.h" +#include "mozilla/OriginAttributes.h" +#include "mozilla/Preferences.h" +#include "mozilla/RefPtr.h" +#include "mozilla/StaticMutex.h" +#include "mozilla/StaticPrefs_dom.h" +#include "mozilla/dom/StorageUtils.h" +#include "mozilla/dom/quota/ResultExtensions.h" +#include "mozilla/ipc/PBackgroundSharedTypes.h" +#include "mozilla/net/MozURL.h" +#include "mozilla/net/WebSocketFrame.h" +#include "nsDebug.h" +#include "nsError.h" +#include "nsPrintfCString.h" +#include "nsString.h" +#include "nsStringFlags.h" +#include "nsXULAppAPI.h" + +namespace mozilla::dom { + +using namespace mozilla::net; + +namespace { + +StaticMutex gNextGenLocalStorageMutex; +Atomic<int32_t> gNextGenLocalStorageEnabled(-1); +LazyLogModule gLogger("LocalStorage"); + +} // namespace + +const char16_t* kLocalStorageType = u"localStorage"; + +bool NextGenLocalStorageEnabled() { + if (XRE_IsParentProcess()) { + StaticMutexAutoLock lock(gNextGenLocalStorageMutex); + + if (gNextGenLocalStorageEnabled == -1) { + // Ideally all this Mutex stuff would be replaced with just using + // an AtStartup StaticPref, but there are concerns about this causing + // deadlocks if this access needs to init the AtStartup cache. + bool enabled = + !StaticPrefs:: + dom_storage_enable_unsupported_legacy_implementation_DoNotUseDirectly(); + + gNextGenLocalStorageEnabled = enabled ? 1 : 0; + } + + return !!gNextGenLocalStorageEnabled; + } + + return CachedNextGenLocalStorageEnabled(); +} + +void RecvInitNextGenLocalStorageEnabled(const bool aEnabled) { + MOZ_ASSERT(!XRE_IsParentProcess()); + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(gNextGenLocalStorageEnabled == -1); + + gNextGenLocalStorageEnabled = aEnabled ? 1 : 0; +} + +bool CachedNextGenLocalStorageEnabled() { + MOZ_ASSERT(gNextGenLocalStorageEnabled != -1); + + return !!gNextGenLocalStorageEnabled; +} + +Result<std::pair<nsCString, nsCString>, nsresult> GenerateOriginKey2( + const mozilla::ipc::PrincipalInfo& aPrincipalInfo) { + OriginAttributes attrs; + nsCString spec; + + switch (aPrincipalInfo.type()) { + case mozilla::ipc::PrincipalInfo::TNullPrincipalInfo: { + const auto& info = aPrincipalInfo.get_NullPrincipalInfo(); + + attrs = info.attrs(); + spec = info.spec(); + + break; + } + + case mozilla::ipc::PrincipalInfo::TContentPrincipalInfo: { + const auto& info = aPrincipalInfo.get_ContentPrincipalInfo(); + + attrs = info.attrs(); + spec = info.spec(); + + break; + } + + default: { + spec.SetIsVoid(true); + + break; + } + } + + if (spec.IsVoid()) { + return Err(NS_ERROR_UNEXPECTED); + } + + nsCString originAttrSuffix; + attrs.CreateSuffix(originAttrSuffix); + + RefPtr<MozURL> specURL; + QM_TRY(MOZ_TO_RESULT(MozURL::Init(getter_AddRefs(specURL), spec))); + + nsCString host(specURL->Host()); + uint32_t length = host.Length(); + if (length > 0 && host.CharAt(0) == '[' && host.CharAt(length - 1) == ']') { + host = Substring(host, 1, length - 2); + } + + nsCString domainOrigin(host); + + if (domainOrigin.IsEmpty()) { + // For the file:/// protocol use the exact directory as domain. + if (specURL->Scheme().EqualsLiteral("file")) { + domainOrigin.Assign(specURL->Directory()); + } + } + + // Append reversed domain + nsAutoCString reverseDomain; + nsresult rv = StorageUtils::CreateReversedDomain(domainOrigin, reverseDomain); + if (NS_FAILED(rv)) { + return Err(rv); + } + + nsCString originKey = reverseDomain; + + // Append scheme + originKey.Append(':'); + originKey.Append(specURL->Scheme()); + + // Append port if any + int32_t port = specURL->RealPort(); + if (port != -1) { + originKey.AppendPrintf(":%d", port); + } + + return std::make_pair(std::move(originAttrSuffix), std::move(originKey)); +} + +LogModule* GetLocalStorageLogger() { return gLogger; } + +} // namespace mozilla::dom |