michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "CacheLog.h" michael@0: #include "CacheStorage.h" michael@0: #include "CacheStorageService.h" michael@0: #include "CacheEntry.h" michael@0: #include "CacheObserver.h" michael@0: michael@0: #include "OldWrappers.h" michael@0: michael@0: #include "nsICacheEntryDoomCallback.h" michael@0: michael@0: #include "nsIApplicationCache.h" michael@0: #include "nsIApplicationCacheService.h" michael@0: #include "nsIURI.h" michael@0: #include "nsNetCID.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: michael@0: namespace mozilla { michael@0: namespace net { michael@0: michael@0: NS_IMPL_ISUPPORTS(CacheStorage, nsICacheStorage) michael@0: michael@0: CacheStorage::CacheStorage(nsILoadContextInfo* aInfo, michael@0: bool aAllowDisk, michael@0: bool aLookupAppCache) michael@0: : mLoadContextInfo(GetLoadContextInfo(aInfo)) michael@0: , mWriteToDisk(aAllowDisk) michael@0: , mLookupAppCache(aLookupAppCache) michael@0: { michael@0: } michael@0: michael@0: CacheStorage::~CacheStorage() michael@0: { michael@0: } michael@0: michael@0: NS_IMETHODIMP CacheStorage::AsyncOpenURI(nsIURI *aURI, michael@0: const nsACString & aIdExtension, michael@0: uint32_t aFlags, michael@0: nsICacheEntryOpenCallback *aCallback) michael@0: { michael@0: if (!CacheStorageService::Self()) michael@0: return NS_ERROR_NOT_INITIALIZED; michael@0: michael@0: if (MOZ_UNLIKELY(!CacheObserver::UseDiskCache()) && mWriteToDisk) { michael@0: aCallback->OnCacheEntryAvailable(nullptr, false, nullptr, NS_ERROR_NOT_AVAILABLE); michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (MOZ_UNLIKELY(!CacheObserver::UseMemoryCache()) && !mWriteToDisk) { michael@0: aCallback->OnCacheEntryAvailable(nullptr, false, nullptr, NS_ERROR_NOT_AVAILABLE); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_ENSURE_ARG(aURI); michael@0: NS_ENSURE_ARG(aCallback); michael@0: michael@0: nsresult rv; michael@0: michael@0: bool truncate = aFlags & nsICacheStorage::OPEN_TRUNCATE; michael@0: michael@0: nsCOMPtr noRefURI; michael@0: rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCOMPtr appCache; michael@0: if (LookupAppCache()) { michael@0: rv = ChooseApplicationCache(noRefURI, getter_AddRefs(appCache)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: if (appCache) { michael@0: nsAutoCString cacheKey; michael@0: rv = noRefURI->GetAsciiSpec(cacheKey); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsAutoCString scheme; michael@0: rv = noRefURI->GetScheme(scheme); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsRefPtr<_OldCacheLoad> appCacheLoad = michael@0: new _OldCacheLoad(scheme, cacheKey, aCallback, appCache, michael@0: LoadInfo(), WriteToDisk(), aFlags); michael@0: rv = appCacheLoad->Start(); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: LOG(("CacheStorage::AsyncOpenURI loading from appcache")); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsRefPtr entry; michael@0: rv = CacheStorageService::Self()->AddStorageEntry( michael@0: this, noRefURI, aIdExtension, michael@0: true, // create always michael@0: truncate, // replace any existing one? michael@0: getter_AddRefs(entry)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // May invoke the callback synchronously michael@0: entry->Entry()->AsyncOpen(aCallback, aFlags); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP CacheStorage::AsyncDoomURI(nsIURI *aURI, const nsACString & aIdExtension, michael@0: nsICacheEntryDoomCallback* aCallback) michael@0: { michael@0: if (!CacheStorageService::Self()) michael@0: return NS_ERROR_NOT_INITIALIZED; michael@0: michael@0: nsresult rv = CacheStorageService::Self()->DoomStorageEntry( michael@0: this, aURI, aIdExtension, aCallback); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP CacheStorage::AsyncEvictStorage(nsICacheEntryDoomCallback* aCallback) michael@0: { michael@0: if (!CacheStorageService::Self()) michael@0: return NS_ERROR_NOT_INITIALIZED; michael@0: michael@0: nsresult rv = CacheStorageService::Self()->DoomStorageEntries( michael@0: this, aCallback); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP CacheStorage::AsyncVisitStorage(nsICacheStorageVisitor* aVisitor, michael@0: bool aVisitEntries) michael@0: { michael@0: LOG(("CacheStorage::AsyncVisitStorage [this=%p, cb=%p, disk=%d]", this, aVisitor, (bool)mWriteToDisk)); michael@0: if (!CacheStorageService::Self()) michael@0: return NS_ERROR_NOT_INITIALIZED; michael@0: michael@0: nsresult rv = CacheStorageService::Self()->WalkStorageEntries( michael@0: this, aVisitEntries, aVisitor); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: // Internal michael@0: michael@0: nsresult CacheStorage::ChooseApplicationCache(nsIURI* aURI, michael@0: nsIApplicationCache** aCache) michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr appCacheService = michael@0: do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsAutoCString cacheKey; michael@0: rv = aURI->GetAsciiSpec(cacheKey); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = appCacheService->ChooseApplicationCache(cacheKey, LoadInfo(), aCache); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: } // net michael@0: } // mozilla