forked from mirrors/gecko-dev
		
	 3f2298c2f6
			
		
	
	
		3f2298c2f6
		
	
	
	
	
		
			
			MozReview-Commit-ID: 666LNaHyiuQ --HG-- extra : rebase_source : f3a24e0342d8dcdf9020dd473bc6b1045cbc533b
		
			
				
	
	
		
			1155 lines
		
	
	
	
		
			31 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1155 lines
		
	
	
	
		
			31 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Stuff to link the old imp to the new api - will go away!
 | |
| 
 | |
| #include "CacheLog.h"
 | |
| #include "OldWrappers.h"
 | |
| #include "CacheStorage.h"
 | |
| #include "CacheStorageService.h"
 | |
| #include "LoadContextInfo.h"
 | |
| #include "nsCacheService.h"
 | |
| 
 | |
| #include "nsIURI.h"
 | |
| #include "nsICacheSession.h"
 | |
| #include "nsIApplicationCache.h"
 | |
| #include "nsIApplicationCacheService.h"
 | |
| #include "nsIStreamTransportService.h"
 | |
| #include "nsIFile.h"
 | |
| #include "nsICacheEntryDoomCallback.h"
 | |
| #include "nsICacheListener.h"
 | |
| #include "nsICacheStorageVisitor.h"
 | |
| 
 | |
| #include "nsServiceManagerUtils.h"
 | |
| #include "nsNetCID.h"
 | |
| #include "nsNetUtil.h"
 | |
| #include "nsProxyRelease.h"
 | |
| #include "mozilla/IntegerPrintfMacros.h"
 | |
| #include "mozilla/Telemetry.h"
 | |
| 
 | |
| static NS_DEFINE_CID(kStreamTransportServiceCID,
 | |
|                      NS_STREAMTRANSPORTSERVICE_CID);
 | |
| 
 | |
| static uint32_t const CHECK_MULTITHREADED = nsICacheStorage::CHECK_MULTITHREADED;
 | |
| 
 | |
