зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1202085 - Part 4: Add an ID for controlled document to the image cache key; r=seth
This ID will be null for non-controlled documents and also for image cache entries for which a document is not available, and it will be the numerical value of the document pointer for controlled documents. This effectively makes sure that a controlled document doesn't share its image cache entries with anything else.
This commit is contained in:
Родитель
98b8da3eb6
Коммит
3c9fd0e9e1
|
@ -10,6 +10,10 @@
|
|||
#include "ImageURL.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/dom/workers/ServiceWorkerManager.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -42,8 +46,9 @@ BlobSerial(ImageURL* aURI)
|
|||
return Nothing();
|
||||
}
|
||||
|
||||
ImageCacheKey::ImageCacheKey(nsIURI* aURI)
|
||||
ImageCacheKey::ImageCacheKey(nsIURI* aURI, nsIDOMDocument* aDocument)
|
||||
: mURI(new ImageURL(aURI))
|
||||
, mControlledDocument(GetControlledDocumentToken(aDocument))
|
||||
, mIsChrome(URISchemeIs(mURI, "chrome"))
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -52,11 +57,12 @@ ImageCacheKey::ImageCacheKey(nsIURI* aURI)
|
|||
mBlobSerial = BlobSerial(mURI);
|
||||
}
|
||||
|
||||
mHash = ComputeHash(mURI, mBlobSerial);
|
||||
mHash = ComputeHash(mURI, mBlobSerial, mControlledDocument);
|
||||
}
|
||||
|
||||
ImageCacheKey::ImageCacheKey(ImageURL* aURI)
|
||||
ImageCacheKey::ImageCacheKey(ImageURL* aURI, nsIDOMDocument* aDocument)
|
||||
: mURI(aURI)
|
||||
, mControlledDocument(GetControlledDocumentToken(aDocument))
|
||||
, mIsChrome(URISchemeIs(mURI, "chrome"))
|
||||
{
|
||||
MOZ_ASSERT(aURI);
|
||||
|
@ -65,12 +71,13 @@ ImageCacheKey::ImageCacheKey(ImageURL* aURI)
|
|||
mBlobSerial = BlobSerial(mURI);
|
||||
}
|
||||
|
||||
mHash = ComputeHash(mURI, mBlobSerial);
|
||||
mHash = ComputeHash(mURI, mBlobSerial, mControlledDocument);
|
||||
}
|
||||
|
||||
ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
|
||||
: mURI(aOther.mURI)
|
||||
, mBlobSerial(aOther.mBlobSerial)
|
||||
, mControlledDocument(aOther.mControlledDocument)
|
||||
, mHash(aOther.mHash)
|
||||
, mIsChrome(aOther.mIsChrome)
|
||||
{ }
|
||||
|
@ -78,6 +85,7 @@ ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
|
|||
ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
|
||||
: mURI(Move(aOther.mURI))
|
||||
, mBlobSerial(Move(aOther.mBlobSerial))
|
||||
, mControlledDocument(aOther.mControlledDocument)
|
||||
, mHash(aOther.mHash)
|
||||
, mIsChrome(aOther.mIsChrome)
|
||||
{ }
|
||||
|
@ -85,6 +93,10 @@ ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
|
|||
bool
|
||||
ImageCacheKey::operator==(const ImageCacheKey& aOther) const
|
||||
{
|
||||
// Don't share the image cache between a controlled document and anything else.
|
||||
if (mControlledDocument != aOther.mControlledDocument) {
|
||||
return false;
|
||||
}
|
||||
if (mBlobSerial || aOther.mBlobSerial) {
|
||||
// If at least one of us has a blob serial, just compare the blob serial and
|
||||
// the ref portion of the URIs.
|
||||
|
@ -104,11 +116,13 @@ ImageCacheKey::Spec() const
|
|||
|
||||
/* static */ uint32_t
|
||||
ImageCacheKey::ComputeHash(ImageURL* aURI,
|
||||
const Maybe<uint64_t>& aBlobSerial)
|
||||
const Maybe<uint64_t>& aBlobSerial,
|
||||
void* aControlledDocument)
|
||||
{
|
||||
// Since we frequently call Hash() several times in a row on the same
|
||||
// ImageCacheKey, as an optimization we compute our hash once and store it.
|
||||
|
||||
nsPrintfCString ptr("%p", aControlledDocument);
|
||||
if (aBlobSerial) {
|
||||
// For blob URIs, we hash the serial number of the underlying blob, so that
|
||||
// different blob URIs which point to the same blob share a cache entry. We
|
||||
|
@ -117,13 +131,32 @@ ImageCacheKey::ComputeHash(ImageURL* aURI,
|
|||
// the same.
|
||||
nsAutoCString ref;
|
||||
aURI->GetRef(ref);
|
||||
return HashGeneric(*aBlobSerial, HashString(ref));
|
||||
return HashGeneric(*aBlobSerial, HashString(ref + ptr));
|
||||
}
|
||||
|
||||
// For non-blob URIs, we hash the URI spec.
|
||||
nsAutoCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
return HashString(spec);
|
||||
return HashString(spec + ptr);
|
||||
}
|
||||
|
||||
/* static */ void*
|
||||
ImageCacheKey::GetControlledDocumentToken(nsIDOMDocument* aDocument)
|
||||
{
|
||||
// For non-controlled documents, we just return null. For controlled
|
||||
// documents, we cast the pointer into a void* to avoid dereferencing
|
||||
// it (since we only use it for comparisons), and return it.
|
||||
void* pointer = nullptr;
|
||||
using dom::workers::ServiceWorkerManager;
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
|
||||
if (doc && swm) {
|
||||
ErrorResult rv;
|
||||
if (swm->IsControlled(doc, rv)) {
|
||||
pointer = doc;
|
||||
}
|
||||
}
|
||||
return pointer;
|
||||
}
|
||||
|
||||
} // namespace image
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
class nsIDOMDocument;
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -24,12 +25,14 @@ class ImageURL;
|
|||
*
|
||||
* We key the cache on the initial URI (before any redirects), with some
|
||||
* canonicalization applied. See ComputeHash() for the details.
|
||||
* Controlled documents do not share their cache entries with
|
||||
* non-controlled documents, or other controlled documents.
|
||||
*/
|
||||
class ImageCacheKey final
|
||||
{
|
||||
public:
|
||||
explicit ImageCacheKey(nsIURI* aURI);
|
||||
explicit ImageCacheKey(ImageURL* aURI);
|
||||
ImageCacheKey(nsIURI* aURI, nsIDOMDocument* aDocument);
|
||||
ImageCacheKey(ImageURL* aURI, nsIDOMDocument* aDocument);
|
||||
|
||||
ImageCacheKey(const ImageCacheKey& aOther);
|
||||
ImageCacheKey(ImageCacheKey&& aOther);
|
||||
|
@ -45,10 +48,13 @@ public:
|
|||
|
||||
private:
|
||||
static uint32_t ComputeHash(ImageURL* aURI,
|
||||
const Maybe<uint64_t>& aBlobSerial);
|
||||
const Maybe<uint64_t>& aBlobSerial,
|
||||
void* aControlledDocument);
|
||||
static void* GetControlledDocumentToken(nsIDOMDocument* aDocument);
|
||||
|
||||
RefPtr<ImageURL> mURI;
|
||||
Maybe<uint64_t> mBlobSerial;
|
||||
void* mControlledDocument;
|
||||
uint32_t mHash;
|
||||
bool mIsChrome;
|
||||
};
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsILoadGroupChild.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::image;
|
||||
|
@ -1341,7 +1342,7 @@ imgLoader::FindEntryProperties(nsIURI* uri,
|
|||
{
|
||||
*_retval = nullptr;
|
||||
|
||||
ImageCacheKey key(uri);
|
||||
ImageCacheKey key(uri, doc);
|
||||
imgCacheTable& cache = GetCache(key);
|
||||
|
||||
RefPtr<imgCacheEntry> entry;
|
||||
|
@ -2087,7 +2088,8 @@ imgLoader::LoadImage(nsIURI* aURI,
|
|||
// XXX For now ignore aCacheKey. We will need it in the future
|
||||
// for correctly dealing with image load requests that are a result
|
||||
// of post data.
|
||||
ImageCacheKey key(aURI);
|
||||
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aCX);
|
||||
ImageCacheKey key(aURI, doc);
|
||||
imgCacheTable& cache = GetCache(key);
|
||||
|
||||
if (cache.Get(key, getter_AddRefs(entry)) && entry) {
|
||||
|
@ -2311,7 +2313,8 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel,
|
|||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
ImageCacheKey key(uri);
|
||||
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aCX);
|
||||
ImageCacheKey key(uri, doc);
|
||||
|
||||
nsLoadFlags requestFlags = nsIRequest::LOAD_NORMAL;
|
||||
channel->GetLoadFlags(&requestFlags);
|
||||
|
@ -2405,7 +2408,7 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel,
|
|||
// constructed above with the *current URI* and not the *original URI*. I'm
|
||||
// pretty sure this is a bug, and it's preventing us from ever getting a
|
||||
// cache hit in LoadImageWithChannel when redirects are involved.
|
||||
ImageCacheKey originalURIKey(originalURI);
|
||||
ImageCacheKey originalURIKey(originalURI, doc);
|
||||
|
||||
// Default to doing a principal check because we don't know who
|
||||
// started that load and whether their principal ended up being
|
||||
|
|
|
@ -501,7 +501,7 @@ imgRequest::RemoveFromCache()
|
|||
if (mCacheEntry) {
|
||||
mLoader->RemoveFromCache(mCacheEntry);
|
||||
} else {
|
||||
mLoader->RemoveFromCache(ImageCacheKey(mURI));
|
||||
mLoader->RemoveFromCache(mCacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче