/*
    Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
    Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
    Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
    Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
    Copyright (C) 2004-2011, 2014, 2018 Apple Inc. All rights reserved.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "CachedResource.h"

#include "CachePolicy.h"
#include "CachedResourceClient.h"
#include "CachedResourceClientWalker.h"
#include "CachedResourceHandle.h"
#include "CachedResourceLoader.h"
#include "CookieJar.h"
#include "CrossOriginAccessControl.h"
#include "DefaultResourceLoadPriority.h"
#include "DiagnosticLoggingClient.h"
#include "DiagnosticLoggingKeys.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "HTTPHeaderNames.h"
#include "HTTPHeaderValues.h"
#include "InspectorInstrumentation.h"
#include "LegacySchemeRegistry.h"
#include "LoaderStrategy.h"
#include "Logging.h"
#include "MemoryCache.h"
#include "PlatformStrategies.h"
#include "ProgressTracker.h"
#include "ResourceHandle.h"
#include "SecurityOrigin.h"
#include "SubresourceLoader.h"
#include <wtf/CompletionHandler.h>
#include <wtf/MathExtras.h>
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/StdLibExtras.h>
#include <wtf/URL.h>
#include <wtf/Vector.h>
#include <wtf/text/CString.h>

#if USE(QUICK_LOOK)
#include "QuickLook.h"
#endif

#undef CACHEDRESOURCE_RELEASE_LOG
#define PAGE_ID(frame) (valueOrDefault(frame.pageID()).toUInt64())
#define FRAME_ID(frame) (valueOrDefault(frame.frameID()).toUInt64())
#define CACHEDRESOURCE_RELEASE_LOG(fmt, ...) RELEASE_LOG(Network, "%p - CachedResource::" fmt, this, ##__VA_ARGS__)
#define CACHEDRESOURCE_RELEASE_LOG_WITH_FRAME(fmt, frame, ...) RELEASE_LOG(Network, "%p - [pageID=%" PRIu64 ", frameID=%" PRIu64 "] CachedResource::" fmt, this, PAGE_ID(frame), FRAME_ID(frame), ##__VA_ARGS__)

namespace WebCore {

DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CachedResource);

static Seconds deadDecodedDataDeletionIntervalForResourceType(CachedResource::Type type)
{
    if (type == CachedResource::Type::Script)
        return 5_s;

    return MemoryCache::singleton().deadDecodedDataDeletionInterval();
}

DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, cachedResourceLeakCounter, ("CachedResource"));

CachedResource::CachedResource(CachedResourceRequest&& request, Type type, PAL::SessionID sessionID, const CookieJar* cookieJar)
    : m_options(request.options())
    , m_resourceRequest(request.releaseResourceRequest())
    , m_decodedDataDeletionTimer(*this, &CachedResource::destroyDecodedData, deadDecodedDataDeletionIntervalForResourceType(type))
    , m_sessionID(sessionID)
    , m_cookieJar(cookieJar)
    , m_responseTimestamp(WallTime::now())
    , m_fragmentIdentifierForRequest(request.releaseFragmentIdentifier())
    , m_origin(request.releaseOrigin())
    , m_initiatorName(request.initiatorName())
    , m_type(type)
    , m_preloadResult(PreloadResult::PreloadNotReferenced)
    , m_responseTainting(ResourceResponse::Tainting::Basic)
    , m_loadPriority(DefaultResourceLoadPriority::forResourceType(type))
    , m_status(Pending)
    , m_requestedFromNetworkingLayer(false)
    , m_inCache(false)
    , m_loading(false)
    , m_isLinkPreload(request.isLinkPreload())
    , m_hasUnknownEncoding(request.isLinkPreload())
    , m_switchingClientsToRevalidatedResource(false)
    , m_ignoreForRequestCount(request.ignoreForRequestCount())
{
    ASSERT(m_sessionID.isValid());

    setLoadPriority(request.priority());
#ifndef NDEBUG
    cachedResourceLeakCounter.increment();
#endif

    // FIXME: We should have a better way of checking for Navigation loads, maybe FetchMode::Options::Navigate.
    ASSERT(m_origin || m_type == Type::MainResource);

    if (isRequestCrossOrigin(m_origin.get(), m_resourceRequest.url(), m_options))
        setCrossOrigin();
}

// FIXME: For this constructor, we should probably mandate that the URL has no fragment identifier.
CachedResource::CachedResource(const URL& url, Type type, PAL::SessionID sessionID, const CookieJar* cookieJar)
    : m_resourceRequest(url)
    , m_decodedDataDeletionTimer(*this, &CachedResource::destroyDecodedData, deadDecodedDataDeletionIntervalForResourceType(type))
    , m_sessionID(sessionID)
    , m_cookieJar(cookieJar)
    , m_responseTimestamp(WallTime::now())
    , m_fragmentIdentifierForRequest(CachedResourceRequest::splitFragmentIdentifierFromRequestURL(m_resourceRequest))
    , m_type(type)
    , m_preloadResult(PreloadResult::PreloadNotReferenced)
    , m_responseTainting(ResourceResponse::Tainting::Basic)
    , m_status(Cached)
    , m_requestedFromNetworkingLayer(false)
    , m_inCache(false)
    , m_loading(false)
    , m_isLinkPreload(false)
    , m_hasUnknownEncoding(false)
    , m_switchingClientsToRevalidatedResource(false)
    , m_ignoreForRequestCount(false)
{
    ASSERT(m_sessionID.isValid());
#ifndef NDEBUG
    cachedResourceLeakCounter.increment();
#endif
}

CachedResource::~CachedResource()
{
    ASSERT(!m_resourceToRevalidate); // Should be true because canDelete() checks this.
    ASSERT(canDelete());
    ASSERT(!inCache());
    ASSERT(!m_deleted);
    ASSERT(url().isNull() || !allowsCaching() || MemoryCache::singleton().resourceForRequest(resourceRequest(), sessionID()) != this);

#ifndef NDEBUG
    m_deleted = true;
    cachedResourceLeakCounter.decrement();
#endif
}

void CachedResource::failBeforeStarting()
{
    // FIXME: What if resources in other frames were waiting for this revalidation?
    LOG(ResourceLoading, "Cannot start loading '%s'", url().string().latin1().data());
    if (allowsCaching() && m_resourceToRevalidate)
        MemoryCache::singleton().revalidationFailed(*this);
    error(CachedResource::LoadError);
}

void CachedResource::load(CachedResourceLoader& cachedResourceLoader)
{
    if (!cachedResourceLoader.frame()) {
        CACHEDRESOURCE_RELEASE_LOG("load: No associated frame");
        failBeforeStarting();
        return;
    }
    Frame& frame = *cachedResourceLoader.frame();

    // Prevent new loads if we are in the BackForwardCache or being added to the BackForwardCache.
    // We query the top document because new frames may be created in pagehide event handlers
    // and their backForwardCacheState will not reflect the fact that they are about to enter page
    // cache.
    if (auto* topDocument = frame.mainFrame().document()) {
        switch (topDocument->backForwardCacheState()) {
        case Document::NotInBackForwardCache:
            break;
        case Document::AboutToEnterBackForwardCache:
            // Beacons are allowed to go through in 'pagehide' event handlers.
            if (m_options.keepAlive || shouldUsePingLoad(type()))
                break;
            CACHEDRESOURCE_RELEASE_LOG_WITH_FRAME("load: About to enter back/forward cache", frame);
            failBeforeStarting();
            return;
        case Document::InBackForwardCache:
            CACHEDRESOURCE_RELEASE_LOG_WITH_FRAME("load: Already in back/forward cache", frame);
            failBeforeStarting();
            return;
        }
    }

    FrameLoader& frameLoader = frame.loader();
    if (m_options.securityCheck == SecurityCheckPolicy::DoSecurityCheck && !m_options.keepAlive && !shouldUsePingLoad(type())) {
        while (true) {
            if (frameLoader.state() == FrameState::Provisional)
                CACHEDRESOURCE_RELEASE_LOG_WITH_FRAME("load: Failed security check -- state is provisional", frame);
            else if (!frameLoader.activeDocumentLoader())
                CACHEDRESOURCE_RELEASE_LOG_WITH_FRAME("load: Failed security check -- not active document", frame);
            else if (frameLoader.activeDocumentLoader()->isStopping())
                CACHEDRESOURCE_RELEASE_LOG_WITH_FRAME("load: Failed security check -- active loader is stopping", frame);
            else
                break;
            failBeforeStarting();
            return;
        }
    }

    m_loading = true;

    if (isCacheValidator()) {
        CachedResource* resourceToRevalidate = m_resourceToRevalidate;
        ASSERT(resourceToRevalidate->canUseCacheValidator());
        ASSERT(resourceToRevalidate->isLoaded());
        const String& lastModified = resourceToRevalidate->response().httpHeaderField(HTTPHeaderName::LastModified);
        const String& eTag = resourceToRevalidate->response().httpHeaderField(HTTPHeaderName::ETag);
        if (!lastModified.isEmpty() || !eTag.isEmpty()) {
            ASSERT(cachedResourceLoader.cachePolicy(type(), url()) != CachePolicy::Reload);
            if (cachedResourceLoader.cachePolicy(type(), url()) == CachePolicy::Revalidate)
                m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::CacheControl, HTTPHeaderValues::maxAge0());
            if (!lastModified.isEmpty())
                m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
            if (!eTag.isEmpty())
                m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
        }
    }

    if (type() == Type::LinkPrefetch)
        m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::Purpose, "prefetch");
    m_resourceRequest.setPriority(loadPriority());

    // Navigation algorithm is setting up the request before sending it to CachedResourceLoader?CachedResource.
    // So no need for extra fields for MainResource.
    if (type() != Type::MainResource) {
        bool isServiceWorkerNavigationLoad = type() != Type::SVGDocumentResource && m_options.serviceWorkersMode == ServiceWorkersMode::None && (m_options.destination == FetchOptions::Destination::Document || m_options.destination == FetchOptions::Destination::Iframe);
        frameLoader.updateRequestAndAddExtraFields(m_resourceRequest, IsMainResource::No, FrameLoadType::Standard, ShouldUpdateAppInitiatedValue::Yes, isServiceWorkerNavigationLoad ? FrameLoader::IsServiceWorkerNavigationLoad::Yes : FrameLoader::IsServiceWorkerNavigationLoad::No);
    }

    // FIXME: It's unfortunate that the cache layer and below get to know anything about fragment identifiers.
    // We should look into removing the expectation of that knowledge from the platform network stacks.
    ResourceRequest request(m_resourceRequest);
    if (!m_fragmentIdentifierForRequest.isNull()) {
        URL url = request.url();
        url.setFragmentIdentifier(m_fragmentIdentifierForRequest);
        request.setURL(url);
        m_fragmentIdentifierForRequest = String();
    }

    if (m_options.keepAlive && type() != Type::Ping && !cachedResourceLoader.keepaliveRequestTracker().tryRegisterRequest(*this)) {
        setResourceError({ errorDomainWebKitInternal, 0, request.url(), "Reached maximum amount of queued data of 64Kb for keepalive requests"_s, ResourceError::Type::AccessControl });
        failBeforeStarting();
        return;
    }

    // FIXME: Deprecate that code path.
    if (m_options.keepAlive && shouldUsePingLoad(type()) && platformStrategies()->loaderStrategy()->usePingLoad()) {
        ASSERT(m_originalRequest);
        CachedResourceHandle<CachedResource> protectedThis(this);

        auto identifier = ResourceLoaderIdentifier::generate();
        InspectorInstrumentation::willSendRequestOfType(&frame, identifier, frameLoader.activeDocumentLoader(), request, InspectorInstrumentation::LoadType::Beacon);

        platformStrategies()->loaderStrategy()->startPingLoad(frame, request, m_originalRequest->httpHeaderFields(), m_options, m_options.contentSecurityPolicyImposition, [this, protectedThis = WTFMove(protectedThis), protectedFrame = Ref { frame }, identifier] (const ResourceError& error, const ResourceResponse& response) {
            if (!response.isNull())
                InspectorInstrumentation::didReceiveResourceResponse(protectedFrame, identifier, protectedFrame->loader().activeDocumentLoader(), response, nullptr);
            if (!error.isNull()) {
                setResourceError(error);
                this->error(LoadError);
                InspectorInstrumentation::didFailLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, error);
                return;
            }
            finishLoading(nullptr, { });
            NetworkLoadMetrics emptyMetrics;
            InspectorInstrumentation::didFinishLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, emptyMetrics, nullptr);
        });
        return;
    }

    platformStrategies()->loaderStrategy()->loadResource(frame, *this, WTFMove(request), m_options, [this, protectedThis = CachedResourceHandle<CachedResource>(this), frameRef = Ref { frame }] (RefPtr<SubresourceLoader>&& loader) {
        m_loader = WTFMove(loader);
        if (!m_loader) {
            RELEASE_LOG(Network, "%p - [pageID=%" PRIu64 ", frameID=%" PRIu64 "] CachedResource::load: Unable to create SubresourceLoader", this, PAGE_ID(frameRef.get()), FRAME_ID(frameRef.get()));
            failBeforeStarting();
            return;
        }
        setStatus(Pending);
    });
}

void CachedResource::loadFrom(const CachedResource& resource)
{
    ASSERT(url() == resource.url());
    ASSERT(type() == resource.type());
    ASSERT(resource.status() == Status::Cached);

    if (isCrossOrigin() && m_options.mode == FetchOptions::Mode::Cors) {
        ASSERT(m_origin);
        auto accessControlCheckResult = WebCore::passesAccessControlCheck(resource.response(), m_options.storedCredentialsPolicy, *m_origin, &CrossOriginAccessControlCheckDisabler::singleton());
        if (!accessControlCheckResult) {
            setResourceError(ResourceError(String(), 0, url(), accessControlCheckResult.error(), ResourceError::Type::AccessControl));
            return;
        }
    }

    setBodyDataFrom(resource);
    setStatus(Status::Cached);
    setLoading(false);
}

void CachedResource::setBodyDataFrom(const CachedResource& resource)
{
    m_data = resource.m_data;
    m_response = resource.m_response;
    m_response.setTainting(m_responseTainting);
    setDecodedSize(resource.decodedSize());
    setEncodedSize(resource.encodedSize());
}

void CachedResource::checkNotify(const NetworkLoadMetrics& metrics)
{
    if (isLoading() || stillNeedsLoad())
        return;

    CachedResourceClientWalker<CachedResourceClient> walker(m_clients);
    while (CachedResourceClient* client = walker.next())
        client->notifyFinished(*this, metrics);
}

void CachedResource::updateBuffer(const FragmentedSharedBuffer&)
{
    ASSERT(dataBufferingPolicy() == DataBufferingPolicy::BufferData);
}

void CachedResource::updateData(const SharedBuffer&)
{
    ASSERT(dataBufferingPolicy() == DataBufferingPolicy::DoNotBufferData);
}

void CachedResource::finishLoading(const FragmentedSharedBuffer*, const NetworkLoadMetrics& metrics)
{
    setLoading(false);
    checkNotify(metrics);
}

void CachedResource::error(CachedResource::Status status)
{
    setStatus(status);
    ASSERT(errorOccurred());
    m_data = nullptr;

    setLoading(false);
    checkNotify({ });
}
    
void CachedResource::cancelLoad()
{
    if (!isLoading() && !stillNeedsLoad())
        return;

    auto* documentLoader = (m_loader && m_loader->frame()) ? m_loader->frame()->loader().activeDocumentLoader() : nullptr;
    if (m_options.keepAlive && (!documentLoader || documentLoader->isStopping()))
        m_error = { };
    else
        setStatus(LoadError);

    setLoading(false);
    checkNotify({ });
}

void CachedResource::finish()
{
    if (!errorOccurred())
        setStatus(Cached);
}

void CachedResource::setCrossOrigin()
{
    ASSERT(m_options.mode != FetchOptions::Mode::SameOrigin);
    m_responseTainting = (m_options.mode == FetchOptions::Mode::Cors) ? ResourceResponse::Tainting::Cors : ResourceResponse::Tainting::Opaque;
}

bool CachedResource::isCrossOrigin() const
{
    return m_responseTainting != ResourceResponse::Tainting::Basic;
}

bool CachedResource::isCORSSameOrigin() const
{
    // Following resource types do not use CORS
    ASSERT(type() != Type::FontResource);
    ASSERT(type() != Type::SVGFontResource);
#if ENABLE(XSLT)
    ASSERT(type() != Type::XSLStyleSheet);
#endif

    // https://html.spec.whatwg.org/multipage/infrastructure.html#cors-same-origin
    return !loadFailedOrCanceled() && m_responseTainting != ResourceResponse::Tainting::Opaque;
}

bool CachedResource::isExpired() const
{
    if (m_response.isNull())
        return false;

    return computeCurrentAge(m_response, m_responseTimestamp) > freshnessLifetime(m_response);
}

static inline bool shouldCacheSchemeIndefinitely(StringView scheme)
{
#if PLATFORM(COCOA)
    if (equalLettersIgnoringASCIICase(scheme, "applewebdata"))
        return true;
#endif
#if USE(SOUP)
    if (equalLettersIgnoringASCIICase(scheme, "resource"))
        return true;
#endif
    return equalLettersIgnoringASCIICase(scheme, "data");
}

Seconds CachedResource::freshnessLifetime(const ResourceResponse& response) const
{
    if (!response.url().protocolIsInHTTPFamily()) {
        StringView protocol = response.url().protocol();
        if (!shouldCacheSchemeIndefinitely(protocol)) {
            // Don't cache non-HTTP main resources since we can't check for freshness.
            // FIXME: We should not cache subresources either, but when we tried this
            // it caused performance and flakiness issues in our test infrastructure.
            if (m_type == Type::MainResource || LegacySchemeRegistry::shouldAlwaysRevalidateURLScheme(protocol.toStringWithoutCopying()))
                return 0_us;
        }

        return Seconds::infinity();
    }

    return computeFreshnessLifetimeForHTTPFamily(response, m_responseTimestamp);
}

void CachedResource::redirectReceived(ResourceRequest&& request, const ResourceResponse& response, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
{
    CACHEDRESOURCE_RELEASE_LOG("redirectReceived:");

    m_requestedFromNetworkingLayer = true;
    if (!response.isNull())
        updateRedirectChainStatus(m_redirectChainCacheStatus, response);

    completionHandler(WTFMove(request));
}

#if ASSERT_ENABLED
static bool isOpaqueRedirectResponseWithoutLocationHeader(const ResourceResponse& response)
{
    return response.type() == ResourceResponse::Type::Opaqueredirect && response.isRedirection() && response.httpHeaderField(HTTPHeaderName::Location).isNull();
}
#endif

void CachedResource::setResponse(const ResourceResponse& response)
{
    ASSERT(m_response.type() == ResourceResponse::Type::Default || isOpaqueRedirectResponseWithoutLocationHeader(m_response));
    m_response = response;
    m_varyingHeaderValues = collectVaryingRequestHeaders(cookieJar(), m_resourceRequest, m_response);

#if ENABLE(SERVICE_WORKER)
    if (m_response.source() == ResourceResponse::Source::ServiceWorker) {
        m_responseTainting = m_response.tainting();
        return;
    }
#endif
    m_response.setRedirected(m_redirectChainCacheStatus.status != RedirectChainCacheStatus::Status::NoRedirection);
    if (m_response.tainting() == ResourceResponse::Tainting::Basic || m_response.tainting() == ResourceResponse::Tainting::Cors)
        m_response.setTainting(m_responseTainting);
}

void CachedResource::responseReceived(const ResourceResponse& response)
{
    setResponse(response);
    m_responseTimestamp = WallTime::now();
    String encoding = response.textEncodingName();
    if (!encoding.isNull())
        setEncoding(encoding);
}

void CachedResource::clearLoader()
{
    if (m_loader)
        m_identifierForLoadWithoutResourceLoader = m_loader->identifier();
    else
        ASSERT_NOT_REACHED();
    m_loader = nullptr;
    deleteIfPossible();
}

void CachedResource::addClient(CachedResourceClient& client)
{
    if (addClientToSet(client))
        didAddClient(client);
}

void CachedResource::didAddClient(CachedResourceClient& client)
{
    if (m_decodedDataDeletionTimer.isActive())
        m_decodedDataDeletionTimer.stop();

    if (m_clientsAwaitingCallback.remove(&client))
        m_clients.add(&client);

    // FIXME: Make calls to notifyFinished async
    if (!isLoading() && !stillNeedsLoad())
        client.notifyFinished(*this, { });
}

bool CachedResource::addClientToSet(CachedResourceClient& client)
{
    if (m_preloadResult == PreloadResult::PreloadNotReferenced && client.shouldMarkAsReferenced()) {
        if (isLoaded())
            m_preloadResult = PreloadResult::PreloadReferencedWhileComplete;
        else if (m_requestedFromNetworkingLayer)
            m_preloadResult = PreloadResult::PreloadReferencedWhileLoading;
        else
            m_preloadResult = PreloadResult::PreloadReferenced;
    }
    if (allowsCaching() && !hasClients() && inCache())
        MemoryCache::singleton().addToLiveResourcesSize(*this);

    if ((m_type == Type::RawResource || m_type == Type::MainResource) && !m_response.isNull() && !m_proxyResource) {
        // Certain resources (especially XHRs and main resources) do crazy things if an asynchronous load returns
        // synchronously (e.g., scripts may not have set all the state they need to handle the load).
        // Therefore, rather than immediately sending callbacks on a cache hit like other CachedResources,
        // we schedule the callbacks and ensure we never finish synchronously.
        ASSERT(!m_clientsAwaitingCallback.contains(&client));
        m_clientsAwaitingCallback.add(&client, makeUnique<Callback>(*this, client));
        return false;
    }

    m_clients.add(&client);
    return true;
}

void CachedResource::removeClient(CachedResourceClient& client)
{
    auto callback = m_clientsAwaitingCallback.take(&client);
    if (callback) {
        ASSERT(!m_clients.contains(&client));
        callback->cancel();
        callback = nullptr;
    } else {
        ASSERT(m_clients.contains(&client));
        m_clients.remove(&client);
        didRemoveClient(client);
    }

    if (hasClients())
        return;

    auto& memoryCache = MemoryCache::singleton();
    if (allowsCaching() && inCache()) {
        memoryCache.removeFromLiveResourcesSize(*this);
        memoryCache.removeFromLiveDecodedResourcesList(*this);
    }

    if (deleteIfPossible()) {
        // `this` object is dead here.
        return;
    }

    if (!m_switchingClientsToRevalidatedResource)
        allClientsRemoved();
    destroyDecodedDataIfNeeded();

    if (!allowsCaching())
        return;

    memoryCache.pruneSoon();
}

void CachedResource::allClientsRemoved()
{
    if (isLinkPreload() && m_loader)
        m_loader->cancelIfNotFinishing();
}

void CachedResource::destroyDecodedDataIfNeeded()
{
    if (!m_decodedSize)
        return;
    if (!MemoryCache::singleton().deadDecodedDataDeletionInterval())
        return;
    m_decodedDataDeletionTimer.restart();
}

void CachedResource::decodedDataDeletionTimerFired()
{
    destroyDecodedData();
}

bool CachedResource::deleteIfPossible()
{
    if (!canDelete()) {
        LOG(ResourceLoading, "CachedResource %p deleteIfPossible - can't delete (hasClients %d loader %p preloadCount %u handleCount %u resourceToRevalidate %p proxyResource %p)", this, hasClients(), m_loader.get(), m_preloadCount, m_handleCount, m_resourceToRevalidate, m_proxyResource);
        return false;
    }

    LOG(ResourceLoading, "CachedResource %p deleteIfPossible - can delete, in cache %d", this, inCache());

    if (!inCache()) {
        deleteThis();
        return true;
    }

    auto shouldRemoveFromCache = [&] {
        // We may still keeps some of these cases in disk cache for history navigation.
        if (response().cacheControlContainsNoStore())
            return true;
        if (isExpired() && !canUseCacheValidator())
            return true;
        return false;
    }();

    if (shouldRemoveFromCache) {
        // Deletes this.
        MemoryCache::singleton().remove(*this);
        return true;
    }

    if (m_data)
        m_data->hintMemoryNotNeededSoon();

    return false;
}

void CachedResource::deleteThis()
{
    RELEASE_ASSERT(canDelete());
    RELEASE_ASSERT(!inCache());

    InspectorInstrumentation::willDestroyCachedResource(*this);

    delete this;
}

void CachedResource::setDecodedSize(unsigned size)
{
    if (size == m_decodedSize)
        return;

    long long delta = static_cast<long long>(size) - m_decodedSize;

    // The object must be moved to a different queue, since its size has been changed.
    // Remove before updating m_decodedSize, so we find the resource in the correct LRU list.
    if (allowsCaching() && inCache())
        MemoryCache::singleton().removeFromLRUList(*this);

    m_decodedSize = size;
   
    if (allowsCaching() && inCache()) {
        auto& memoryCache = MemoryCache::singleton();
        // Now insert into the new LRU list.
        memoryCache.insertInLRUList(*this);
        
        // Insert into or remove from the live decoded list if necessary.
        // When inserting into the LiveDecodedResourcesList it is possible
        // that the m_lastDecodedAccessTime is still zero or smaller than
        // the m_lastDecodedAccessTime of the current list head. This is a
        // violation of the invariant that the list is to be kept sorted
        // by access time. The weakening of the invariant does not pose
        // a problem. For more details please see: https://bugs.webkit.org/show_bug.cgi?id=30209
        bool inLiveDecodedResourcesList = memoryCache.inLiveDecodedResourcesList(*this);
        if (m_decodedSize && !inLiveDecodedResourcesList && hasClients())
            memoryCache.insertInLiveDecodedResourcesList(*this);
        else if (!m_decodedSize && inLiveDecodedResourcesList)
            memoryCache.removeFromLiveDecodedResourcesList(*this);

        // Update the cache's size totals.
        memoryCache.adjustSize(hasClients(), delta);
    }
}

void CachedResource::setEncodedSize(unsigned size)
{
    if (size == m_encodedSize)
        return;

    long long delta = static_cast<long long>(size) - m_encodedSize;

    // The object must be moved to a different queue, since its size has been changed.
    // Remove before updating m_encodedSize, so we find the resource in the correct LRU list.
    if (allowsCaching() && inCache())
        MemoryCache::singleton().removeFromLRUList(*this);

    m_encodedSize = size;

    if (allowsCaching() && inCache()) {
        auto& memoryCache = MemoryCache::singleton();
        memoryCache.insertInLRUList(*this);
        memoryCache.adjustSize(hasClients(), delta);
    }
}

void CachedResource::didAccessDecodedData(MonotonicTime timeStamp)
{
    m_lastDecodedAccessTime = timeStamp;
    
    if (allowsCaching() && inCache()) {
        auto& memoryCache = MemoryCache::singleton();
        if (memoryCache.inLiveDecodedResourcesList(*this)) {
            memoryCache.removeFromLiveDecodedResourcesList(*this);
            memoryCache.insertInLiveDecodedResourcesList(*this);
        }
        memoryCache.pruneSoon();
    }
}
    
void CachedResource::setResourceToRevalidate(CachedResource* resource) 
{ 
    ASSERT(resource);
    ASSERT(!m_resourceToRevalidate);
    ASSERT(resource != this);
    ASSERT(m_handlesToRevalidate.isEmpty());
    ASSERT(resource->type() == type());
    ASSERT(!resource->m_proxyResource);

    LOG(ResourceLoading, "CachedResource %p setResourceToRevalidate %p", this, resource);

    resource->m_proxyResource = this;
    m_resourceToRevalidate = resource;
}

void CachedResource::clearResourceToRevalidate() 
{
    ASSERT(m_resourceToRevalidate);
    ASSERT(m_resourceToRevalidate->m_proxyResource == this);

    if (m_switchingClientsToRevalidatedResource)
        return;

    m_resourceToRevalidate->m_proxyResource = nullptr;
    m_resourceToRevalidate->deleteIfPossible();

    m_handlesToRevalidate.clear();
    m_resourceToRevalidate = nullptr;
    deleteIfPossible();
}
    
void CachedResource::switchClientsToRevalidatedResource()
{
    ASSERT(m_resourceToRevalidate);
    ASSERT(m_resourceToRevalidate->inCache());
    ASSERT(!inCache());

    LOG(ResourceLoading, "CachedResource %p switchClientsToRevalidatedResource %p", this, m_resourceToRevalidate);

    m_switchingClientsToRevalidatedResource = true;
    for (auto& handle : m_handlesToRevalidate) {
        handle->m_resource = m_resourceToRevalidate;
        m_resourceToRevalidate->registerHandle(handle);
        --m_handleCount;
    }
    ASSERT(!m_handleCount);
    m_handlesToRevalidate.clear();

    Vector<CachedResourceClient*> clientsToMove;
    for (auto& entry : m_clients) {
        CachedResourceClient* client = entry.key;
        unsigned count = entry.value;
        while (count) {
            clientsToMove.append(client);
            --count;
        }
    }

    for (auto& client : clientsToMove)
        removeClient(*client);
    ASSERT(m_clients.isEmpty());

    for (auto& client : clientsToMove)
        m_resourceToRevalidate->addClientToSet(*client);
    for (auto& client : clientsToMove) {
        // Calling didAddClient may do anything, including trying to cancel revalidation.
        // Assert that it didn't succeed.
        ASSERT(m_resourceToRevalidate);
        // 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(client))
            m_resourceToRevalidate->didAddClient(*client);
    }
    m_switchingClientsToRevalidatedResource = false;
}

void CachedResource::updateResponseAfterRevalidation(const ResourceResponse& validatingResponse)
{
    m_responseTimestamp = WallTime::now();

    updateResponseHeadersAfterRevalidation(m_response, validatingResponse);
}

void CachedResource::registerHandle(CachedResourceHandleBase* h)
{
    ++m_handleCount;
    if (m_resourceToRevalidate)
        m_handlesToRevalidate.add(h);
}

void CachedResource::unregisterHandle(CachedResourceHandleBase* h)
{
    ASSERT(m_handleCount > 0);
    --m_handleCount;

    if (m_resourceToRevalidate)
         m_handlesToRevalidate.remove(h);

    if (!m_handleCount)
        deleteIfPossible();
}

bool CachedResource::canUseCacheValidator() const
{
    if (m_loading || errorOccurred())
        return false;

    if (m_response.cacheControlContainsNoStore())
        return false;
    // Network process will handle revalidation for s-w-r.
    if (m_response.cacheControlStaleWhileRevalidate())
        return false;
    return m_response.hasCacheValidatorFields();
}

CachedResource::RevalidationDecision CachedResource::makeRevalidationDecision(CachePolicy cachePolicy) const
{    
    switch (cachePolicy) {
    case CachePolicy::HistoryBuffer:
        return RevalidationDecision::No;

    case CachePolicy::Reload:
        return RevalidationDecision::YesDueToCachePolicy;

    case CachePolicy::Revalidate:
        if (m_response.cacheControlContainsImmutable() && m_response.url().protocolIs("https")) {
            if (isExpired())
                return RevalidationDecision::YesDueToExpired;
            return RevalidationDecision::No;
        }
        return RevalidationDecision::YesDueToCachePolicy;

    case CachePolicy::Verify:
        if (m_response.cacheControlContainsNoCache())
            return RevalidationDecision::YesDueToNoCache;
        // FIXME: Cache-Control:no-store should prevent storing, not reuse.
        if (m_response.cacheControlContainsNoStore())
            return RevalidationDecision::YesDueToNoStore;

        if (isExpired())
            return RevalidationDecision::YesDueToExpired;

        return RevalidationDecision::No;
    };
    ASSERT_NOT_REACHED();
    return RevalidationDecision::No;
}

bool CachedResource::redirectChainAllowsReuse(ReuseExpiredRedirectionOrNot reuseExpiredRedirection) const
{
    return WebCore::redirectChainAllowsReuse(m_redirectChainCacheStatus, reuseExpiredRedirection);
}

bool CachedResource::varyHeaderValuesMatch(const ResourceRequest& request)
{
    if (m_varyingHeaderValues.isEmpty())
        return true;

    return verifyVaryingRequestHeaders(cookieJar(), m_varyingHeaderValues, request);
}

unsigned CachedResource::overheadSize() const
{
    static const int kAverageClientsHashMapSize = 384;
    return sizeof(CachedResource) + m_response.memoryUsage() + kAverageClientsHashMapSize + m_resourceRequest.url().string().length() * 2;
}

void CachedResource::setLoadPriority(const std::optional<ResourceLoadPriority>& loadPriority)
{
    if (loadPriority)
        m_loadPriority = loadPriority.value();
    else
        m_loadPriority = DefaultResourceLoadPriority::forResourceType(type());
}

inline CachedResource::Callback::Callback(CachedResource& resource, CachedResourceClient& client)
    : m_resource(resource)
    , m_client(client)
    , m_timer(*this, &Callback::timerFired)
{
    m_timer.startOneShot(0_s);
}

inline void CachedResource::Callback::cancel()
{
    if (m_timer.isActive())
        m_timer.stop();
}

void CachedResource::Callback::timerFired()
{
    m_resource.didAddClient(m_client);
}

#if ENABLE(SHAREABLE_RESOURCE)

void CachedResource::tryReplaceEncodedData(SharedBuffer& newBuffer)
{
    if (!m_data)
        return;
    
    if (!mayTryReplaceEncodedData())
        return;

    // We have to compare the buffers because we can't tell if the replacement file backed data is for the
    // same resource or if we made a second request with the same URL which gave us a different resource.
    // We have seen this happen for cached POST resources.
    if (*m_data != newBuffer)
        return;

    m_data = Ref { newBuffer };
    didReplaceSharedBufferContents();
}

#endif

#if USE(QUICK_LOOK)

void CachedResource::previewResponseReceived(const ResourceResponse& response)
{
    ASSERT(response.url().protocolIs(QLPreviewProtocol));
    CachedResource::responseReceived(response);
}

#endif

}

#undef PAGE_ID
#undef FRAME_ID
#undef CACHEDRESOURCE_RELEASE_LOG
#undef CACHEDRESOURCE_RELEASE_LOG_WITH_FRAME
