From 35df656ad7abda42f4c66f5da0e87ec60bf0692f Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Tue, 17 May 2016 05:20:00 -0400 Subject: [PATCH] Bug 1266196 - Make about:cache handler be multiple-instance capable. r=michal --- netwerk/protocol/about/nsAboutCache.cpp | 51 +++++---- netwerk/protocol/about/nsAboutCache.h | 83 +++++++++------ netwerk/protocol/about/nsAboutCacheEntry.cpp | 105 +++++++++++-------- netwerk/protocol/about/nsAboutCacheEntry.h | 92 +++++++++------- 4 files changed, 197 insertions(+), 134 deletions(-) diff --git a/netwerk/protocol/about/nsAboutCache.cpp b/netwerk/protocol/about/nsAboutCache.cpp index 2ab2e719d52f..c354b3931a9e 100644 --- a/netwerk/protocol/about/nsAboutCache.cpp +++ b/netwerk/protocol/about/nsAboutCache.cpp @@ -25,18 +25,31 @@ using namespace mozilla::net; -NS_IMPL_ISUPPORTS(nsAboutCache, nsIAboutModule, nsICacheStorageVisitor) +NS_IMPL_ISUPPORTS(nsAboutCache, nsIAboutModule) +NS_IMPL_ISUPPORTS(nsAboutCache::Channel, nsIChannel, nsIRequest, nsICacheStorageVisitor) NS_IMETHODIMP nsAboutCache::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo, nsIChannel** result) { - NS_ENSURE_ARG_POINTER(aURI); - nsresult rv; - *result = nullptr; + NS_ENSURE_ARG_POINTER(aURI); + + RefPtr channel = new Channel(); + rv = channel->Init(aURI, aLoadInfo); + if (NS_FAILED(rv)) return rv; + + channel.forget(result); + + return NS_OK; +} + +nsresult +nsAboutCache::Channel::Init(nsIURI* aURI, nsILoadInfo* aLoadInfo) +{ + nsresult rv; nsCOMPtr inputStream; rv = NS_NewPipe(getter_AddRefs(inputStream), getter_AddRefs(mStream), @@ -64,8 +77,7 @@ nsAboutCache::NewChannel(nsIURI* aURI, // The entries header is added on encounter of the first entry mEntriesHeaderAdded = false; - nsCOMPtr channel; - rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), + rv = NS_NewInputStreamChannelInternal(getter_AddRefs(mChannel), aURI, inputStream, NS_LITERAL_CSTRING("text/html"), @@ -121,12 +133,11 @@ nsAboutCache::NewChannel(nsIURI* aURI, rv = VisitNextStorage(); if (NS_FAILED(rv)) return rv; - channel.forget(result); return NS_OK; } nsresult -nsAboutCache::ParseURI(nsIURI * uri, nsACString & storage) +nsAboutCache::Channel::ParseURI(nsIURI * uri, nsACString & storage) { // // about:cache[?storage=[&context=]] @@ -167,7 +178,7 @@ nsAboutCache::ParseURI(nsIURI * uri, nsACString & storage) } nsresult -nsAboutCache::VisitNextStorage() +nsAboutCache::Channel::VisitNextStorage() { if (!mStorageList.Length()) return NS_ERROR_NOT_AVAILABLE; @@ -179,11 +190,11 @@ nsAboutCache::VisitNextStorage() // from visitor callback. The cache v1 service doesn't like it. // TODO - mayhemer, bug 913828, remove this dispatch and call // directly. - return NS_DispatchToMainThread(mozilla::NewRunnableMethod(this, &nsAboutCache::FireVisitStorage)); + return NS_DispatchToMainThread(mozilla::NewRunnableMethod(this, &nsAboutCache::Channel::FireVisitStorage)); } void -nsAboutCache::FireVisitStorage() +nsAboutCache::Channel::FireVisitStorage() { nsresult rv; @@ -212,7 +223,7 @@ nsAboutCache::FireVisitStorage() } nsresult -nsAboutCache::VisitStorage(nsACString const & storageName) +nsAboutCache::Channel::VisitStorage(nsACString const & storageName) { nsresult rv; @@ -257,8 +268,8 @@ nsAboutCache::GetStorage(nsACString const & storageName, } NS_IMETHODIMP -nsAboutCache::OnCacheStorageInfo(uint32_t aEntryCount, uint64_t aConsumption, - uint64_t aCapacity, nsIFile * aDirectory) +nsAboutCache::Channel::OnCacheStorageInfo(uint32_t aEntryCount, uint64_t aConsumption, + uint64_t aCapacity, nsIFile * aDirectory) { // We need mStream for this if (!mStream) { @@ -342,10 +353,10 @@ nsAboutCache::OnCacheStorageInfo(uint32_t aEntryCount, uint64_t aConsumption, } NS_IMETHODIMP -nsAboutCache::OnCacheEntryInfo(nsIURI *aURI, const nsACString & aIdEnhance, - int64_t aDataSize, int32_t aFetchCount, - uint32_t aLastModified, uint32_t aExpirationTime, - bool aPinned) +nsAboutCache::Channel::OnCacheEntryInfo(nsIURI *aURI, const nsACString & aIdEnhance, + int64_t aDataSize, int32_t aFetchCount, + uint32_t aLastModified, uint32_t aExpirationTime, + bool aPinned) { // We need mStream for this if (!mStream) { @@ -464,7 +475,7 @@ nsAboutCache::OnCacheEntryInfo(nsIURI *aURI, const nsACString & aIdEnhance, } NS_IMETHODIMP -nsAboutCache::OnCacheEntryVisitCompleted() +nsAboutCache::Channel::OnCacheEntryVisitCompleted() { if (!mStream) { return NS_ERROR_FAILURE; @@ -493,7 +504,7 @@ nsAboutCache::OnCacheEntryVisitCompleted() } void -nsAboutCache::FlushBuffer() +nsAboutCache::Channel::FlushBuffer() { uint32_t bytesWritten; mStream->Write(mBuffer.get(), mBuffer.Length(), &bytesWritten); diff --git a/netwerk/protocol/about/nsAboutCache.h b/netwerk/protocol/about/nsAboutCache.h index 494fbdd6c299..a197c1f5e789 100644 --- a/netwerk/protocol/about/nsAboutCache.h +++ b/netwerk/protocol/about/nsAboutCache.h @@ -18,12 +18,10 @@ #include "nsTArray.h" class nsAboutCache final : public nsIAboutModule - , public nsICacheStorageVisitor { public: NS_DECL_ISUPPORTS NS_DECL_NSIABOUTMODULE - NS_DECL_NSICACHESTORAGEVISITOR nsAboutCache() {} @@ -37,45 +35,62 @@ public: protected: virtual ~nsAboutCache() {} - nsresult ParseURI(nsIURI * uri, nsACString & storage); + class Channel final : public nsIChannel + , public nsICacheStorageVisitor + { + NS_DECL_ISUPPORTS + NS_DECL_NSICACHESTORAGEVISITOR + NS_FORWARD_SAFE_NSICHANNEL(mChannel) + NS_FORWARD_SAFE_NSIREQUEST(mChannel) - // Finds a next storage we wish to visit (we use this method - // even there is a specified storage name, which is the only - // one in the list then.) Posts FireVisitStorage() when found. - nsresult VisitNextStorage(); - // Helper method that calls VisitStorage() for the current storage. - // When it fails, OnCacheEntryVisitCompleted is simlated to close - // the output stream and thus the about:cache channel. - void FireVisitStorage(); - // Kiks the visit cycle for the given storage, names can be: - // "disk", "memory", "appcache" - // Note: any newly added storage type has to be manually handled here. - nsresult VisitStorage(nsACString const & storageName); + private: + virtual ~Channel() {} - // Writes content of mBuffer to mStream and truncates - // the buffer. - void FlushBuffer(); + public: + nsresult Init(nsIURI* aURI, nsILoadInfo* aLoadInfo); + nsresult ParseURI(nsIURI * uri, nsACString & storage); - // Whether we are showing overview status of all available - // storages. - bool mOverview; + // Finds a next storage we wish to visit (we use this method + // even there is a specified storage name, which is the only + // one in the list then.) Posts FireVisitStorage() when found. + nsresult VisitNextStorage(); + // Helper method that calls VisitStorage() for the current storage. + // When it fails, OnCacheEntryVisitCompleted is simlated to close + // the output stream and thus the about:cache channel. + void FireVisitStorage(); + // Kiks the visit cycle for the given storage, names can be: + // "disk", "memory", "appcache" + // Note: any newly added storage type has to be manually handled here. + nsresult VisitStorage(nsACString const & storageName); - // Flag initially false, that indicates the entries header has - // been added to the output HTML. - bool mEntriesHeaderAdded; + // Writes content of mBuffer to mStream and truncates + // the buffer. + void FlushBuffer(); - // The context we are working with. - nsCOMPtr mLoadInfo; - nsCString mContextString; + // Whether we are showing overview status of all available + // storages. + bool mOverview; - // The list of all storage names we want to visit - nsTArray mStorageList; - nsCString mStorageName; - nsCOMPtr mStorage; + // Flag initially false, that indicates the entries header has + // been added to the output HTML. + bool mEntriesHeaderAdded; - // Output data buffering and streaming output - nsCString mBuffer; - nsCOMPtr mStream; + // The context we are working with. + nsCOMPtr mLoadInfo; + nsCString mContextString; + + // The list of all storage names we want to visit + nsTArray mStorageList; + nsCString mStorageName; + nsCOMPtr mStorage; + + // Output data buffering and streaming output + nsCString mBuffer; + nsCOMPtr mStream; + + // The input stream channel, the one that actually does the job + nsCOMPtr mChannel; + }; }; #define NS_ABOUT_CACHE_MODULE_CID \ diff --git a/netwerk/protocol/about/nsAboutCacheEntry.cpp b/netwerk/protocol/about/nsAboutCacheEntry.cpp index 2587b0866d00..05d0c70fc59d 100644 --- a/netwerk/protocol/about/nsAboutCacheEntry.cpp +++ b/netwerk/protocol/about/nsAboutCacheEntry.cpp @@ -81,10 +81,12 @@ HexDump(uint32_t *state, const char *buf, int32_t n, nsCString &result) // nsAboutCacheEntry::nsISupports NS_IMPL_ISUPPORTS(nsAboutCacheEntry, - nsIAboutModule, + nsIAboutModule) +NS_IMPL_ISUPPORTS(nsAboutCacheEntry::Channel, nsICacheEntryOpenCallback, nsICacheEntryMetaDataVisitor, - nsIStreamListener) + nsIStreamListener, + nsIChannel) //----------------------------------------------------------------------------- // nsAboutCacheEntry::nsIAboutModule @@ -97,15 +99,13 @@ nsAboutCacheEntry::NewChannel(nsIURI* uri, NS_ENSURE_ARG_POINTER(uri); nsresult rv; - nsCOMPtr stream; - rv = GetContentStream(uri, getter_AddRefs(stream)); + RefPtr channel = new Channel(); + rv = channel->Init(uri, aLoadInfo); if (NS_FAILED(rv)) return rv; - return NS_NewInputStreamChannelInternal(result, - uri, - stream, - NS_LITERAL_CSTRING("text/html"), - NS_LITERAL_CSTRING("utf-8"), - aLoadInfo); + + channel.forget(result); + + return NS_OK; } NS_IMETHODIMP @@ -123,10 +123,30 @@ nsAboutCacheEntry::GetIndexedDBOriginPostfix(nsIURI *aURI, nsAString &result) } //----------------------------------------------------------------------------- -// nsAboutCacheEntry +// nsAboutCacheEntry::Channel nsresult -nsAboutCacheEntry::GetContentStream(nsIURI *uri, nsIInputStream **result) +nsAboutCacheEntry::Channel::Init(nsIURI* uri, nsILoadInfo* aLoadInfo) +{ + nsresult rv; + + nsCOMPtr stream; + rv = GetContentStream(uri, getter_AddRefs(stream)); + if (NS_FAILED(rv)) return rv; + + rv = NS_NewInputStreamChannelInternal(getter_AddRefs(mChannel), + uri, + stream, + NS_LITERAL_CSTRING("text/html"), + NS_LITERAL_CSTRING("utf-8"), + aLoadInfo); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + +nsresult +nsAboutCacheEntry::Channel::GetContentStream(nsIURI *uri, nsIInputStream **result) { nsresult rv; @@ -164,7 +184,7 @@ nsAboutCacheEntry::GetContentStream(nsIURI *uri, nsIInputStream **result) } nsresult -nsAboutCacheEntry::OpenCacheEntry(nsIURI *uri) +nsAboutCacheEntry::Channel::OpenCacheEntry(nsIURI *uri) { nsresult rv; @@ -184,7 +204,7 @@ nsAboutCacheEntry::OpenCacheEntry(nsIURI *uri) } nsresult -nsAboutCacheEntry::OpenCacheEntry() +nsAboutCacheEntry::Channel::OpenCacheEntry() { nsresult rv; @@ -201,11 +221,11 @@ nsAboutCacheEntry::OpenCacheEntry() } nsresult -nsAboutCacheEntry::ParseURI(nsIURI *uri, - nsACString &storageName, - nsILoadContextInfo **loadInfo, - nsCString &enahnceID, - nsIURI **cacheUri) +nsAboutCacheEntry::Channel::ParseURI(nsIURI *uri, + nsACString &storageName, + nsILoadContextInfo **loadInfo, + nsCString &enahnceID, + nsIURI **cacheUri) { // // about:cache-entry?storage=[string]&contenxt=[string]&eid=[string]&uri=[string] @@ -270,19 +290,19 @@ nsAboutCacheEntry::ParseURI(nsIURI *uri, //----------------------------------------------------------------------------- NS_IMETHODIMP -nsAboutCacheEntry::OnCacheEntryCheck(nsICacheEntry *aEntry, - nsIApplicationCache *aApplicationCache, - uint32_t *result) +nsAboutCacheEntry::Channel::OnCacheEntryCheck(nsICacheEntry *aEntry, + nsIApplicationCache *aApplicationCache, + uint32_t *result) { *result = nsICacheEntryOpenCallback::ENTRY_WANTED; return NS_OK; } NS_IMETHODIMP -nsAboutCacheEntry::OnCacheEntryAvailable(nsICacheEntry *entry, - bool isNew, - nsIApplicationCache *aApplicationCache, - nsresult status) +nsAboutCacheEntry::Channel::OnCacheEntryAvailable(nsICacheEntry *entry, + bool isNew, + nsIApplicationCache *aApplicationCache, + nsresult status) { nsresult rv; @@ -334,7 +354,7 @@ nsAboutCacheEntry::OnCacheEntryAvailable(nsICacheEntry *entry, PR_END_MACRO nsresult -nsAboutCacheEntry::WriteCacheEntryDescription(nsICacheEntry *entry) +nsAboutCacheEntry::Channel::WriteCacheEntryDescription(nsICacheEntry *entry) { nsresult rv; nsCString buffer; @@ -484,7 +504,7 @@ nsAboutCacheEntry::WriteCacheEntryDescription(nsICacheEntry *entry) } nsresult -nsAboutCacheEntry::WriteCacheEntryUnavailable() +nsAboutCacheEntry::Channel::WriteCacheEntryUnavailable() { uint32_t n; NS_NAMED_LITERAL_CSTRING(buffer, @@ -498,7 +518,7 @@ nsAboutCacheEntry::WriteCacheEntryUnavailable() //----------------------------------------------------------------------------- NS_IMETHODIMP -nsAboutCacheEntry::OnMetaDataElement(char const * key, char const * value) +nsAboutCacheEntry::Channel::OnMetaDataElement(char const * key, char const * value) { mBuffer->AppendLiteral(" \n" " "); @@ -519,7 +539,7 @@ nsAboutCacheEntry::OnMetaDataElement(char const * key, char const * value) //----------------------------------------------------------------------------- NS_IMETHODIMP -nsAboutCacheEntry::OnStartRequest(nsIRequest *request, nsISupports *ctx) +nsAboutCacheEntry::Channel::OnStartRequest(nsIRequest *request, nsISupports *ctx) { mHexDumpState = 0; @@ -529,26 +549,27 @@ nsAboutCacheEntry::OnStartRequest(nsIRequest *request, nsISupports *ctx) } NS_IMETHODIMP -nsAboutCacheEntry::OnDataAvailable(nsIRequest *request, nsISupports *ctx, +nsAboutCacheEntry::Channel::OnDataAvailable(nsIRequest *request, nsISupports *ctx, nsIInputStream *aInputStream, uint64_t aOffset, uint32_t aCount) { uint32_t n; return aInputStream->ReadSegments( - &nsAboutCacheEntry::PrintCacheData, this, aCount, &n); + &nsAboutCacheEntry::Channel::PrintCacheData, this, aCount, &n); } // static NS_METHOD -nsAboutCacheEntry::PrintCacheData(nsIInputStream *aInStream, - void *aClosure, - const char *aFromSegment, - uint32_t aToOffset, - uint32_t aCount, - uint32_t *aWriteCount) +nsAboutCacheEntry::Channel::PrintCacheData(nsIInputStream *aInStream, + void *aClosure, + const char *aFromSegment, + uint32_t aToOffset, + uint32_t aCount, + uint32_t *aWriteCount) { - nsAboutCacheEntry *a = static_cast(aClosure); + nsAboutCacheEntry::Channel *a = + static_cast(aClosure); nsCString buffer; HexDump(&a->mHexDumpState, aFromSegment, aCount, buffer); @@ -562,8 +583,8 @@ nsAboutCacheEntry::PrintCacheData(nsIInputStream *aInStream, } NS_IMETHODIMP -nsAboutCacheEntry::OnStopRequest(nsIRequest *request, nsISupports *ctx, - nsresult result) +nsAboutCacheEntry::Channel::OnStopRequest(nsIRequest *request, nsISupports *ctx, + nsresult result) { NS_NAMED_LITERAL_CSTRING(buffer, "\n"); uint32_t n; @@ -575,7 +596,7 @@ nsAboutCacheEntry::OnStopRequest(nsIRequest *request, nsISupports *ctx, } void -nsAboutCacheEntry::CloseContent() +nsAboutCacheEntry::Channel::CloseContent() { NS_NAMED_LITERAL_CSTRING(buffer, "\n\n"); uint32_t n; diff --git a/netwerk/protocol/about/nsAboutCacheEntry.h b/netwerk/protocol/about/nsAboutCacheEntry.h index 2c15df2a749e..e3f1b03123b9 100644 --- a/netwerk/protocol/about/nsAboutCacheEntry.h +++ b/netwerk/protocol/about/nsAboutCacheEntry.h @@ -19,55 +19,71 @@ class nsILoadContextInfo; class nsIURI; class nsCString; -class nsAboutCacheEntry : public nsIAboutModule - , public nsICacheEntryOpenCallback - , public nsICacheEntryMetaDataVisitor - , public nsIStreamListener +class nsAboutCacheEntry final : public nsIAboutModule { public: NS_DECL_ISUPPORTS NS_DECL_NSIABOUTMODULE - NS_DECL_NSICACHEENTRYOPENCALLBACK - NS_DECL_NSICACHEENTRYMETADATAVISITOR - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - - nsAboutCacheEntry() - : mBuffer(nullptr) - , mWaitingForData(false) - , mHexDumpState(0) - {} private: virtual ~nsAboutCacheEntry() {} - nsresult GetContentStream(nsIURI *, nsIInputStream **); - nsresult OpenCacheEntry(nsIURI *); - nsresult OpenCacheEntry(); - nsresult WriteCacheEntryDescription(nsICacheEntry *); - nsresult WriteCacheEntryUnavailable(); - nsresult ParseURI(nsIURI *uri, nsACString &storageName, - nsILoadContextInfo **loadInfo, - nsCString &enahnceID, nsIURI **cacheUri); - void CloseContent(); + class Channel final : public nsICacheEntryOpenCallback + , public nsICacheEntryMetaDataVisitor + , public nsIStreamListener + , public nsIChannel + { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSICACHEENTRYOPENCALLBACK + NS_DECL_NSICACHEENTRYMETADATAVISITOR + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + NS_FORWARD_SAFE_NSICHANNEL(mChannel) + NS_FORWARD_SAFE_NSIREQUEST(mChannel) - static NS_METHOD - PrintCacheData(nsIInputStream *aInStream, - void *aClosure, - const char *aFromSegment, - uint32_t aToOffset, - uint32_t aCount, - uint32_t *aWriteCount); + Channel() + : mBuffer(nullptr) + , mWaitingForData(false) + , mHexDumpState(0) + {} -private: - nsCString mStorageName, mEnhanceId; - nsCOMPtr mLoadInfo; - nsCOMPtr mCacheURI; + private: + virtual ~Channel() {} - nsCString *mBuffer; - nsCOMPtr mOutputStream; - bool mWaitingForData; - uint32_t mHexDumpState; + public: + nsresult Init(nsIURI* uri, nsILoadInfo* aLoadInfo); + + nsresult GetContentStream(nsIURI *, nsIInputStream **); + nsresult OpenCacheEntry(nsIURI *); + nsresult OpenCacheEntry(); + nsresult WriteCacheEntryDescription(nsICacheEntry *); + nsresult WriteCacheEntryUnavailable(); + nsresult ParseURI(nsIURI *uri, nsACString &storageName, + nsILoadContextInfo **loadInfo, + nsCString &enahnceID, nsIURI **cacheUri); + void CloseContent(); + + static NS_METHOD + PrintCacheData(nsIInputStream *aInStream, + void *aClosure, + const char *aFromSegment, + uint32_t aToOffset, + uint32_t aCount, + uint32_t *aWriteCount); + + private: + nsCString mStorageName, mEnhanceId; + nsCOMPtr mLoadInfo; + nsCOMPtr mCacheURI; + + nsCString *mBuffer; + nsCOMPtr mOutputStream; + bool mWaitingForData; + uint32_t mHexDumpState; + + nsCOMPtr mChannel; + }; }; #define NS_ABOUT_CACHE_ENTRY_MODULE_CID \