diff options
Diffstat (limited to 'WebCore/loader/CachedResource.cpp')
-rw-r--r-- | WebCore/loader/CachedResource.cpp | 54 |
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 |