| namespace mozilla {
 | |
| namespace net {
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| // Fires the doom callback back on the main thread
 | |
| // after the cache I/O thread is looped.
 | |
| 
 | |
| class DoomCallbackSynchronizer : public Runnable
 | |
| {
 | |
| public:
 | |
|   explicit DoomCallbackSynchronizer(nsICacheEntryDoomCallback* cb)
 | |
|     : Runnable("net::DoomCallbackSynchronizer")
 | |
|     , mCB(cb)
 | |
|   {
 | |
|   }
 | |
|   nsresult Dispatch();
 | |
| 
 | |
| private:
 | |
|   virtual ~DoomCallbackSynchronizer() = default;
 | |
| 
 | |
|   NS_DECL_NSIRUNNABLE
 | |
|   nsCOMPtr<nsICacheEntryDoomCallback> mCB;
 | |
| };
 | |
| 
 | |
| nsresult DoomCallbackSynchronizer::Dispatch()
 | |
| {
 | |
|   nsresult rv;
 | |
| 
 | |
|   nsCOMPtr<nsICacheService> serv =
 | |
|       do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   nsCOMPtr<nsIEventTarget> eventTarget;
 | |
|   rv = serv->GetCacheIOTarget(getter_AddRefs(eventTarget));
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   rv = eventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP DoomCallbackSynchronizer::Run()
 | |
| {
 | |
|   if (!NS_IsMainThread()) {
 | |
|     NS_DispatchToMainThread(this);
 | |
|   }
 | |
|   else {
 | |
|     if (mCB)
 | |
|       mCB->OnCacheEntryDoomed(NS_OK);
 | |
|   }
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| // Receives doom callback from the old API and forwards to the new API
 | |
| 
 | |
| class DoomCallbackWrapper : public nsICacheListener
 | |
| {
 | |
|   NS_DECL_THREADSAFE_ISUPPORTS
 | |
|   NS_DECL_NSICACHELISTENER
 | |
| 
 | |
|   explicit DoomCallbackWrapper(nsICacheEntryDoomCallback* cb) : mCB(cb)
 | |
|   {
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   virtual ~DoomCallbackWrapper() = default;
 | |
| 
 | |
|   nsCOMPtr<nsICacheEntryDoomCallback> mCB;
 | |
| };
 | |
| 
 | |
| NS_IMPL_ISUPPORTS(DoomCallbackWrapper, nsICacheListener);
 | |
| 
 | |
| NS_IMETHODIMP DoomCallbackWrapper::OnCacheEntryAvailable(nsICacheEntryDescriptor *descriptor,
 | |
|                                                          nsCacheAccessMode accessGranted,
 | |
|                                                          nsresult status)
 | |
| {
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP DoomCallbackWrapper::OnCacheEntryDoomed(nsresult status)
 | |
| {
 | |
|   if (!mCB)
 | |
|     return NS_ERROR_NULL_POINTER;
 | |
| 
 | |
|   mCB->OnCacheEntryDoomed(status);
 | |
|   mCB = nullptr;
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| } // namespace
 | |
| 
 | |
| // _OldVisitCallbackWrapper
 | |
| // Receives visit callbacks from the old API and forwards it to the new API
 | |
| 
 | |
| NS_IMPL_ISUPPORTS(_OldVisitCallbackWrapper, nsICacheVisitor)
 | |
| 
 | |
| _OldVisitCallbackWrapper::~_OldVisitCallbackWrapper()
 | |
| {
 | |
|   if (!mHit) {
 | |
|     // The device has not been found, to not break the chain, simulate
 | |
|     // storage info callback.
 | |
|     mCB->OnCacheStorageInfo(0, 0, 0, nullptr);
 | |
|   }
 | |
| 
 | |
|   if (mVisitEntries) {
 | |
|     mCB->OnCacheEntryVisitCompleted();
 | |
|   }
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldVisitCallbackWrapper::VisitDevice(const char * deviceID,
 | |
|                                                     nsICacheDeviceInfo *deviceInfo,
 | |
|                                                     bool *_retval)
 | |
| {
 | |
|   if (!mCB)
 | |
|     return NS_ERROR_NULL_POINTER;
 | |
| 
 | |
|   *_retval = false;
 | |
|   if (strcmp(deviceID, mDeviceID)) {
 | |
|     // Not the device we want to visit
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   mHit = true;
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   uint32_t capacity;
 | |
|   rv = deviceInfo->GetMaximumSize(&capacity);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   nsCOMPtr<nsIFile> dir;
 | |
|   if (!strcmp(mDeviceID, "disk")) {
 | |
|     nsCacheService::GetDiskCacheDirectory(getter_AddRefs(dir));
 | |
|   } else if (!strcmp(mDeviceID, "offline")) {
 | |
|     nsCacheService::GetAppCacheDirectory(getter_AddRefs(dir));
 | |
|   }
 | |
| 
 | |
|   if (mLoadInfo->IsAnonymous()) {
 | |
|     // Anonymous visiting reports 0, 0 since we cannot count that
 | |
|     // early the number of anon entries.
 | |
|     mCB->OnCacheStorageInfo(0, 0, capacity, dir);
 | |
|   } else {
 | |
|     // Non-anon visitor counts all non-anon + ALL ANON entries,
 | |
|     // there is no way to determine the number of entries when
 | |
|     // using the old cache APIs - there is no concept of anonymous
 | |
|     // storage.
 | |
|     uint32_t entryCount;
 | |
|     rv = deviceInfo->GetEntryCount(&entryCount);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     uint32_t totalSize;
 | |
|     rv = deviceInfo->GetTotalSize(&totalSize);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     mCB->OnCacheStorageInfo(entryCount, totalSize, capacity, dir);
 | |
|   }
 | |
| 
 | |
|   *_retval = mVisitEntries;
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldVisitCallbackWrapper::VisitEntry(const char * deviceID,
 | |
|                                                    nsICacheEntryInfo *entryInfo,
 | |
|                                                    bool *_retval)
 | |
| {
 | |
|   MOZ_ASSERT(!strcmp(deviceID, mDeviceID));
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   *_retval = true;
 | |
| 
 | |
|   // Read all informative properties from the entry.
 | |
|   nsAutoCString clientId;
 | |
|   rv = entryInfo->GetClientID(clientId);
 | |
|   if (NS_FAILED(rv))
 | |
|     return NS_OK;
 | |
| 
 | |
|   if (mLoadInfo->IsPrivate() !=
 | |
|       StringBeginsWith(clientId, NS_LITERAL_CSTRING("HTTP-memory-only-PB"))) {
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   nsAutoCString cacheKey, enhanceId;
 | |
|   rv = entryInfo->GetKey(cacheKey);
 | |
|   if (NS_FAILED(rv))
 | |
|     return NS_OK;
 | |
| 
 | |
|   if (StringBeginsWith(cacheKey, NS_LITERAL_CSTRING("anon&"))) {
 | |
|     if (!mLoadInfo->IsAnonymous())
 | |
|       return NS_OK;
 | |
| 
 | |
|     cacheKey = Substring(cacheKey, 5, cacheKey.Length());
 | |
|   } else if (mLoadInfo->IsAnonymous()) {
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   if (StringBeginsWith(cacheKey, NS_LITERAL_CSTRING("id="))) {
 | |
|     int32_t uriSpecEnd = cacheKey.Find("&uri=");
 | |
|     if (uriSpecEnd == kNotFound) // Corrupted, ignore
 | |
|       return NS_OK;
 | |
| 
 | |
|     enhanceId = Substring(cacheKey, 3, uriSpecEnd - 3);
 | |
|     cacheKey = Substring(cacheKey, uriSpecEnd + 1, cacheKey.Length());
 | |
|   }
 | |
| 
 | |
|   if (StringBeginsWith(cacheKey, NS_LITERAL_CSTRING("uri="))) {
 | |
|     cacheKey = Substring(cacheKey, 4, cacheKey.Length());
 | |
|   }
 | |
| 
 | |
|   nsCOMPtr<nsIURI> uri;
 | |
|   // cacheKey is strip of any prefixes
 | |
|   rv = NS_NewURI(getter_AddRefs(uri), cacheKey);
 | |
|   if (NS_FAILED(rv))
 | |
|     return NS_OK;
 | |
| 
 | |
|   uint32_t dataSize;
 | |
|   if (NS_FAILED(entryInfo->GetDataSize(&dataSize)))
 | |
|     dataSize = 0;
 | |
|   int32_t fetchCount;
 | |
|   if (NS_FAILED(entryInfo->GetFetchCount(&fetchCount)))
 | |
|     fetchCount = 0;
 | |
|   uint32_t expirationTime;
 | |
|   if (NS_FAILED(entryInfo->GetExpirationTime(&expirationTime)))
 | |
|     expirationTime = 0;
 | |
|   uint32_t lastModified;
 | |
|   if (NS_FAILED(entryInfo->GetLastModified(&lastModified)))
 | |
|     lastModified = 0;
 | |
| 
 | |
|   // Send them to the consumer.
 | |
|   rv = mCB->OnCacheEntryInfo(
 | |
|     uri, enhanceId, (int64_t)dataSize, fetchCount, lastModified,
 | |
|     expirationTime, false, mLoadInfo);
 | |
| 
 | |
|   *_retval = NS_SUCCEEDED(rv);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| // _OldGetDiskConsumption
 | |
| 
 | |
| //static
 | |
| nsresult _OldGetDiskConsumption::Get(nsICacheStorageConsumptionObserver* aCallback)
 | |
| {
 | |
|   nsresult rv;
 | |
| 
 | |
|   nsCOMPtr<nsICacheService> serv =
 | |
|       do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   RefPtr<_OldGetDiskConsumption> cb = new _OldGetDiskConsumption(aCallback);
 | |
| 
 | |
|   // _OldGetDiskConsumption stores the found size value, but until dispatched
 | |
|   // to the main thread it doesn't call on the consupmtion observer. See bellow.
 | |
|   rv = serv->VisitEntries(cb);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   // We are called from CacheStorageService::AsyncGetDiskConsumption whose IDL
 | |
|   // documentation claims the callback is always delievered asynchronously
 | |
|   // back to the main thread.  Despite we know the result synchronosusly when
 | |
|   // querying the old cache, we need to stand the word and dispatch the result
 | |
|   // to the main thread asynchronously.  Hence the dispatch here.
 | |
|   return NS_DispatchToMainThread(cb);
 | |
| }
 | |
| 
 | |
| NS_IMPL_ISUPPORTS_INHERITED(_OldGetDiskConsumption,
 | |
|                             Runnable,
 | |
|                             nsICacheVisitor)
 | |
| 
 | |
| _OldGetDiskConsumption::_OldGetDiskConsumption(
 | |
|   nsICacheStorageConsumptionObserver* aCallback)
 | |
|   : Runnable("net::_OldGetDiskConsumption")
 | |
|   , mCallback(aCallback)
 | |
|   , mSize(0)
 | |
| {
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| _OldGetDiskConsumption::Run()
 | |
| {
 | |
|   mCallback->OnNetworkCacheDiskConsumption(mSize);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| _OldGetDiskConsumption::VisitDevice(const char * deviceID,
 | |
|                                     nsICacheDeviceInfo *deviceInfo,
 | |
|                                     bool *_retval)
 | |
| {
 | |
|   if (!strcmp(deviceID, "disk")) {
 | |
|     uint32_t size;
 | |
|     nsresult rv = deviceInfo->GetTotalSize(&size);
 | |
|     if (NS_SUCCEEDED(rv))
 | |
|       mSize = (int64_t)size;
 | |
|   }
 | |
| 
 | |
|   *_retval = false;
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| _OldGetDiskConsumption::VisitEntry(const char * deviceID,
 | |
|                                    nsICacheEntryInfo *entryInfo,
 | |
|                                    bool *_retval)
 | |
| {
 | |
|   MOZ_CRASH("Unexpected");
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| // _OldCacheEntryWrapper
 | |
| 
 | |
| _OldCacheEntryWrapper::_OldCacheEntryWrapper(nsICacheEntryDescriptor* desc)
 | |
| : mOldDesc(desc), mOldInfo(desc), mCacheEntryId(CacheEntry::GetNextId())
 | |
| {
 | |
|   LOG(("Creating _OldCacheEntryWrapper %p for descriptor %p", this, desc));
 | |
| }
 | |
| 
 | |
| _OldCacheEntryWrapper::_OldCacheEntryWrapper(nsICacheEntryInfo* info)
 | |
| : mOldDesc(nullptr), mOldInfo(info), mCacheEntryId(CacheEntry::GetNextId())
 | |
| {
 | |
|   LOG(("Creating _OldCacheEntryWrapper %p for info %p", this, info));
 | |
| }
 | |
| 
 | |
| _OldCacheEntryWrapper::~_OldCacheEntryWrapper()
 | |
| {
 | |
|   LOG(("Destroying _OldCacheEntryWrapper %p for descriptor %p", this, mOldInfo.get()));
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::GetIsForcedValid(bool *aIsForcedValid)
 | |
| {
 | |
|   // Unused stub
 | |
|   return NS_ERROR_NOT_IMPLEMENTED;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::ForceValidFor(uint32_t aSecondsToTheFuture)
 | |
| {
 | |
|   // Unused stub
 | |
|   return NS_ERROR_NOT_IMPLEMENTED;
 | |
| }
 | |
| 
 | |
| NS_IMPL_ISUPPORTS(_OldCacheEntryWrapper, nsICacheEntry)
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::AsyncDoom(nsICacheEntryDoomCallback* listener)
 | |
| {
 | |
|   RefPtr<DoomCallbackWrapper> cb = listener
 | |
|     ? new DoomCallbackWrapper(listener)
 | |
|     : nullptr;
 | |
|   return AsyncDoom(cb);
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::GetDataSize(int64_t *aSize)
 | |
| {
 | |
|   uint32_t size;
 | |
|   nsresult rv = GetDataSize(&size);
 | |
|   if (NS_FAILED(rv))
 | |
|     return rv;
 | |
| 
 | |
|   *aSize = size;
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::GetAltDataSize(int64_t *aSize)
 | |
| {
 | |
|   return NS_ERROR_NOT_IMPLEMENTED;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::GetPersistent(bool *aPersistToDisk)
 | |
| {
 | |
|   if (!mOldDesc) {
 | |
|     return NS_ERROR_NULL_POINTER;
 | |
|   }
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   nsCacheStoragePolicy policy;
 | |
|   rv = mOldDesc->GetStoragePolicy(&policy);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   *aPersistToDisk = policy != nsICache::STORE_IN_MEMORY;
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::Recreate(bool aMemoryOnly,
 | |
|                                               nsICacheEntry** aResult)
 | |
| {
 | |
|   NS_ENSURE_TRUE(mOldDesc, NS_ERROR_NOT_AVAILABLE);
 | |
| 
 | |
|   nsCacheAccessMode mode;
 | |
|   nsresult rv = mOldDesc->GetAccessGranted(&mode);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   if (!(mode & nsICache::ACCESS_WRITE))
 | |
|     return NS_ERROR_NOT_AVAILABLE;
 | |
| 
 | |
|   LOG(("_OldCacheEntryWrapper::Recreate [this=%p]", this));
 | |
| 
 | |
|   if (aMemoryOnly)
 | |
|     mOldDesc->SetStoragePolicy(nsICache::STORE_IN_MEMORY);
 | |
| 
 | |
|   nsCOMPtr<nsICacheEntry> self(this);
 | |
|   self.forget(aResult);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::OpenInputStream(int64_t offset,
 | |
|                                                      nsIInputStream * *_retval)
 | |
| {
 | |
|   if (offset > PR_UINT32_MAX)
 | |
|     return NS_ERROR_INVALID_ARG;
 | |
| 
 | |
|   return OpenInputStream(uint32_t(offset), _retval);
 | |
| }
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::OpenOutputStream(int64_t offset,
 | |
|                                                       int64_t predictedSize,
 | |
|                                                       nsIOutputStream * *_retval)
 | |
| {
 | |
|   if (offset > PR_UINT32_MAX)
 | |
|     return NS_ERROR_INVALID_ARG;
 | |
| 
 | |
|   return OpenOutputStream(uint32_t(offset), _retval);
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::MaybeMarkValid()
 | |
| {
 | |
|   LOG(("_OldCacheEntryWrapper::MaybeMarkValid [this=%p]", this));
 | |
| 
 | |
|   NS_ENSURE_TRUE(mOldDesc, NS_ERROR_NULL_POINTER);
 | |
| 
 | |
|   nsCacheAccessMode mode;
 | |
|   nsresult rv = mOldDesc->GetAccessGranted(&mode);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   if (mode & nsICache::ACCESS_WRITE) {
 | |
|     LOG(("Marking cache entry valid [entry=%p, descr=%p]", this, mOldDesc));
 | |
|     return mOldDesc->MarkValid();
 | |
|   }
 | |
| 
 | |
|   LOG(("Not marking read-only cache entry valid [entry=%p, descr=%p]", this, mOldDesc));
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::HasWriteAccess(bool aWriteAllowed_unused, bool *aWriteAccess)
 | |
| {
 | |
|   NS_ENSURE_TRUE(mOldDesc, NS_ERROR_NULL_POINTER);
 | |
|   NS_ENSURE_ARG(aWriteAccess);
 | |
| 
 | |
|   nsCacheAccessMode mode;
 | |
|   nsresult rv = mOldDesc->GetAccessGranted(&mode);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   *aWriteAccess = !!(mode & nsICache::ACCESS_WRITE);
 | |
| 
 | |
|   LOG(("_OldCacheEntryWrapper::HasWriteAccess [this=%p, write-access=%d]", this, *aWriteAccess));
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| class MetaDataVisitorWrapper : public nsICacheMetaDataVisitor
 | |
| {
 | |
|   virtual ~MetaDataVisitorWrapper() = default;
 | |
| 
 | |
|   NS_DECL_ISUPPORTS
 | |
|   NS_DECL_NSICACHEMETADATAVISITOR
 | |
|   explicit MetaDataVisitorWrapper(nsICacheEntryMetaDataVisitor* cb) : mCB(cb) {}
 | |
|   nsCOMPtr<nsICacheEntryMetaDataVisitor> mCB;
 | |
| };
 | |
| 
 | |
| NS_IMPL_ISUPPORTS(MetaDataVisitorWrapper, nsICacheMetaDataVisitor)
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| MetaDataVisitorWrapper::VisitMetaDataElement(char const * key,
 | |
|                                              char const * value,
 | |
|                                              bool *goon)
 | |
| {
 | |
|   *goon = true;
 | |
|   return mCB->OnMetaDataElement(key, value);
 | |
| }
 | |
| 
 | |
| } // namespace
 | |
| 
 | |
| NS_IMETHODIMP _OldCacheEntryWrapper::VisitMetaData(nsICacheEntryMetaDataVisitor* cb)
 | |
| {
 | |
|   RefPtr<MetaDataVisitorWrapper> w = new MetaDataVisitorWrapper(cb);
 | |
|   return mOldDesc->VisitMetaData(w);
 | |
| }
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| nsresult
 | |
| GetCacheSessionNameForStoragePolicy(
 | |
|         const nsACString& scheme,
 | |
|         nsCacheStoragePolicy storagePolicy,
 | |
|         bool isPrivate,
 | |
|         OriginAttributes const *originAttribs,
 | |
|         nsACString& sessionName)
 | |
| {
 | |
|   MOZ_ASSERT(!isPrivate || storagePolicy == nsICache::STORE_IN_MEMORY);
 | |
| 
 | |
|   // HTTP
 | |
|   if (scheme.EqualsLiteral("http") ||
 | |
|       scheme.EqualsLiteral("https")) {
 | |
|     switch (storagePolicy) {
 | |
|     case nsICache::STORE_IN_MEMORY:
 | |
|       if (isPrivate)
 | |
|         sessionName.AssignLiteral("HTTP-memory-only-PB");
 | |
|       else
 | |
|         sessionName.AssignLiteral("HTTP-memory-only");
 | |
|       break;
 | |
|     case nsICache::STORE_OFFLINE:
 | |
|       // XXX This is actually never used, only added to prevent
 | |
|       // any compatibility damage.
 | |
|       sessionName.AssignLiteral("HTTP-offline");
 | |
|       break;
 | |
|     default:
 | |
|       sessionName.AssignLiteral("HTTP");
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   // WYCIWYG
 | |
|   else if (scheme.EqualsLiteral("wyciwyg")) {
 | |
|     if (isPrivate)
 | |
|       sessionName.AssignLiteral("wyciwyg-private");
 | |
|     else
 | |
|       sessionName.AssignLiteral("wyciwyg");
 | |
|   }
 | |
|   // FTP
 | |
|   else if (scheme.EqualsLiteral("ftp")) {
 | |
|     if (isPrivate)
 | |
|       sessionName.AssignLiteral("FTP-private");
 | |
|     else
 | |
|       sessionName.AssignLiteral("FTP");
 | |
|   }
 | |
|   // all remaining URL scheme
 | |
|   else {
 | |
|     // Since with the new API a consumer cannot specify its own session name
 | |
|     // and partitioning of the cache is handled stricly only by the cache
 | |
|     // back-end internally, we will use a separate session name to pretend
 | |
|     // functionality of the new API wrapping the Darin's cache for all other
 | |
|     // URL schemes.
 | |
|     // Deliberately omitting |anonymous| since other session types don't
 | |
|     // recognize it too.
 | |
|     sessionName.AssignLiteral("other");
 | |
|     if (isPrivate)
 | |
|       sessionName.AppendLiteral("-private");
 | |
|   }
 | |
| 
 | |
|   nsAutoCString suffix;
 | |
|   originAttribs->CreateSuffix(suffix);
 | |
|   sessionName.Append(suffix);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| nsresult
 | |
| GetCacheSession(const nsACString& aScheme,
 | |
|                 bool aWriteToDisk,
 | |
|                 nsILoadContextInfo* aLoadInfo,
 | |
|                 nsIApplicationCache* aAppCache,
 | |
|                 nsICacheSession** _result)
 | |
| {
 | |
|   nsresult rv;
 | |
| 
 | |
|   nsCacheStoragePolicy storagePolicy;
 | |
|   if (aAppCache)
 | |
|     storagePolicy = nsICache::STORE_OFFLINE;
 | |
|   else if (!aWriteToDisk || aLoadInfo->IsPrivate())
 | |
|     storagePolicy = nsICache::STORE_IN_MEMORY;
 | |
|   else
 | |
|     storagePolicy = nsICache::STORE_ANYWHERE;
 | |
| 
 | |
|   nsAutoCString clientId;
 | |
|   if (aAppCache) {
 | |
|     aAppCache->GetClientID(clientId);
 | |
|   }
 | |
|   else {
 | |
|     rv = GetCacheSessionNameForStoragePolicy(
 | |
|       aScheme,
 | |
|       storagePolicy,
 | |
|       aLoadInfo->IsPrivate(),
 | |
|       aLoadInfo->OriginAttributesPtr(),
 | |
|       clientId);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
|   }
 | |
| 
 | |
|   LOG(("  GetCacheSession for client=%s, policy=%d", clientId.get(), storagePolicy));
 | |
| 
 | |
|   nsCOMPtr<nsICacheService> serv =
 | |
|       do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   nsCOMPtr<nsICacheSession> session;
 | |
|   rv = nsCacheService::GlobalInstance()->CreateSessionInternal(clientId.get(),
 | |
|                                                                storagePolicy,
 | |
|                                                                nsICache::STREAM_BASED,
 | |
|                                                                getter_AddRefs(session));
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   rv = session->SetIsPrivate(aLoadInfo->IsPrivate());
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   rv = session->SetDoomEntriesIfExpired(false);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   if (aAppCache) {
 | |
|     nsCOMPtr<nsIFile> profileDirectory;
 | |
|     aAppCache->GetProfileDirectory(getter_AddRefs(profileDirectory));
 | |
|     if (profileDirectory)
 | |
|       rv = session->SetProfileDirectory(profileDirectory);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
|   }
 | |
| 
 | |
|   session.forget(_result);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| } // namespace
 | |
| 
 | |
| 
 | |
| NS_IMPL_ISUPPORTS_INHERITED(_OldCacheLoad, Runnable, nsICacheListener)
 | |
| 
 | |
| _OldCacheLoad::_OldCacheLoad(const nsACString& aScheme,
 | |
|                              const nsACString& aCacheKey,
 | |
|                              nsICacheEntryOpenCallback* aCallback,
 | |
|                              nsIApplicationCache* aAppCache,
 | |
|                              nsILoadContextInfo* aLoadInfo,
 | |
|                              bool aWriteToDisk,
 | |
|                              uint32_t aFlags)
 | |
|   : Runnable("net::_OldCacheLoad")
 | |
|   , mScheme(aScheme)
 | |
|   , mCacheKey(aCacheKey)
 | |
|   , mCallback(aCallback)
 | |
|   , mLoadInfo(GetLoadContextInfo(aLoadInfo))
 | |
|   , mFlags(aFlags)
 | |
|   , mWriteToDisk(aWriteToDisk)
 | |
|   , mNew(true)
 | |
|   , mOpening(true)
 | |
|   , mSync(false)
 | |
|   , mStatus(NS_ERROR_UNEXPECTED)
 | |
|   , mRunCount(0)
 | |
|   , mAppCache(aAppCache)
 | |
| {
 | |
| }
 | |
| 
 | |
| _OldCacheLoad::~_OldCacheLoad()
 | |
| {
 | |
|   ProxyReleaseMainThread(
 | |
|     "_OldCacheLoad::mAppCache", mAppCache);
 | |
| }
 | |
| 
 | |
| nsresult _OldCacheLoad::Start()
 | |
| {
 | |
|   LOG(("_OldCacheLoad::Start [this=%p, key=%s]", this, mCacheKey.get()));
 | |
| 
 | |
|   mLoadStart = mozilla::TimeStamp::Now();
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   // Consumers that can invoke this code as first and off the main thread
 | |
|   // are responsible for initiating these two services on the main thread.
 | |
|   // Currently this is only nsWyciwygChannel.
 | |
| 
 | |
|   // XXX: Start the cache service; otherwise DispatchToCacheIOThread will
 | |
|   // fail.
 | |
|   nsCOMPtr<nsICacheService> service =
 | |
|     do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
 | |
| 
 | |
|   // Ensure the stream transport service gets initialized on the main thread
 | |
|   if (NS_SUCCEEDED(rv) && NS_IsMainThread()) {
 | |
|     nsCOMPtr<nsIStreamTransportService> sts =
 | |
|       do_GetService(kStreamTransportServiceCID, &rv);
 | |
|   }
 | |
| 
 | |
|   if (NS_SUCCEEDED(rv)) {
 | |
|     rv = service->GetCacheIOTarget(getter_AddRefs(mCacheThread));
 | |
|   }
 | |
| 
 | |
|   if (NS_SUCCEEDED(rv)) {
 | |
|     bool onCacheTarget;
 | |
|     rv = mCacheThread->IsOnCurrentThread(&onCacheTarget);
 | |
|     if (NS_SUCCEEDED(rv) && onCacheTarget) {
 | |
|       mSync = true;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (NS_SUCCEEDED(rv)) {
 | |
|     if (mSync) {
 | |
|       rv = Run();
 | |
|     }
 | |
|     else {
 | |
|       rv = mCacheThread->Dispatch(this, NS_DISPATCH_NORMAL);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return rv;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| _OldCacheLoad::Run()
 | |
| {
 | |
|   LOG(("_OldCacheLoad::Run [this=%p, key=%s, cb=%p]", this, mCacheKey.get(), mCallback.get()));
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   if (mOpening) {
 | |
|     mOpening = false;
 | |
|     nsCOMPtr<nsICacheSession> session;
 | |
|     rv = GetCacheSession(mScheme, mWriteToDisk, mLoadInfo, mAppCache,
 | |
|                          getter_AddRefs(session));
 | |
|     if (NS_SUCCEEDED(rv)) {
 | |
|       // AsyncOpenCacheEntry isn't really async when its called on the
 | |
|       // cache service thread.
 | |
| 
 | |
|       nsCacheAccessMode cacheAccess;
 | |
|       if (mFlags & nsICacheStorage::OPEN_TRUNCATE)
 | |
|         cacheAccess = nsICache::ACCESS_WRITE;
 | |
|       else if ((mFlags & nsICacheStorage::OPEN_READONLY) || mAppCache)
 | |
|         cacheAccess = nsICache::ACCESS_READ;
 | |
|       else
 | |
|         cacheAccess = nsICache::ACCESS_READ_WRITE;
 | |
| 
 | |
|       LOG(("  session->AsyncOpenCacheEntry with access=%d", cacheAccess));
 | |
| 
 | |
|       bool bypassBusy = mFlags & nsICacheStorage::OPEN_BYPASS_IF_BUSY;
 | |
| 
 | |
|       if (mSync && cacheAccess == nsICache::ACCESS_WRITE) {
 | |
|         nsCOMPtr<nsICacheEntryDescriptor> entry;
 | |
|         rv = session->OpenCacheEntry(mCacheKey, cacheAccess, bypassBusy,
 | |
|           getter_AddRefs(entry));
 | |
| 
 | |
|         nsCacheAccessMode grantedAccess = 0;
 | |
|         if (NS_SUCCEEDED(rv)) {
 | |
|           entry->GetAccessGranted(&grantedAccess);
 | |
|         }
 | |
| 
 | |
|         return OnCacheEntryAvailable(entry, grantedAccess, rv);
 | |
|       }
 | |
| 
 | |
|       rv = session->AsyncOpenCacheEntry(mCacheKey, cacheAccess, this, bypassBusy);
 | |
|       if (NS_SUCCEEDED(rv))
 | |
|         return NS_OK;
 | |
|     }
 | |
| 
 | |
|     // Opening failed, propagate the error to the consumer
 | |
|     LOG(("  Opening cache entry failed with rv=0x%08" PRIx32, static_cast<uint32_t>(rv)));
 | |
|     mStatus = rv;
 | |
|     mNew = false;
 | |
|     NS_DispatchToMainThread(this);
 | |
|   } else {
 | |
|     if (!mCallback) {
 | |
|       LOG(("  duplicate call, bypassed"));
 | |
|       return NS_OK;
 | |
|     }
 | |
| 
 | |
|     if (NS_SUCCEEDED(mStatus)) {
 | |
|       if (mFlags & nsICacheStorage::OPEN_TRUNCATE) {
 | |
|         mozilla::Telemetry::AccumulateTimeDelta(
 | |
|           mozilla::Telemetry::NETWORK_CACHE_V1_TRUNCATE_TIME_MS,
 | |
|           mLoadStart);
 | |
|       }
 | |
|       else if (mNew) {
 | |
|         mozilla::Telemetry::AccumulateTimeDelta(
 | |
|           mozilla::Telemetry::NETWORK_CACHE_V1_MISS_TIME_MS,
 | |
|           mLoadStart);
 | |
|       }
 | |
|       else {
 | |
|         mozilla::Telemetry::AccumulateTimeDelta(
 | |
|           mozilla::Telemetry::NETWORK_CACHE_V1_HIT_TIME_MS,
 | |
|           mLoadStart);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (!(mFlags & CHECK_MULTITHREADED))
 | |
|       Check();
 | |
| 
 | |
|     // break cycles
 | |
|     nsCOMPtr<nsICacheEntryOpenCallback> cb = mCallback.forget();
 | |
|     mCacheThread = nullptr;
 | |
|     nsCOMPtr<nsICacheEntry> entry = mCacheEntry.forget();
 | |
| 
 | |
|     rv = cb->OnCacheEntryAvailable(entry, mNew, mAppCache, mStatus);
 | |
| 
 | |
|     if (NS_FAILED(rv) && entry) {
 | |
|       LOG(("  cb->OnCacheEntryAvailable failed with rv=0x%08" PRIx32,
 | |
|            static_cast<uint32_t>(rv)));
 | |
|       if (mNew)
 | |
|         entry->AsyncDoom(nullptr);
 | |
|       else
 | |
|         entry->Close();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return rv;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| _OldCacheLoad::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry,
 | |
|                                      nsCacheAccessMode access,
 | |
|                                      nsresult status)
 | |
| {
 | |
|   LOG(("_OldCacheLoad::OnCacheEntryAvailable [this=%p, ent=%p, cb=%p, appcache=%p, access=%x]",
 | |
|     this, entry, mCallback.get(), mAppCache.get(), access));
 | |
| 
 | |
|   // XXX Bug 759805: Sometimes we will call this method directly from
 | |
|   // HttpCacheQuery::Run when AsyncOpenCacheEntry fails, but
 | |
|   // AsyncOpenCacheEntry will also call this method. As a workaround, we just
 | |
|   // ensure we only execute this code once.
 | |
|   NS_ENSURE_TRUE(mRunCount == 0, NS_ERROR_UNEXPECTED);
 | |
|   ++mRunCount;
 | |
| 
 | |
|   mCacheEntry = entry ? new _OldCacheEntryWrapper(entry) : nullptr;
 | |
|   mStatus = status;
 | |
|   mNew = access == nsICache::ACCESS_WRITE;
 | |
| 
 | |
|   if (mFlags & CHECK_MULTITHREADED)
 | |
|     Check();
 | |
| 
 | |
|   if (mSync)
 | |
|     return Run();
 | |
| 
 | |
|   return NS_DispatchToMainThread(this);
 | |
| }
 | |
| 
 | |
| void
 | |
| _OldCacheLoad::Check()
 | |
| {
 | |
|   if (!mCacheEntry)
 | |
|     return;
 | |
| 
 | |
|   if (mNew)
 | |
|     return;
 | |
| 
 | |
|   uint32_t result;
 | |
|   nsresult rv = mCallback->OnCacheEntryCheck(mCacheEntry, mAppCache, &result);
 | |
|   LOG(("  OnCacheEntryCheck result ent=%p, cb=%p, appcache=%p, rv=0x%08"
 | |
|        PRIx32 ", result=%d",
 | |
|       mCacheEntry.get(), mCallback.get(), mAppCache.get(), static_cast<uint32_t>(rv),
 | |
|       result));
 | |
| 
 | |
|   if (NS_FAILED(rv)) {
 | |
|     NS_WARNING("cache check failed");
 | |
|   }
 | |
| 
 | |
|   if (NS_FAILED(rv) || result == nsICacheEntryOpenCallback::ENTRY_NOT_WANTED) {
 | |
|     mCacheEntry->Close();
 | |
|     mCacheEntry = nullptr;
 | |
|     mStatus = NS_ERROR_CACHE_KEY_NOT_FOUND;
 | |
|   }
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| _OldCacheLoad::OnCacheEntryDoomed(nsresult)
 | |
| {
 | |
|   return NS_ERROR_NOT_IMPLEMENTED;
 | |
| }
 | |
| 
 | |
| // nsICacheStorage old cache wrapper
 | |
| 
 | |
| NS_IMPL_ISUPPORTS(_OldStorage, nsICacheStorage)
 | |
| 
 | |
| _OldStorage::_OldStorage(nsILoadContextInfo* aInfo,
 | |
|                          bool aAllowDisk,
 | |
|                          bool aLookupAppCache,
 | |
|                          bool aOfflineStorage,
 | |
|                          nsIApplicationCache* aAppCache)
 | |
| : mLoadInfo(GetLoadContextInfo(aInfo))
 | |
| , mAppCache(aAppCache)
 | |
| , mWriteToDisk(aAllowDisk)
 | |
| , mLookupAppCache(aLookupAppCache)
 | |
| , mOfflineStorage(aOfflineStorage)
 | |
| {
 | |
| }
 | |
| 
 | |
| _OldStorage::~_OldStorage() = default;
 | |
| 
 | |
| NS_IMETHODIMP _OldStorage::AsyncOpenURI(nsIURI *aURI,
 | |
|                                         const nsACString & aIdExtension,
 | |
|                                         uint32_t aFlags,
 | |
|                                         nsICacheEntryOpenCallback *aCallback)
 | |
| {
 | |
|   NS_ENSURE_ARG(aURI);
 | |
|   NS_ENSURE_ARG(aCallback);
 | |
| 
 | |
| #ifdef MOZ_LOGGING
 | |
|   nsAutoCString uriSpec;
 | |
|   aURI->GetAsciiSpec(uriSpec);
 | |
|   LOG(("_OldStorage::AsyncOpenURI [this=%p, uri=%s, ide=%s, flags=%x]",
 | |
|     this, uriSpec.get(), aIdExtension.BeginReading(), aFlags));
 | |
| #endif
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   nsAutoCString cacheKey, scheme;
 | |
|   rv = AssembleCacheKey(aURI, aIdExtension, cacheKey, scheme);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   if (!mAppCache && (mLookupAppCache || mOfflineStorage)) {
 | |
|     rv = ChooseApplicationCache(cacheKey, getter_AddRefs(mAppCache));
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     if (mAppCache) {
 | |
|       // From a chosen appcache open only as readonly
 | |
|       aFlags &= ~nsICacheStorage::OPEN_TRUNCATE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   RefPtr<_OldCacheLoad> cacheLoad =
 | |
|     new _OldCacheLoad(scheme, cacheKey, aCallback, mAppCache,
 | |
|                       mLoadInfo, mWriteToDisk, aFlags);
 | |
| 
 | |
|   rv = cacheLoad->Start();
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldStorage::OpenTruncate(nsIURI *aURI, const nsACString & aIdExtension,
 | |
|                                         nsICacheEntry **aCacheEntry)
 | |
| {
 | |
|   return NS_ERROR_NOT_IMPLEMENTED;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldStorage::Exists(nsIURI *aURI, const nsACString & aIdExtension,
 | |
|                                    bool *aResult)
 | |
| {
 | |
|   return NS_ERROR_NOT_AVAILABLE;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldStorage::AsyncDoomURI(nsIURI *aURI, const nsACString & aIdExtension,
 | |
|                                         nsICacheEntryDoomCallback* aCallback)
 | |
| {
 | |
|   LOG(("_OldStorage::AsyncDoomURI"));
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   nsAutoCString cacheKey, scheme;
 | |
|   rv = AssembleCacheKey(aURI, aIdExtension, cacheKey, scheme);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   nsCOMPtr<nsICacheSession> session;
 | |
|   rv = GetCacheSession(scheme, mWriteToDisk, mLoadInfo, mAppCache,
 | |
|                        getter_AddRefs(session));
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   RefPtr<DoomCallbackWrapper> cb = aCallback
 | |
|     ? new DoomCallbackWrapper(aCallback)
 | |
|     : nullptr;
 | |
|   rv = session->DoomEntry(cacheKey, cb);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldStorage::AsyncEvictStorage(nsICacheEntryDoomCallback* aCallback)
 | |
| {
 | |
|   LOG(("_OldStorage::AsyncEvictStorage"));
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   if (!mAppCache && mOfflineStorage) {
 | |
|     nsCOMPtr<nsIApplicationCacheService> appCacheService =
 | |
|       do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     rv = appCacheService->Evict(mLoadInfo);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
|   } else if (mAppCache) {
 | |
|     nsCOMPtr<nsICacheSession> session;
 | |
|     rv = GetCacheSession(EmptyCString(),
 | |
|                           mWriteToDisk, mLoadInfo, mAppCache,
 | |
|                           getter_AddRefs(session));
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     rv = session->EvictEntries();
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
|   } else {
 | |
|     // Oh, I'll be so happy when session names are gone...
 | |
|     nsCOMPtr<nsICacheSession> session;
 | |
|     rv = GetCacheSession(NS_LITERAL_CSTRING("http"),
 | |
|                           mWriteToDisk, mLoadInfo, mAppCache,
 | |
|                           getter_AddRefs(session));
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     rv = session->EvictEntries();
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     rv = GetCacheSession(NS_LITERAL_CSTRING("wyciwyg"),
 | |
|                           mWriteToDisk, mLoadInfo, mAppCache,
 | |
|                           getter_AddRefs(session));
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     rv = session->EvictEntries();
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     // This clears any data from scheme other then http, wyciwyg or ftp
 | |
|     rv = GetCacheSession(EmptyCString(),
 | |
|                           mWriteToDisk, mLoadInfo, mAppCache,
 | |
|                           getter_AddRefs(session));
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     rv = session->EvictEntries();
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
|   }
 | |
| 
 | |
|   if (aCallback) {
 | |
|     RefPtr<DoomCallbackSynchronizer> sync =
 | |
|       new DoomCallbackSynchronizer(aCallback);
 | |
|     rv = sync->Dispatch();
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldStorage::AsyncVisitStorage(nsICacheStorageVisitor* aVisitor,
 | |
|                                              bool aVisitEntries)
 | |
| {
 | |
|   LOG(("_OldStorage::AsyncVisitStorage"));
 | |
| 
 | |
|   NS_ENSURE_ARG(aVisitor);
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   nsCOMPtr<nsICacheService> serv =
 | |
|     do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   char* deviceID;
 | |
|   if (mAppCache || mOfflineStorage) {
 | |
|     deviceID = const_cast<char*>("offline");
 | |
|   } else if (!mWriteToDisk || mLoadInfo->IsPrivate()) {
 | |
|     deviceID = const_cast<char*>("memory");
 | |
|   } else {
 | |
|     deviceID = const_cast<char*>("disk");
 | |
|   }
 | |
| 
 | |
|   RefPtr<_OldVisitCallbackWrapper> cb = new _OldVisitCallbackWrapper(
 | |
|     deviceID, aVisitor, aVisitEntries, mLoadInfo);
 | |
|   rv = nsCacheService::GlobalInstance()->VisitEntriesInternal(cb);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP _OldStorage::GetCacheIndexEntryAttrs(nsIURI *aURI,
 | |
|                                                    const nsACString &aIdExtension,
 | |
|                                                    bool *aHasAltData,
 | |
|                                                    uint32_t *aSizeInKB)
 | |
| {
 | |
|   return NS_ERROR_NOT_IMPLEMENTED;
 | |
| }
 | |
| 
 | |
| // Internal
 | |
| 
 | |
| nsresult _OldStorage::AssembleCacheKey(nsIURI *aURI,
 | |
|                                        nsACString const & aIdExtension,
 | |
|                                        nsACString & aCacheKey,
 | |
|                                        nsACString & aScheme)
 | |
| {
 | |
|   // Copied from nsHttpChannel::AssembleCacheKey
 | |
| 
 | |
|   aCacheKey.Truncate();
 | |
| 
 | |
|   nsresult rv;
 | |
| 
 | |
|   rv = aURI->GetScheme(aScheme);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   nsAutoCString uriSpec;
 | |
|   if (aScheme.EqualsLiteral("http") ||
 | |
|       aScheme.EqualsLiteral("https")) {
 | |
|     if (mLoadInfo->IsAnonymous()) {
 | |
|       aCacheKey.AssignLiteral("anon&");
 | |
|     }
 | |
| 
 | |
|     if (!aIdExtension.IsEmpty()) {
 | |
|       aCacheKey.AppendPrintf("id=%s&", aIdExtension.BeginReading());
 | |
|     }
 | |
| 
 | |
|     nsCOMPtr<nsIURI> noRefURI;
 | |
|     rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     rv = noRefURI->GetAsciiSpec(uriSpec);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|     if (!aCacheKey.IsEmpty()) {
 | |
|       aCacheKey.AppendLiteral("uri=");
 | |
|     }
 | |
|   }
 | |
|   else if (aScheme.EqualsLiteral("wyciwyg")) {
 | |
|     rv = aURI->GetSpec(uriSpec);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
|   }
 | |
|   else {
 | |
|     rv = aURI->GetAsciiSpec(uriSpec);
 | |
|     NS_ENSURE_SUCCESS(rv, rv);
 | |
|   }
 | |
| 
 | |
|   aCacheKey.Append(uriSpec);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| nsresult _OldStorage::ChooseApplicationCache(const nsACString& cacheKey,
 | |
|                                              nsIApplicationCache** aCache)
 | |
| {
 | |
|   nsresult rv;
 | |
| 
 | |
|   nsCOMPtr<nsIApplicationCacheService> appCacheService =
 | |
|     do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   rv = appCacheService->ChooseApplicationCache(cacheKey, mLoadInfo, aCache);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| } // namespace net
 | |
| } // namespace mozilla
 |