Home | History | Annotate | Download | only in cache
      1 /*
      2     Copyright (C) 1998 Lars Knoll (knoll (at) mpi-hd.mpg.de)
      3     Copyright (C) 2001 Dirk Mueller <mueller (at) kde.org>
      4     Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
      5     Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
      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     This class provides all functionality needed for loading images, style sheets and html
     23     pages from the web. It has a memory cache for these objects.
     24 */
     25 
     26 #ifndef ResourceFetcher_h
     27 #define ResourceFetcher_h
     28 
     29 #include "core/loader/ResourceLoaderHost.h"
     30 #include "core/loader/cache/CachePolicy.h"
     31 #include "core/loader/cache/FetchInitiatorInfo.h"
     32 #include "core/loader/cache/FetchRequest.h"
     33 #include "core/loader/cache/Resource.h"
     34 #include "core/loader/cache/ResourcePtr.h"
     35 #include "core/platform/Timer.h"
     36 #include "wtf/Deque.h"
     37 #include "wtf/HashMap.h"
     38 #include "wtf/HashSet.h"
     39 #include "wtf/ListHashSet.h"
     40 #include "wtf/text/StringHash.h"
     41 
     42 namespace WebCore {
     43 
     44 class CSSStyleSheetResource;
     45 class DocumentResource;
     46 class FontResource;
     47 class ImageResource;
     48 class RawResource;
     49 class ScriptResource;
     50 class ShaderResource;
     51 class TextTrackResource;
     52 class XSLStyleSheetResource;
     53 class Document;
     54 class DocumentLoader;
     55 class Frame;
     56 class FrameLoader;
     57 class ImageLoader;
     58 class KURL;
     59 class ResourceTimingInfo;
     60 
     61 // The ResourceFetcher provides a per-context interface to the MemoryCache
     62 // and enforces a bunch of security checks and rules for resource revalidation.
     63 // Its lifetime is roughly per-DocumentLoader, in that it is generally created
     64 // in the DocumentLoader constructor and loses its ability to generate network
     65 // requests when the DocumentLoader is destroyed. Documents also hold a
     66 // RefPtr<ResourceFetcher> for their lifetime (and will create one if they
     67 // are initialized without a Frame), so a Document can keep a ResourceFetcher
     68 // alive past detach if scripts still reference the Document.
     69 class ResourceFetcher : public RefCounted<ResourceFetcher>, public ResourceLoaderHost {
     70     WTF_MAKE_NONCOPYABLE(ResourceFetcher); WTF_MAKE_FAST_ALLOCATED;
     71 friend class ImageLoader;
     72 friend class ResourceCacheValidationSuppressor;
     73 
     74 public:
     75     static PassRefPtr<ResourceFetcher> create(DocumentLoader* documentLoader) { return adoptRef(new ResourceFetcher(documentLoader)); }
     76     virtual ~ResourceFetcher();
     77 
     78     using RefCounted<ResourceFetcher>::ref;
     79     using RefCounted<ResourceFetcher>::deref;
     80 
     81     ResourcePtr<ImageResource> requestImage(FetchRequest&);
     82     ResourcePtr<CSSStyleSheetResource> requestCSSStyleSheet(FetchRequest&);
     83     ResourcePtr<CSSStyleSheetResource> requestUserCSSStyleSheet(FetchRequest&);
     84     ResourcePtr<ScriptResource> requestScript(FetchRequest&);
     85     ResourcePtr<FontResource> requestFont(FetchRequest&);
     86     ResourcePtr<RawResource> requestRawResource(FetchRequest&);
     87     ResourcePtr<RawResource> requestMainResource(FetchRequest&);
     88     ResourcePtr<DocumentResource> requestSVGDocument(FetchRequest&);
     89     ResourcePtr<XSLStyleSheetResource> requestXSLStyleSheet(FetchRequest&);
     90     ResourcePtr<Resource> requestLinkResource(Resource::Type, FetchRequest&);
     91     ResourcePtr<TextTrackResource> requestTextTrack(FetchRequest&);
     92     ResourcePtr<ShaderResource> requestShader(FetchRequest&);
     93     ResourcePtr<RawResource> requestImport(FetchRequest&);
     94 
     95     // Logs an access denied message to the console for the specified URL.
     96     void printAccessDeniedMessage(const KURL&) const;
     97 
     98     Resource* cachedResource(const String& url) const;
     99     Resource* cachedResource(const KURL&) const;
    100 
    101     typedef HashMap<String, ResourcePtr<Resource> > DocumentResourceMap;
    102     const DocumentResourceMap& allResources() const { return m_documentResources; }
    103 
    104     bool autoLoadImages() const { return m_autoLoadImages; }
    105     void setAutoLoadImages(bool);
    106 
    107     void setImagesEnabled(bool);
    108 
    109     bool shouldDeferImageLoad(const KURL&) const;
    110 
    111     CachePolicy cachePolicy(Resource::Type) const;
    112 
    113     Frame* frame() const; // Can be null
    114     Document* document() const { return m_document; } // Can be null
    115     void setDocument(Document* document) { m_document = document; }
    116 
    117     DocumentLoader* documentLoader() const { return m_documentLoader; }
    118     void clearDocumentLoader() { m_documentLoader = 0; }
    119 
    120     void garbageCollectDocumentResources();
    121 
    122     int requestCount() const { return m_requestCount; }
    123 
    124     bool isPreloaded(const String& urlString) const;
    125     void clearPreloads();
    126     void clearPendingPreloads();
    127     void preload(Resource::Type, FetchRequest&, const String& charset);
    128     void checkForPendingPreloads();
    129     void printPreloadStats();
    130     bool canRequest(Resource::Type, const KURL&, const ResourceLoaderOptions&, bool forPreload = false);
    131     bool canAccess(Resource*);
    132 
    133     // ResourceLoaderHost
    134     virtual void incrementRequestCount(const Resource*) OVERRIDE;
    135     virtual void decrementRequestCount(const Resource*) OVERRIDE;
    136     virtual void didLoadResource(Resource*) OVERRIDE;
    137     virtual void redirectReceived(Resource*, const ResourceResponse&) OVERRIDE;
    138     virtual void didFinishLoading(const Resource*, double finishTime, const ResourceLoaderOptions&) OVERRIDE;
    139     virtual void didChangeLoadingPriority(const Resource*, ResourceLoadPriority) OVERRIDE;
    140     virtual void didFailLoading(const Resource*, const ResourceError&, const ResourceLoaderOptions&) OVERRIDE;
    141     virtual void willSendRequest(const Resource*, ResourceRequest&, const ResourceResponse& redirectResponse, const ResourceLoaderOptions&) OVERRIDE;
    142     virtual void didReceiveResponse(const Resource*, const ResourceResponse&, const ResourceLoaderOptions&) OVERRIDE;
    143     virtual void didReceiveData(const Resource*, const char* data, int dataLength, int encodedDataLength, const ResourceLoaderOptions&) OVERRIDE;
    144     virtual void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*) OVERRIDE;
    145     virtual void didInitializeResourceLoader(ResourceLoader*) OVERRIDE;
    146     virtual void willTerminateResourceLoader(ResourceLoader*) OVERRIDE;
    147     virtual void willStartLoadingResource(ResourceRequest&) OVERRIDE;
    148     virtual bool defersLoading() const OVERRIDE;
    149     virtual bool isLoadedBy(ResourceLoaderHost*) const OVERRIDE;
    150     virtual bool shouldRequest(Resource*, const ResourceRequest&, const ResourceLoaderOptions&) OVERRIDE;
    151     virtual void refResourceLoaderHost() OVERRIDE;
    152     virtual void derefResourceLoaderHost() OVERRIDE;
    153 
    154     static const ResourceLoaderOptions& defaultResourceOptions();
    155 private:
    156 
    157     explicit ResourceFetcher(DocumentLoader*);
    158 
    159     FrameLoader* frameLoader();
    160     bool shouldLoadNewResource() const;
    161 
    162     ResourcePtr<Resource> requestResource(Resource::Type, FetchRequest&);
    163     ResourcePtr<Resource> revalidateResource(const FetchRequest&, Resource*);
    164     ResourcePtr<Resource> loadResource(Resource::Type, FetchRequest&, const String& charset);
    165     void preCacheDataURIImage(const FetchRequest&);
    166     void storeResourceTimingInitiatorInformation(const ResourcePtr<Resource>&, const FetchRequest&);
    167     void requestPreload(Resource::Type, FetchRequest&, const String& charset);
    168 
    169     enum RevalidationPolicy { Use, Revalidate, Reload, Load };
    170     RevalidationPolicy determineRevalidationPolicy(Resource::Type, ResourceRequest&, bool forPreload, Resource* existingResource, FetchRequest::DeferOption) const;
    171 
    172     void determineTargetType(ResourceRequest&, Resource::Type);
    173     ResourceRequestCachePolicy resourceRequestCachePolicy(const ResourceRequest&, Resource::Type);
    174     void addAdditionalRequestHeaders(ResourceRequest&, Resource::Type);
    175 
    176     void notifyLoadedFromMemoryCache(Resource*);
    177     bool checkInsecureContent(Resource::Type, const KURL&) const;
    178 
    179     void garbageCollectDocumentResourcesTimerFired(Timer<ResourceFetcher>*);
    180     void performPostLoadActions();
    181 
    182     bool clientDefersImage(const KURL&) const;
    183     void reloadImagesIfNotDeferred();
    184 
    185     HashSet<String> m_validatedURLs;
    186     mutable DocumentResourceMap m_documentResources;
    187     Document* m_document;
    188     DocumentLoader* m_documentLoader;
    189 
    190     int m_requestCount;
    191 
    192     OwnPtr<ListHashSet<Resource*> > m_preloads;
    193     struct PendingPreload {
    194         Resource::Type m_type;
    195         FetchRequest m_request;
    196         String m_charset;
    197     };
    198     Deque<PendingPreload> m_pendingPreloads;
    199 
    200     Timer<ResourceFetcher> m_garbageCollectDocumentResourcesTimer;
    201 
    202     typedef HashMap<Resource*, RefPtr<ResourceTimingInfo> > ResourceTimingInfoMap;
    203     ResourceTimingInfoMap m_resourceTimingInfoMap;
    204 
    205     // 29 bits left
    206     bool m_autoLoadImages : 1;
    207     bool m_imagesEnabled : 1;
    208     bool m_allowStaleResources : 1;
    209 };
    210 
    211 class ResourceCacheValidationSuppressor {
    212     WTF_MAKE_NONCOPYABLE(ResourceCacheValidationSuppressor);
    213     WTF_MAKE_FAST_ALLOCATED;
    214 public:
    215     ResourceCacheValidationSuppressor(ResourceFetcher* loader)
    216         : m_loader(loader)
    217         , m_previousState(false)
    218     {
    219         if (m_loader) {
    220             m_previousState = m_loader->m_allowStaleResources;
    221             m_loader->m_allowStaleResources = true;
    222         }
    223     }
    224     ~ResourceCacheValidationSuppressor()
    225     {
    226         if (m_loader)
    227             m_loader->m_allowStaleResources = m_previousState;
    228     }
    229 private:
    230     ResourceFetcher* m_loader;
    231     bool m_previousState;
    232 };
    233 
    234 } // namespace WebCore
    235 
    236 #endif
    237