summaryrefslogtreecommitdiffstats
path: root/WebCore/loader/CachedResource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/loader/CachedResource.cpp')
-rw-r--r--WebCore/loader/CachedResource.cpp54
1 files changed, 43 insertions, 11 deletions
diff --git a/WebCore/loader/CachedResource.cpp b/WebCore/loader/CachedResource.cpp
index a2eaa2c..478873f 100644
--- a/WebCore/loader/CachedResource.cpp
+++ b/WebCore/loader/CachedResource.cpp
@@ -173,7 +173,13 @@ void CachedResource::setRequest(Request* request)
delete this;
}
-void CachedResource::addClient(CachedResourceClient *c)
+void CachedResource::addClient(CachedResourceClient* client)
+{
+ addClientToSet(client);
+ didAddClient(client);
+}
+
+void CachedResource::addClientToSet(CachedResourceClient* client)
{
ASSERT(!isPurgeable());
@@ -187,21 +193,28 @@ void CachedResource::addClient(CachedResourceClient *c)
}
if (!hasClients() && inCache())
cache()->addToLiveResourcesSize(this);
- m_clients.add(c);
+ m_clients.add(client);
}
-void CachedResource::removeClient(CachedResourceClient *c)
+void CachedResource::removeClient(CachedResourceClient* client)
{
- ASSERT(m_clients.contains(c));
- m_clients.remove(c);
+ ASSERT(m_clients.contains(client));
+ m_clients.remove(client);
+
if (canDelete() && !inCache())
delete this;
else if (!hasClients() && inCache()) {
cache()->removeFromLiveResourcesSize(this);
cache()->removeFromLiveDecodedResourcesList(this);
allClientsRemoved();
- cache()->prune();
+ if (response().cacheControlContainsNoStore()) {
+ // RFC2616 14.9.2:
+ // "no-store: ...MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible"
+ cache()->remove(this);
+ } else
+ cache()->prune();
}
+ // This object may be dead here.
}
void CachedResource::deleteIfPossible()
@@ -330,10 +343,15 @@ void CachedResource::switchClientsToRevalidatedResource()
}
// Equivalent of calling removeClient() for all clients
m_clients.clear();
-
+
unsigned moveCount = clientsToMove.size();
for (unsigned n = 0; n < moveCount; ++n)
- m_resourceToRevalidate->addClient(clientsToMove[n]);
+ m_resourceToRevalidate->addClientToSet(clientsToMove[n]);
+ for (unsigned n = 0; n < moveCount; ++n) {
+ // Calling didAddClient for a client may end up removing another client. In that case it won't be in the set anymore.
+ if (m_resourceToRevalidate->m_clients.contains(clientsToMove[n]))
+ m_resourceToRevalidate->didAddClient(clientsToMove[n]);
+ }
}
void CachedResource::updateResponseAfterRevalidation(const ResourceResponse& validatingResponse)
@@ -355,18 +373,32 @@ void CachedResource::updateResponseAfterRevalidation(const ResourceResponse& val
bool CachedResource::canUseCacheValidator() const
{
- return !m_loading && (!m_response.httpHeaderField("Last-Modified").isEmpty() || !m_response.httpHeaderField("ETag").isEmpty());
+ if (m_loading || m_errorOccurred)
+ return false;
+
+ if (m_response.cacheControlContainsNoStore())
+ return false;
+
+ DEFINE_STATIC_LOCAL(const AtomicString, lastModifiedHeader, ("last-modified"));
+ DEFINE_STATIC_LOCAL(const AtomicString, eTagHeader, ("etag"));
+ return !m_response.httpHeaderField(lastModifiedHeader).isEmpty() || !m_response.httpHeaderField(eTagHeader).isEmpty();
}
bool CachedResource::mustRevalidate(CachePolicy cachePolicy) const
{
+ if (m_errorOccurred)
+ return true;
+
if (m_loading)
return false;
+
+ if (m_response.cacheControlContainsNoCache() || m_response.cacheControlContainsNoStore())
+ return true;
if (cachePolicy == CachePolicyCache)
- return m_response.cacheControlContainsNoCache() || (isExpired() && m_response.cacheControlContainsMustRevalidate());
+ return m_response.cacheControlContainsMustRevalidate() && isExpired();
- return isExpired() || m_response.cacheControlContainsNoCache();
+ return isExpired();
}
bool CachedResource::isSafeToMakePurgeable() const