WebCore/loader/CachedResource.h
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2     Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
       
     3     Copyright (C) 2001 Dirk Mueller <mueller@kde.org>
       
     4     Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
       
     5     Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
       
     6 
       
     7     This library is free software; you can redistribute it and/or
       
     8     modify it under the terms of the GNU Library General Public
       
     9     License as published by the Free Software Foundation; either
       
    10     version 2 of the License, or (at your option) any later version.
       
    11 
       
    12     This library is distributed in the hope that it will be useful,
       
    13     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    15     Library General Public License for more details.
       
    16 
       
    17     You should have received a copy of the GNU Library General Public License
       
    18     along with this library; see the file COPYING.LIB.  If not, write to
       
    19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    20     Boston, MA 02110-1301, USA.
       
    21 */
       
    22 
       
    23 #ifndef CachedResource_h
       
    24 #define CachedResource_h
       
    25 
       
    26 #include "CachePolicy.h"
       
    27 #include "FrameLoaderTypes.h"
       
    28 #include "PlatformString.h"
       
    29 #include "ResourceResponse.h"
       
    30 #include <wtf/HashCountedSet.h>
       
    31 #include <wtf/HashSet.h>
       
    32 #include <wtf/OwnPtr.h>
       
    33 #include <wtf/Vector.h>
       
    34 #include <time.h>
       
    35 
       
    36 namespace WebCore {
       
    37 
       
    38 class Cache;
       
    39 class CachedMetadata;
       
    40 class CachedResourceClient;
       
    41 class CachedResourceHandleBase;
       
    42 class DocLoader;
       
    43 class Frame;
       
    44 class InspectorResource;
       
    45 class Request;
       
    46 class PurgeableBuffer;
       
    47 
       
    48 // A resource that is held in the cache. Classes who want to use this object should derive
       
    49 // from CachedResourceClient, to get the function calls in case the requested data has arrived.
       
    50 // This class also does the actual communication with the loader to obtain the resource from the network.
       
    51 class CachedResource : public Noncopyable {
       
    52     friend class Cache;
       
    53     friend class InspectorResource;
       
    54     
       
    55 public:
       
    56     enum Type {
       
    57         ImageResource,
       
    58         CSSStyleSheet,
       
    59         Script,
       
    60         FontResource
       
    61 #if ENABLE(XSLT)
       
    62         , XSLStyleSheet
       
    63 #endif
       
    64 #if ENABLE(XBL)
       
    65         , XBL
       
    66 #endif
       
    67 #if ENABLE(LINK_PREFETCH)
       
    68         , LinkPrefetch
       
    69 #endif
       
    70     };
       
    71 
       
    72     enum Status {
       
    73         NotCached,    // this URL is not cached
       
    74         Unknown,      // let cache decide what to do with it
       
    75         New,          // inserting new item
       
    76         Pending,      // only partially loaded
       
    77         Cached        // regular case
       
    78     };
       
    79 
       
    80     CachedResource(const String& url, Type);
       
    81     virtual ~CachedResource();
       
    82     
       
    83     virtual void load(DocLoader* docLoader)  { load(docLoader, false, DoSecurityCheck, true); }
       
    84     void load(DocLoader*, bool incremental, SecurityCheckPolicy, bool sendResourceLoadCallbacks);
       
    85 
       
    86     virtual void setEncoding(const String&) { }
       
    87     virtual String encoding() const { return String(); }
       
    88     virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived);
       
    89     virtual void error() { }
       
    90     virtual void httpStatusCodeError() { error(); } // Images keep loading in spite of HTTP errors (for legacy compat with <img>, etc.).
       
    91 
       
    92     const String &url() const { return m_url; }
       
    93     Type type() const { return static_cast<Type>(m_type); }
       
    94 
       
    95     void addClient(CachedResourceClient*);
       
    96     void removeClient(CachedResourceClient*);
       
    97     bool hasClients() const { return !m_clients.isEmpty(); }
       
    98     void deleteIfPossible();
       
    99 
       
   100     enum PreloadResult {
       
   101         PreloadNotReferenced,
       
   102         PreloadReferenced,
       
   103         PreloadReferencedWhileLoading,
       
   104         PreloadReferencedWhileComplete
       
   105     };
       
   106     PreloadResult preloadResult() const { return static_cast<PreloadResult>(m_preloadResult); }
       
   107     void setRequestedFromNetworkingLayer() { m_requestedFromNetworkingLayer = true; }
       
   108 
       
   109     virtual void didAddClient(CachedResourceClient*);
       
   110     virtual void allClientsRemoved() { }
       
   111 
       
   112     unsigned count() const { return m_clients.size(); }
       
   113 
       
   114     Status status() const { return static_cast<Status>(m_status); }
       
   115     void setStatus(Status status) { m_status = status; }
       
   116 
       
   117     unsigned size() const { return encodedSize() + decodedSize() + overheadSize(); }
       
   118     unsigned encodedSize() const { return m_encodedSize; }
       
   119     unsigned decodedSize() const { return m_decodedSize; }
       
   120     unsigned overheadSize() const;
       
   121     
       
   122     bool isLoaded() const { return !m_loading; } // FIXME. Method name is inaccurate. Loading might not have started yet.
       
   123 
       
   124     bool isLoading() const { return m_loading; }
       
   125     void setLoading(bool b) { m_loading = b; }
       
   126 
       
   127     virtual bool isImage() const { return false; }
       
   128     bool isPrefetch() const
       
   129     {
       
   130 #if ENABLE(LINK_PREFETCH)
       
   131         return type() == LinkPrefetch;
       
   132 #else
       
   133         return false;
       
   134 #endif
       
   135     }
       
   136 
       
   137     unsigned accessCount() const { return m_accessCount; }
       
   138     void increaseAccessCount() { m_accessCount++; }
       
   139 
       
   140     // Computes the status of an object after loading.  
       
   141     // Updates the expire date on the cache entry file
       
   142     void finish();
       
   143 
       
   144     // Called by the cache if the object has been removed from the cache
       
   145     // while still being referenced. This means the object should delete itself
       
   146     // if the number of clients observing it ever drops to 0.
       
   147     // The resource can be brought back to cache after successful revalidation.
       
   148     void setInCache(bool inCache) { m_inCache = inCache; }
       
   149     bool inCache() const { return m_inCache; }
       
   150     
       
   151     void setInLiveDecodedResourcesList(bool b) { m_inLiveDecodedResourcesList = b; }
       
   152     bool inLiveDecodedResourcesList() { return m_inLiveDecodedResourcesList; }
       
   153     
       
   154     void setRequest(Request*);
       
   155 
       
   156     SharedBuffer* data() const { ASSERT(!m_purgeableData); return m_data.get(); }
       
   157 
       
   158     void setResponse(const ResourceResponse&);
       
   159     const ResourceResponse& response() const { return m_response; }
       
   160 
       
   161     // Sets the serialized metadata retrieved from the platform's cache.
       
   162     void setSerializedCachedMetadata(const char*, size_t);
       
   163 
       
   164     // Caches the given metadata in association with this resource and suggests
       
   165     // that the platform persist it. The dataTypeID is a pseudo-randomly chosen
       
   166     // identifier that is used to distinguish data generated by the caller.
       
   167     void setCachedMetadata(unsigned dataTypeID, const char*, size_t);
       
   168 
       
   169     // Returns cached metadata of the given type associated with this resource.
       
   170     CachedMetadata* cachedMetadata(unsigned dataTypeID) const;
       
   171 
       
   172     bool canDelete() const { return !hasClients() && !m_request && !m_preloadCount && !m_handleCount && !m_resourceToRevalidate && !m_proxyResource; }
       
   173 
       
   174     bool isExpired() const;
       
   175 
       
   176     // List of acceptable MIME types separated by ",".
       
   177     // A MIME type may contain a wildcard, e.g. "text/*".
       
   178     String accept() const { return m_accept; }
       
   179     void setAccept(const String& accept) { m_accept = accept; }
       
   180 
       
   181     bool errorOccurred() const { return m_errorOccurred; }
       
   182     void setErrorOccurred(bool b) { m_errorOccurred = b; }
       
   183 
       
   184     bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
       
   185     
       
   186     virtual void destroyDecodedData() { }
       
   187 
       
   188     void setDocLoader(DocLoader* docLoader) { m_docLoader = docLoader; }
       
   189     
       
   190     bool isPreloaded() const { return m_preloadCount; }
       
   191     void increasePreloadCount() { ++m_preloadCount; }
       
   192     void decreasePreloadCount() { ASSERT(m_preloadCount); --m_preloadCount; }
       
   193     
       
   194     void registerHandle(CachedResourceHandleBase* h) { ++m_handleCount; if (m_resourceToRevalidate) m_handlesToRevalidate.add(h); }
       
   195     void unregisterHandle(CachedResourceHandleBase* h) { ASSERT(m_handleCount > 0); --m_handleCount; if (m_resourceToRevalidate) m_handlesToRevalidate.remove(h); if (!m_handleCount) deleteIfPossible(); }
       
   196     
       
   197     bool canUseCacheValidator() const;
       
   198     bool mustRevalidate(CachePolicy) const;
       
   199     bool isCacheValidator() const { return m_resourceToRevalidate; }
       
   200     CachedResource* resourceToRevalidate() const { return m_resourceToRevalidate; }
       
   201     
       
   202     bool isPurgeable() const;
       
   203     bool wasPurged() const;
       
   204     
       
   205     // This is used by the archive machinery to get at a purged resource without
       
   206     // triggering a load. We should make it protected again if we can find a
       
   207     // better way to handle the archive case.
       
   208     bool makePurgeable(bool purgeable);
       
   209 
       
   210 protected:
       
   211     void setEncodedSize(unsigned);
       
   212     void setDecodedSize(unsigned);
       
   213     void didAccessDecodedData(double timeStamp);
       
   214 
       
   215     bool isSafeToMakePurgeable() const;
       
   216     
       
   217     HashCountedSet<CachedResourceClient*> m_clients;
       
   218 
       
   219     String m_url;
       
   220     String m_accept;
       
   221     Request* m_request;
       
   222 
       
   223     ResourceResponse m_response;
       
   224     double m_responseTimestamp;
       
   225 
       
   226     RefPtr<SharedBuffer> m_data;
       
   227     OwnPtr<PurgeableBuffer> m_purgeableData;
       
   228 
       
   229 private:
       
   230     void addClientToSet(CachedResourceClient*);
       
   231                                         
       
   232     // These are called by the friendly Cache only
       
   233     void setResourceToRevalidate(CachedResource*);
       
   234     void switchClientsToRevalidatedResource();
       
   235     void clearResourceToRevalidate();
       
   236     void updateResponseAfterRevalidation(const ResourceResponse& validatingResponse);
       
   237 
       
   238     double currentAge() const;
       
   239     double freshnessLifetime() const;
       
   240 
       
   241     RefPtr<CachedMetadata> m_cachedMetadata;
       
   242 
       
   243     double m_lastDecodedAccessTime; // Used as a "thrash guard" in the cache
       
   244 
       
   245     unsigned m_encodedSize;
       
   246     unsigned m_decodedSize;
       
   247     unsigned m_accessCount;
       
   248     unsigned m_handleCount;
       
   249     unsigned m_preloadCount;
       
   250 
       
   251     unsigned m_preloadResult : 2; // PreloadResult
       
   252 
       
   253     bool m_inLiveDecodedResourcesList : 1;
       
   254     bool m_requestedFromNetworkingLayer : 1;
       
   255     bool m_sendResourceLoadCallbacks : 1;
       
   256 
       
   257     bool m_errorOccurred : 1;
       
   258     bool m_inCache : 1;
       
   259     bool m_loading : 1;
       
   260 
       
   261     unsigned m_type : 3; // Type
       
   262     unsigned m_status : 3; // Status
       
   263 
       
   264 #ifndef NDEBUG
       
   265     bool m_deleted;
       
   266     unsigned m_lruIndex;
       
   267 #endif
       
   268 
       
   269     CachedResource* m_nextInAllResourcesList;
       
   270     CachedResource* m_prevInAllResourcesList;
       
   271     
       
   272     CachedResource* m_nextInLiveResourcesList;
       
   273     CachedResource* m_prevInLiveResourcesList;
       
   274 
       
   275     DocLoader* m_docLoader; // only non-0 for resources that are not in the cache
       
   276     
       
   277     // If this field is non-null we are using the resource as a proxy for checking whether an existing resource is still up to date
       
   278     // using HTTP If-Modified-Since/If-None-Match headers. If the response is 304 all clients of this resource are moved
       
   279     // to to be clients of m_resourceToRevalidate and the resource is deleted. If not, the field is zeroed and this
       
   280     // resources becomes normal resource load.
       
   281     CachedResource* m_resourceToRevalidate;
       
   282 
       
   283     // If this field is non-null, the resource has a proxy for checking whether it is still up to date (see m_resourceToRevalidate).
       
   284     CachedResource* m_proxyResource;
       
   285 
       
   286     // These handles will need to be updated to point to the m_resourceToRevalidate in case we get 304 response.
       
   287     HashSet<CachedResourceHandleBase*> m_handlesToRevalidate;
       
   288 };
       
   289 
       
   290 }
       
   291 
       
   292 #endif