Bug 327765 - Mozilla's cache does not invalidate on non-GET requests; r=cbiesinger

This commit is contained in:
Bjarne 2008-10-10 18:14:51 +02:00
Родитель 28f42e3991
Коммит caced0161b
2 изменённых файлов: 72 добавлений и 12 удалений

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

@ -867,6 +867,7 @@ nsHttpChannel::ProcessResponse()
}
// these can normally be cached
rv = ProcessNormal();
MaybeInvalidateCacheEntryForSubsequentGet();
break;
case 206:
if (mCachedContentIsPartial) // an internal byte range request...
@ -883,6 +884,7 @@ nsHttpChannel::ProcessResponse()
case 305: // disabled as a security measure (see bug 187996).
#endif
// don't store the response body for redirects
MaybeInvalidateCacheEntryForSubsequentGet();
rv = ProcessRedirection(httpStatus);
if (NS_SUCCEEDED(rv)) {
InitCacheEntry();
@ -917,6 +919,7 @@ nsHttpChannel::ProcessResponse()
break;
default:
rv = ProcessNormal();
MaybeInvalidateCacheEntryForSubsequentGet();
break;
}
@ -1514,14 +1517,10 @@ nsHttpChannel::OpenCacheEntry(PRBool offline, PRBool *delayed)
return NS_OK;
}
GenerateCacheKey(cacheKey);
GenerateCacheKey(mPostID, cacheKey);
// Get a cache session with appropriate storage policy
nsCacheStoragePolicy storagePolicy;
if (mLoadFlags & INHIBIT_PERSISTENT_CACHING)
storagePolicy = nsICache::STORE_IN_MEMORY;
else
storagePolicy = nsICache::STORE_ANYWHERE; // allow on disk
nsCacheStoragePolicy storagePolicy = DetermineStoragePolicy();
// Set the desired cache access mode accordingly...
nsCacheAccessMode accessRequested;
@ -1713,7 +1712,7 @@ nsHttpChannel::OpenOfflineCacheEntryForWriting()
}
nsCAutoString cacheKey;
GenerateCacheKey(cacheKey);
GenerateCacheKey(mPostID, cacheKey);
NS_ENSURE_TRUE(!mOfflineCacheClientID.IsEmpty(),
NS_ERROR_NOT_AVAILABLE);
@ -1748,7 +1747,7 @@ nsHttpChannel::OpenOfflineCacheEntryForWriting()
}
nsresult
nsHttpChannel::GenerateCacheKey(nsACString &cacheKey)
nsHttpChannel::GenerateCacheKey(PRUint32 postID, nsACString &cacheKey)
{
cacheKey.Truncate();
@ -1756,9 +1755,9 @@ nsHttpChannel::GenerateCacheKey(nsACString &cacheKey)
cacheKey.AssignLiteral("anon&");
}
if (mPostID) {
if (postID) {
char buf[32];
PR_snprintf(buf, sizeof(buf), "id=%x&", mPostID);
PR_snprintf(buf, sizeof(buf), "id=%x&", postID);
cacheKey.Append(buf);
}
@ -2263,7 +2262,7 @@ nsHttpChannel::CloseOfflineCacheEntry()
do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID);
if (appCacheService) {
nsCAutoString cacheKey;
GenerateCacheKey(cacheKey);
GenerateCacheKey(mPostID, cacheKey);
appCacheService->CacheOpportunistically(mApplicationCache,
cacheKey);
}
@ -5414,3 +5413,62 @@ nsHttpChannel::SetNewListener(nsIStreamListener *aListener, nsIStreamListener **
mListener = aListener;
return NS_OK;
}
void
nsHttpChannel::MaybeInvalidateCacheEntryForSubsequentGet()
{
// See RFC 2616 section 5.1.1. These are considered valid
// methods which DO NOT invalidate cache-entries for the
// referred resource. POST, PUT and DELETE as well as any
// other method not listed here will potentially invalidate
// any cached copy of the resource
if (mRequestHead.Method() == nsHttp::Options ||
mRequestHead.Method() == nsHttp::Get ||
mRequestHead.Method() == nsHttp::Head ||
mRequestHead.Method() == nsHttp::Trace ||
mRequestHead.Method() == nsHttp::Connect)
return;
// NOTE:
// Following comments 24,32 and 33 in bug #327765, we only care about
// the cache in the protocol-handler.
// The logic below deviates from the original logic in OpenCacheEntry on
// one point by using only READ_ONLY access-policy. I think this is safe.
LOG(("MaybeInvalidateCacheEntryForSubsequentGet [this=%x]\n", this));
nsCAutoString tmpCacheKey;
// passing 0 in first param gives the cache-key for a GET to my resource
GenerateCacheKey(0, tmpCacheKey);
// Now, find the session holding the cache-entry
nsCOMPtr<nsICacheSession> session;
nsCacheStoragePolicy storagePolicy = DetermineStoragePolicy();
nsresult rv;
rv = gHttpHandler->GetCacheSession(storagePolicy,
getter_AddRefs(session));
if (NS_FAILED(rv)) return;
// Finally, find the actual cache-entry
nsCOMPtr<nsICacheEntryDescriptor> tmpCacheEntry;
rv = session->OpenCacheEntry(tmpCacheKey, nsICache::ACCESS_READ,
PR_FALSE,
getter_AddRefs(tmpCacheEntry));
// If entry was found, set its expiration-time = 0
if(NS_SUCCEEDED(rv)) {
tmpCacheEntry->SetExpirationTime(0);
}
}
nsCacheStoragePolicy
nsHttpChannel::DetermineStoragePolicy()
{
nsCacheStoragePolicy policy = nsICache::STORE_ANYWHERE;
if (mLoadFlags & INHIBIT_PERSISTENT_CACHING)
policy = nsICache::STORE_IN_MEMORY;
return policy;
}

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

@ -188,7 +188,7 @@ private:
// cache specific methods
nsresult OpenCacheEntry(PRBool offline, PRBool *delayed);
nsresult OpenOfflineCacheEntryForWriting();
nsresult GenerateCacheKey(nsACString &key);
nsresult GenerateCacheKey(PRUint32 postID, nsACString &key);
nsresult UpdateExpirationTime();
nsresult CheckCache();
nsresult ShouldUpdateOfflineCacheEntry(PRBool *shouldCacheForOfflineUse);
@ -202,6 +202,8 @@ private:
nsresult FinalizeCacheEntry();
nsresult InstallCacheListener(PRUint32 offset = 0);
nsresult InstallOfflineCacheListener();
void MaybeInvalidateCacheEntryForSubsequentGet();
nsCacheStoragePolicy DetermineStoragePolicy();
// Handle the bogus Content-Encoding Apache sometimes sends
void ClearBogusContentEncodingIfNeeded();