summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/cache/CachedRawResource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/loader/cache/CachedRawResource.cpp')
-rw-r--r--Source/WebCore/loader/cache/CachedRawResource.cpp164
1 files changed, 102 insertions, 62 deletions
diff --git a/Source/WebCore/loader/cache/CachedRawResource.cpp b/Source/WebCore/loader/cache/CachedRawResource.cpp
index a6eff5efb..05b9de128 100644
--- a/Source/WebCore/loader/cache/CachedRawResource.cpp
+++ b/Source/WebCore/loader/cache/CachedRawResource.cpp
@@ -29,23 +29,26 @@
#include "CachedRawResourceClient.h"
#include "CachedResourceClientWalker.h"
#include "CachedResourceLoader.h"
-#include "ResourceBuffer.h"
+#include "HTTPHeaderNames.h"
+#include "SharedBuffer.h"
#include "SubresourceLoader.h"
-#include <wtf/PassRefPtr.h>
+#include <wtf/text/StringView.h>
namespace WebCore {
-CachedRawResource::CachedRawResource(ResourceRequest& resourceRequest, Type type)
- : CachedResource(resourceRequest, type)
+CachedRawResource::CachedRawResource(CachedResourceRequest&& request, Type type, SessionID sessionID)
+ : CachedResource(WTFMove(request), type, sessionID)
, m_identifier(0)
+ , m_allowEncodedDataReplacement(true)
{
+ ASSERT(isMainOrMediaOrRawResource());
}
-const char* CachedRawResource::calculateIncrementalDataChunk(ResourceBuffer* data, unsigned& incrementalDataLength)
+const char* CachedRawResource::calculateIncrementalDataChunk(SharedBuffer* data, unsigned& incrementalDataLength)
{
incrementalDataLength = 0;
if (!data)
- return 0;
+ return nullptr;
unsigned previousDataLength = encodedSize();
ASSERT(data->size() >= previousDataLength);
@@ -53,34 +56,37 @@ const char* CachedRawResource::calculateIncrementalDataChunk(ResourceBuffer* dat
return data->data() + previousDataLength;
}
-void CachedRawResource::addDataBuffer(ResourceBuffer* data)
+void CachedRawResource::addDataBuffer(SharedBuffer& data)
{
- CachedResourceHandle<CachedRawResource> protect(this);
- ASSERT(m_options.dataBufferingPolicy == BufferData);
- m_data = data;
+ CachedResourceHandle<CachedRawResource> protectedThis(this);
+ ASSERT(dataBufferingPolicy() == BufferData);
+ m_data = &data;
unsigned incrementalDataLength;
- const char* incrementalData = calculateIncrementalDataChunk(data, incrementalDataLength);
- if (data)
- setEncodedSize(data->size());
+ const char* incrementalData = calculateIncrementalDataChunk(&data, incrementalDataLength);
+ setEncodedSize(data.size());
notifyClientsDataWasReceived(incrementalData, incrementalDataLength);
- if (m_options.dataBufferingPolicy == DoNotBufferData) {
+ if (dataBufferingPolicy() == DoNotBufferData) {
if (m_loader)
m_loader->setDataBufferingPolicy(DoNotBufferData);
clear();
+ return;
}
+
+ CachedResource::addDataBuffer(data);
}
void CachedRawResource::addData(const char* data, unsigned length)
{
- ASSERT(m_options.dataBufferingPolicy == DoNotBufferData);
+ ASSERT(dataBufferingPolicy() == DoNotBufferData);
notifyClientsDataWasReceived(data, length);
+ CachedResource::addData(data, length);
}
-void CachedRawResource::finishLoading(ResourceBuffer* data)
+void CachedRawResource::finishLoading(SharedBuffer* data)
{
- CachedResourceHandle<CachedRawResource> protect(this);
- DataBufferingPolicy dataBufferingPolicy = m_options.dataBufferingPolicy;
+ CachedResourceHandle<CachedRawResource> protectedThis(this);
+ DataBufferingPolicy dataBufferingPolicy = this->dataBufferingPolicy();
if (dataBufferingPolicy == BufferData) {
m_data = data;
@@ -91,8 +97,12 @@ void CachedRawResource::finishLoading(ResourceBuffer* data)
notifyClientsDataWasReceived(incrementalData, incrementalDataLength);
}
+#if USE(QUICK_LOOK)
+ m_allowEncodedDataReplacement = !m_loader->isQuickLookResource();
+#endif
+
CachedResource::finishLoading(data);
- if (dataBufferingPolicy == BufferData && m_options.dataBufferingPolicy == DoNotBufferData) {
+ if (dataBufferingPolicy == BufferData && this->dataBufferingPolicy() == DoNotBufferData) {
if (m_loader)
m_loader->setDataBufferingPolicy(DoNotBufferData);
clear();
@@ -104,37 +114,45 @@ void CachedRawResource::notifyClientsDataWasReceived(const char* data, unsigned
if (!length)
return;
- CachedResourceHandle<CachedRawResource> protect(this);
+ CachedResourceHandle<CachedRawResource> protectedThis(this);
CachedResourceClientWalker<CachedRawResourceClient> w(m_clients);
while (CachedRawResourceClient* c = w.next())
- c->dataReceived(this, data, length);
+ c->dataReceived(*this, data, length);
}
-void CachedRawResource::didAddClient(CachedResourceClient* c)
+void CachedRawResource::didAddClient(CachedResourceClient& c)
{
if (!hasClient(c))
return;
// The calls to the client can result in events running, potentially causing
// this resource to be evicted from the cache and all clients to be removed,
// so a protector is necessary.
- CachedResourceHandle<CachedRawResource> protect(this);
- CachedRawResourceClient* client = static_cast<CachedRawResourceClient*>(c);
+ CachedResourceHandle<CachedRawResource> protectedThis(this);
+ CachedRawResourceClient& client = static_cast<CachedRawResourceClient&>(c);
size_t redirectCount = m_redirectChain.size();
for (size_t i = 0; i < redirectCount; i++) {
RedirectPair redirect = m_redirectChain[i];
ResourceRequest request(redirect.m_request);
- client->redirectReceived(this, request, redirect.m_redirectResponse);
+ client.redirectReceived(*this, request, redirect.m_redirectResponse);
if (!hasClient(c))
return;
}
ASSERT(redirectCount == m_redirectChain.size());
- if (!m_response.isNull())
- client->responseReceived(this, m_response);
+ if (!m_response.isNull()) {
+ ResourceResponse response(m_response);
+ if (validationCompleting())
+ response.setSource(ResourceResponse::Source::MemoryCacheAfterValidation);
+ else {
+ ASSERT(!validationInProgress());
+ response.setSource(ResourceResponse::Source::MemoryCache);
+ }
+ client.responseReceived(*this, response);
+ }
if (!hasClient(c))
return;
if (m_data)
- client->dataReceived(this, m_data->data(), m_data->size());
+ client.dataReceived(*this, m_data->data(), m_data->size());
if (!hasClient(c))
return;
CachedResource::didAddClient(client);
@@ -146,34 +164,51 @@ void CachedRawResource::allClientsRemoved()
m_loader->cancelIfNotFinishing();
}
-void CachedRawResource::willSendRequest(ResourceRequest& request, const ResourceResponse& response)
+void CachedRawResource::redirectReceived(ResourceRequest& request, const ResourceResponse& response)
{
- CachedResourceHandle<CachedRawResource> protect(this);
+ CachedResourceHandle<CachedRawResource> protectedThis(this);
if (!response.isNull()) {
CachedResourceClientWalker<CachedRawResourceClient> w(m_clients);
while (CachedRawResourceClient* c = w.next())
- c->redirectReceived(this, request, response);
+ c->redirectReceived(*this, request, response);
m_redirectChain.append(RedirectPair(request, response));
}
- CachedResource::willSendRequest(request, response);
+ CachedResource::redirectReceived(request, response);
}
void CachedRawResource::responseReceived(const ResourceResponse& response)
{
- CachedResourceHandle<CachedRawResource> protect(this);
+ CachedResourceHandle<CachedRawResource> protectedThis(this);
if (!m_identifier)
m_identifier = m_loader->identifier();
CachedResource::responseReceived(response);
CachedResourceClientWalker<CachedRawResourceClient> w(m_clients);
while (CachedRawResourceClient* c = w.next())
- c->responseReceived(this, m_response);
+ c->responseReceived(*this, m_response);
+}
+
+bool CachedRawResource::shouldCacheResponse(const ResourceResponse& response)
+{
+ CachedResourceClientWalker<CachedRawResourceClient> w(m_clients);
+ while (CachedRawResourceClient* c = w.next()) {
+ if (!c->shouldCacheResponse(*this, response))
+ return false;
+ }
+ return true;
}
void CachedRawResource::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
{
CachedResourceClientWalker<CachedRawResourceClient> w(m_clients);
while (CachedRawResourceClient* c = w.next())
- c->dataSent(this, bytesSent, totalBytesToBeSent);
+ c->dataSent(*this, bytesSent, totalBytesToBeSent);
+}
+
+void CachedRawResource::finishedTimingForWorkerLoad(ResourceTiming&& resourceTiming)
+{
+ CachedResourceClientWalker<CachedRawResourceClient> w(m_clients);
+ while (CachedRawResourceClient* c = w.next())
+ c->finishedTimingForWorkerLoad(*this, resourceTiming);
}
void CachedRawResource::switchClientsToRevalidatedResource()
@@ -181,7 +216,7 @@ void CachedRawResource::switchClientsToRevalidatedResource()
ASSERT(m_loader);
// If we're in the middle of a successful revalidation, responseReceived() hasn't been called, so we haven't set m_identifier.
ASSERT(!m_identifier);
- static_cast<CachedRawResource*>(resourceToRevalidate())->m_identifier = m_loader->identifier();
+ downcast<CachedRawResource>(*resourceToRevalidate()).m_identifier = m_loader->identifier();
CachedResource::switchClientsToRevalidatedResource();
}
@@ -196,25 +231,26 @@ void CachedRawResource::setDataBufferingPolicy(DataBufferingPolicy dataBuffering
m_options.dataBufferingPolicy = dataBufferingPolicy;
}
-static bool shouldIgnoreHeaderForCacheReuse(AtomicString headerName)
+static bool shouldIgnoreHeaderForCacheReuse(HTTPHeaderName name)
{
+ switch (name) {
// FIXME: This list of headers that don't affect cache policy almost certainly isn't complete.
- DEFINE_STATIC_LOCAL(HashSet<AtomicString>, m_headers, ());
- if (m_headers.isEmpty()) {
- m_headers.add("Accept");
- m_headers.add("Cache-Control");
- m_headers.add("Origin");
- m_headers.add("Pragma");
- m_headers.add("Purpose");
- m_headers.add("Referer");
- m_headers.add("User-Agent");
+ case HTTPHeaderName::Accept:
+ case HTTPHeaderName::CacheControl:
+ case HTTPHeaderName::Pragma:
+ case HTTPHeaderName::Purpose:
+ case HTTPHeaderName::Referer:
+ case HTTPHeaderName::UserAgent:
+ return true;
+
+ default:
+ return false;
}
- return m_headers.contains(headerName);
}
bool CachedRawResource::canReuse(const ResourceRequest& newRequest) const
{
- if (m_options.dataBufferingPolicy == DoNotBufferData)
+ if (dataBufferingPolicy() == DoNotBufferData)
return false;
if (m_resourceRequest.httpMethod() != newRequest.httpMethod())
@@ -226,6 +262,9 @@ bool CachedRawResource::canReuse(const ResourceRequest& newRequest) const
if (m_resourceRequest.allowCookies() != newRequest.allowCookies())
return false;
+ if (newRequest.isConditional())
+ return false;
+
// Ensure most headers match the existing headers before continuing.
// Note that the list of ignored headers includes some headers explicitly related to caching.
// A more detailed check of caching policy will be performed later, this is simply a list of
@@ -233,22 +272,23 @@ bool CachedRawResource::canReuse(const ResourceRequest& newRequest) const
const HTTPHeaderMap& newHeaders = newRequest.httpHeaderFields();
const HTTPHeaderMap& oldHeaders = m_resourceRequest.httpHeaderFields();
- HTTPHeaderMap::const_iterator end = newHeaders.end();
- for (HTTPHeaderMap::const_iterator i = newHeaders.begin(); i != end; ++i) {
- AtomicString headerName = i->key;
- if (!shouldIgnoreHeaderForCacheReuse(headerName) && i->value != oldHeaders.get(headerName))
- return false;
- }
-
- end = oldHeaders.end();
- for (HTTPHeaderMap::const_iterator i = oldHeaders.begin(); i != end; ++i) {
- AtomicString headerName = i->key;
- if (!shouldIgnoreHeaderForCacheReuse(headerName) && i->value != newHeaders.get(headerName))
+ for (const auto& header : newHeaders) {
+ if (header.keyAsHTTPHeaderName) {
+ if (!shouldIgnoreHeaderForCacheReuse(header.keyAsHTTPHeaderName.value())
+ && header.value != oldHeaders.commonHeaders().get(header.keyAsHTTPHeaderName.value()))
+ return false;
+ } else if (header.value != oldHeaders.uncommonHeaders().get(header.key))
return false;
}
- for (size_t i = 0; i < m_redirectChain.size(); i++) {
- if (m_redirectChain[i].m_redirectResponse.cacheControlContainsNoStore())
+ // For this second loop, we don't actually need to compare values, checking that the
+ // key is contained in newHeaders is sufficient due to the previous loop.
+ for (const auto& header : oldHeaders) {
+ if (header.keyAsHTTPHeaderName) {
+ if (!shouldIgnoreHeaderForCacheReuse(header.keyAsHTTPHeaderName.value())
+ && !newHeaders.commonHeaders().contains(header.keyAsHTTPHeaderName.value()))
+ return false;
+ } else if (!newHeaders.uncommonHeaders().contains(header.key))
return false;
}
@@ -257,7 +297,7 @@ bool CachedRawResource::canReuse(const ResourceRequest& newRequest) const
void CachedRawResource::clear()
{
- m_data.clear();
+ m_data = nullptr;
setEncodedSize(0);
if (m_loader)
m_loader->clearResourceData();