Bug 1266196 - Make about:cache handler be multiple-instance capable. r=michal

This commit is contained in:
Honza Bambas 2016-05-17 05:20:00 -04:00
parent ff3b7278ef
commit 35df656ad7
4 changed files with 197 additions and 134 deletions

View File

@ -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> 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<nsIInputStream> 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<nsIChannel> 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=<storage-name>[&context=<context-key>]]
@ -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);

View File

@ -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<nsILoadContextInfo> 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<nsCString> mStorageList;
nsCString mStorageName;
nsCOMPtr<nsICacheStorage> 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<nsIOutputStream> mStream;
// The context we are working with.
nsCOMPtr<nsILoadContextInfo> mLoadInfo;
nsCString mContextString;
// The list of all storage names we want to visit
nsTArray<nsCString> mStorageList;
nsCString mStorageName;
nsCOMPtr<nsICacheStorage> mStorage;
// Output data buffering and streaming output
nsCString mBuffer;
nsCOMPtr<nsIOutputStream> mStream;
// The input stream channel, the one that actually does the job
nsCOMPtr<nsIChannel> mChannel;
};
};
#define NS_ABOUT_CACHE_MODULE_CID \

View File

@ -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<nsIInputStream> stream;
rv = GetContentStream(uri, getter_AddRefs(stream));
RefPtr<Channel> 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<nsIInputStream> 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(" <tr>\n"
" <th>");
@ -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<nsAboutCacheEntry*>(aClosure);
nsAboutCacheEntry::Channel *a =
static_cast<nsAboutCacheEntry::Channel*>(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, "</pre>\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, "</body>\n</html>\n");
uint32_t n;

View File

@ -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<nsILoadContextInfo> mLoadInfo;
nsCOMPtr<nsIURI> mCacheURI;
private:
virtual ~Channel() {}
nsCString *mBuffer;
nsCOMPtr<nsIAsyncOutputStream> 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<nsILoadContextInfo> mLoadInfo;
nsCOMPtr<nsIURI> mCacheURI;
nsCString *mBuffer;
nsCOMPtr<nsIAsyncOutputStream> mOutputStream;
bool mWaitingForData;
uint32_t mHexDumpState;
nsCOMPtr<nsIChannel> mChannel;
};
};
#define NS_ABOUT_CACHE_ENTRY_MODULE_CID \