Bug 1729477 - Tweak SubresourceCacheValidationInfo to account for chrome uris. r=tnikkel

Turns out my patch above causes some failures because chrome:// channels
don't have cache information, so we conservatively assume they always
expire, which causes some interesting timing issues in a single test.
Fun stuff.

Tweak the code so that SubresourceCacheValidationInfo has the
pre-existing data:// URI special-case and also special-cases chrome://
URIs.

Differential Revision: https://phabricator.services.mozilla.com/D124921
This commit is contained in:
Emilio Cobos Álvarez 2021-09-08 21:03:02 +00:00
Родитель 8fda6d0a50
Коммит d4d9525111
6 изменённых файлов: 34 добавлений и 22 удалений

Просмотреть файл

@ -10494,7 +10494,8 @@ ScreenIntMargin nsContentUtils::GetWindowSafeAreaInsets(
/* static */
nsContentUtils::SubresourceCacheValidationInfo
nsContentUtils::GetSubresourceCacheValidationInfo(nsIRequest* aRequest) {
nsContentUtils::GetSubresourceCacheValidationInfo(nsIRequest* aRequest,
nsIURI* aURI) {
SubresourceCacheValidationInfo info;
if (nsCOMPtr<nsICacheInfoChannel> cache = do_QueryInterface(aRequest)) {
uint32_t value = 0;
@ -10513,6 +10514,18 @@ nsContentUtils::GetSubresourceCacheValidationInfo(nsIRequest* aRequest) {
}
}
// data: URIs are safe to cache across documents under any circumstance, so we
// special-case them here even though the channel itself doesn't have any
// caching policy. Same for chrome:// uris.
//
// TODO(emilio): Figure out which other schemes that don't have caching
// policies are safe to cache. Blobs should be...
if (aURI && (aURI->SchemeIs("data") || dom::IsChromeURI(aURI))) {
MOZ_ASSERT(!info.mExpirationTime);
MOZ_ASSERT(!info.mMustRevalidate);
info.mExpirationTime = Some(0); // 0 means "doesn't expire".
}
return info;
}

Просмотреть файл

@ -3271,7 +3271,7 @@ class nsContentUtils {
* stylesheets.
*/
static SubresourceCacheValidationInfo GetSubresourceCacheValidationInfo(
nsIRequest*);
nsIRequest*, nsIURI*);
static uint32_t SecondsFromPRTime(PRTime aTime) {
return uint32_t(int64_t(aTime) / int64_t(PR_USEC_PER_SEC));

Просмотреть файл

@ -1880,10 +1880,10 @@ bool imgLoader::ValidateEntry(
LOG_SCOPE(gImgLog, "imgLoader::ValidateEntry");
// If the expiration time is zero, then the request has not gotten far enough
// to know when it will expire.
// to know when it will expire, or we know it will never expire (see
// nsContentUtils::GetSubresourceCacheValidationInfo).
uint32_t expiryTime = aEntry->GetExpiryTime();
bool hasExpired =
expiryTime != 0 && expiryTime <= SecondsFromPRTime(PR_Now());
bool hasExpired = expiryTime && expiryTime <= SecondsFromPRTime(PR_Now());
nsresult rv;

Просмотреть файл

@ -83,8 +83,8 @@ class imgCacheEntry {
void UpdateLoadTime();
int32_t GetExpiryTime() const { return mExpiryTime; }
void SetExpiryTime(int32_t aExpiryTime) {
uint32_t GetExpiryTime() const { return mExpiryTime; }
void SetExpiryTime(uint32_t aExpiryTime) {
mExpiryTime = aExpiryTime;
Touch();
}
@ -130,7 +130,7 @@ class imgCacheEntry {
uint32_t mDataSize;
int32_t mTouchedTime;
uint32_t mLoadTime;
int32_t mExpiryTime;
uint32_t mExpiryTime;
nsExpirationState mExpirationState;
bool mMustValidate : 1;
bool mEvicted : 1;

Просмотреть файл

@ -544,7 +544,17 @@ void imgRequest::SetCacheValidation(imgCacheEntry* aCacheEntry,
return;
}
auto info = nsContentUtils::GetSubresourceCacheValidationInfo(aRequest);
RefPtr<imgRequest> req = aCacheEntry->GetRequest();
MOZ_ASSERT(req);
RefPtr<nsIURI> uri;
req->GetURI(getter_AddRefs(uri));
// TODO(emilio): Seems we should be able to assert `uri` is not null, but we
// get here in such cases sometimes (like for some redirects, see
// docshell/test/chrome/test_bug89419.xhtml).
//
// We have the original URI in the cache key though, probably we should be
// using that instead of relying on Init() getting called.
auto info = nsContentUtils::GetSubresourceCacheValidationInfo(aRequest, uri);
// Expiration time defaults to 0. We set the expiration time on our entry if
// it hasn't been set yet.

Просмотреть файл

@ -115,19 +115,8 @@ StreamLoader::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
}
} // run destructor for `bytes`
auto info = nsContentUtils::GetSubresourceCacheValidationInfo(aRequest);
// data: URIs are safe to cache across documents under any circumstance, so we
// special-case them here even though the channel itself doesn't have any
// caching policy.
//
// TODO(emilio): Figure out which other schemes that don't have caching
// policies are safe to cache. Blobs should be...
if (mSheetLoadData->mURI->SchemeIs("data")) {
MOZ_ASSERT(!info.mExpirationTime);
MOZ_ASSERT(!info.mMustRevalidate);
info.mExpirationTime = Some(0); // 0 means "doesn't expire".
}
auto info = nsContentUtils::GetSubresourceCacheValidationInfo(
aRequest, mSheetLoadData->mURI);
// For now, we never cache entries that we have to revalidate, or whose
// channel don't support caching.