Home | History | Annotate | Download | only in fetch
      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/fetch/CachePolicy.h"
     30 #include "core/fetch/FetchInitiatorInfo.h"
     31 #include "core/fetch/FetchRequest.h"
     32 #include "core/fetch/Resource.h"
     33 #include "core/fetch/ResourceLoaderHost.h"
     34 #include "core/fetch/ResourceLoaderOptions.h"
     35 #include "core/fetch/ResourcePtr.h"
     36 #include "platform/Timer.h"
     37 #include "wtf/Deque.h"
     38 #include "wtf/HashMap.h"
     39 #include "wtf/HashSet.h"
     40 #include "wtf/ListHashSet.h"
     41 #include "wtf/text/StringHash.h"
     42 
     43 namespace WebCore {
     44 
     45 class CSSStyleSheetResource;
     46 class DocumentResource;
     47 class FetchContext;
     48 class FontResource;
     49 class ImageResource;
     50 class RawResource;
     51 class ScriptResource;
     52 class SubstituteData;
     53 class XSLStyleSheetResource;
     54 class Document;
     55 class DocumentLoader;
     56 class LocalFrame;
     57 class FrameLoader;
     58 class ImageLoader;
     59 class KURL;
     60 class ResourceTimingInfo;
     61 class ResourceLoaderSet;
     62 
     63 // The ResourceFetcher provides a per-context interface to the MemoryCache
     64 // and enforces a bunch of security checks and rules for resource revalidation.
     65 // Its lifetime is roughly per-DocumentLoader, in that it is generally created
     66 // in the DocumentLoader constructor and loses its ability to generate network
     67 // requests when the DocumentLoader is destroyed. Documents also hold a
     68 // RefPtr<ResourceFetcher> for their lifetime (and will create one if they
     69 // are initialized without a LocalFrame), so a Document can keep a ResourceFetcher
     70 // alive past detach if scripts still reference the Document.
     71 class ResourceFetcher FINAL : public RefCountedWillBeGarbageCollectedFinalized<ResourceFetcher>, public ResourceLoaderHost {
     72     WTF_MAKE_NONCOPYABLE(ResourceFetcher); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
     73     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(ResourceFetcher);
     74 friend class ImageLoader;
     75 friend class ResourceCacheValidationSuppressor;
     76 
     77 public:
     78     static PassRefPtrWillBeRawPtr<ResourceFetcher> create(DocumentLoader* documentLoader) { return adoptRefWillBeNoop(new ResourceFetcher(documentLoader)); }
     79     virtual ~ResourceFetcher();
     80     virtual void trace(Visitor*);
     81 
     82 #if !ENABLE(OILPAN)
     83     using RefCounted<ResourceFetcher>::ref;
     84     using RefCounted<ResourceFetcher>::deref;
     85 #endif
     86 
     87     ResourcePtr<Resource> fetchSynchronously(FetchRequest&);
     88     ResourcePtr<ImageResource> fetchImage(FetchRequest&);
     89     ResourcePtr<CSSStyleSheetResource> fetchCSSStyleSheet(FetchRequest&);
     90     ResourcePtr<CSSStyleSheetResource> fetchUserCSSStyleSheet(FetchRequest&);
     91     ResourcePtr<ScriptResource> fetchScript(FetchRequest&);
     92     ResourcePtr<FontResource> fetchFont(FetchRequest&);
     93     ResourcePtr<RawResource> fetchRawResource(FetchRequest&);
     94     ResourcePtr<RawResource> fetchMainResource(FetchRequest&, const SubstituteData&);
     95     ResourcePtr<DocumentResource> fetchSVGDocument(FetchRequest&);
     96     ResourcePtr<XSLStyleSheetResource> fetchXSLStyleSheet(FetchRequest&);
     97     ResourcePtr<Resource> fetchLinkResource(Resource::Type, FetchRequest&);
     98     ResourcePtr<RawResource> fetchImport(FetchRequest&);
     99     ResourcePtr<RawResource> fetchMedia(FetchRequest&);
    100     ResourcePtr<RawResource> fetchTextTrack(FetchRequest&);
    101 
    102     // Logs an access denied message to the console for the specified URL.
    103     void printAccessDeniedMessage(const KURL&) const;
    104 
    105     Resource* cachedResource(const KURL&) const;
    106 
    107     typedef HashMap<String, ResourcePtr<Resource> > DocumentResourceMap;
    108     const DocumentResourceMap& allResources() const { return m_documentResources; }
    109 
    110     bool autoLoadImages() const { return m_autoLoadImages; }
    111     void setAutoLoadImages(bool);
    112 
    113     void setImagesEnabled(bool);
    114 
    115     bool shouldDeferImageLoad(const KURL&) const;
    116 
    117     LocalFrame* frame() const; // Can be null
    118     FetchContext& context() const;
    119     Document* document() const { return m_document; } // Can be null
    120     void setDocument(RawPtr<Document> document) { m_document = document; }
    121 
    122     DocumentLoader* documentLoader() const { return m_documentLoader; }
    123     void clearDocumentLoader() { m_documentLoader = 0; }
    124 
    125     void garbageCollectDocumentResources();
    126 
    127     int requestCount() const { return m_requestCount; }
    128 
    129     bool isPreloaded(const String& urlString) const;
    130     void clearPreloads();
    131     void preload(Resource::Type, FetchRequest&, const String& charset);
    132     void printPreloadStats();
    133 
    134     void setDefersLoading(bool);
    135     void stopFetching();
    136     bool isFetching() const;
    137 
    138     // ResourceLoaderHost
    139     virtual void incrementRequestCount(const Resource*) OVERRIDE;
    140     virtual void decrementRequestCount(const Resource*) OVERRIDE;
    141     virtual void didLoadResource(Resource*) OVERRIDE;
    142     virtual void redirectReceived(Resource*, const ResourceResponse&) OVERRIDE;
    143     virtual void didFinishLoading(const Resource*, double finishTime, int64_t encodedDataLength) OVERRIDE;
    144     virtual void didChangeLoadingPriority(const Resource*, ResourceLoadPriority, int intraPriorityValue) OVERRIDE;
    145     virtual void didFailLoading(const Resource*, const ResourceError&) OVERRIDE;
    146     virtual void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&) OVERRIDE;
    147     virtual void didReceiveResponse(const Resource*, const ResourceResponse&) OVERRIDE;
    148     virtual void didReceiveData(const Resource*, const char* data, int dataLength, int encodedDataLength) OVERRIDE;
    149     virtual void didDownloadData(const Resource*, int dataLength, int encodedDataLength) OVERRIDE;
    150     virtual void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*) OVERRIDE;
    151     virtual void didInitializeResourceLoader(ResourceLoader*) OVERRIDE;
    152     virtual void willTerminateResourceLoader(ResourceLoader*) OVERRIDE;
    153     virtual void willStartLoadingResource(Resource*, ResourceRequest&) OVERRIDE;
    154     virtual bool defersLoading() const OVERRIDE;
    155     virtual bool isLoadedBy(ResourceLoaderHost*) const OVERRIDE;
    156     virtual bool canAccessRedirect(Resource*, ResourceRequest&, const ResourceResponse&, ResourceLoaderOptions&) OVERRIDE;
    157     virtual bool canAccessResource(Resource*, SecurityOrigin*, const KURL&) const OVERRIDE;
    158 
    159 #if !ENABLE(OILPAN)
    160     virtual void refResourceLoaderHost() OVERRIDE;
    161     virtual void derefResourceLoaderHost() OVERRIDE;
    162 #endif
    163 
    164     enum ResourceLoadStartType {
    165         ResourceLoadingFromNetwork,
    166         ResourceLoadingFromCache
    167     };
    168     void requestLoadStarted(Resource*, const FetchRequest&, ResourceLoadStartType);
    169     static const ResourceLoaderOptions& defaultResourceOptions();
    170 private:
    171 
    172     explicit ResourceFetcher(DocumentLoader*);
    173 
    174     bool shouldLoadNewResource(Resource::Type) const;
    175 
    176     ResourcePtr<Resource> requestResource(Resource::Type, FetchRequest&);
    177     ResourcePtr<Resource> createResourceForRevalidation(const FetchRequest&, Resource*);
    178     ResourcePtr<Resource> createResourceForLoading(Resource::Type, FetchRequest&, const String& charset);
    179     void preCacheDataURIImage(const FetchRequest&);
    180     void preCacheSubstituteDataForMainResource(const FetchRequest&, const SubstituteData&);
    181     void storeResourceTimingInitiatorInformation(Resource*);
    182     void requestPreload(Resource::Type, FetchRequest&, const String& charset);
    183 
    184     enum RevalidationPolicy { Use, Revalidate, Reload, Load };
    185     RevalidationPolicy determineRevalidationPolicy(Resource::Type, ResourceRequest&, bool forPreload, Resource* existingResource, FetchRequest::DeferOption, const ResourceLoaderOptions&) const;
    186 
    187     void determineTargetType(ResourceRequest&, Resource::Type);
    188     ResourceRequestCachePolicy resourceRequestCachePolicy(const ResourceRequest&, Resource::Type);
    189     void addAdditionalRequestHeaders(ResourceRequest&, Resource::Type);
    190 
    191     bool canRequest(Resource::Type, const KURL&, const ResourceLoaderOptions&, bool forPreload, FetchRequest::OriginRestriction) const;
    192     bool checkInsecureContent(Resource::Type, const KURL&, MixedContentBlockingTreatment) const;
    193 
    194     static bool resourceNeedsLoad(Resource*, const FetchRequest&, RevalidationPolicy);
    195 
    196     void notifyLoadedFromMemoryCache(Resource*);
    197 
    198     void garbageCollectDocumentResourcesTimerFired(Timer<ResourceFetcher>*);
    199     void scheduleDocumentResourcesGC();
    200 
    201     void resourceTimingReportTimerFired(Timer<ResourceFetcher>*);
    202 
    203     bool clientDefersImage(const KURL&) const;
    204     void reloadImagesIfNotDeferred();
    205 
    206     HashSet<String> m_validatedURLs;
    207     mutable DocumentResourceMap m_documentResources;
    208     // FIXME: Oilpan: Ideally this should just be a traced Member but that will
    209     // currently leak because RenderStyle and its data are not on the heap.
    210     // See crbug.com/383860 for details.
    211     RawPtrWillBeWeakMember<Document> m_document;
    212     DocumentLoader* m_documentLoader;
    213 
    214     int m_requestCount;
    215 
    216     OwnPtr<ListHashSet<Resource*> > m_preloads;
    217 
    218     Timer<ResourceFetcher> m_garbageCollectDocumentResourcesTimer;
    219     Timer<ResourceFetcher> m_resourceTimingReportTimer;
    220 
    221     typedef HashMap<Resource*, RefPtr<ResourceTimingInfo> > ResourceTimingInfoMap;
    222     ResourceTimingInfoMap m_resourceTimingInfoMap;
    223 
    224     HashMap<RefPtr<ResourceTimingInfo>, bool> m_scheduledResourceTimingReports;
    225 
    226     OwnPtr<ResourceLoaderSet> m_loaders;
    227     OwnPtr<ResourceLoaderSet> m_multipartLoaders;
    228 
    229     // Used in hit rate histograms.
    230     class DeadResourceStatsRecorder {
    231     public:
    232         DeadResourceStatsRecorder();
    233         ~DeadResourceStatsRecorder();
    234 
    235         void update(RevalidationPolicy);
    236 
    237     private:
    238         int m_useCount;
    239         int m_revalidateCount;
    240         int m_loadCount;
    241     };
    242     DeadResourceStatsRecorder m_deadStatsRecorder;
    243 
    244     // 29 bits left
    245     bool m_autoLoadImages : 1;
    246     bool m_imagesEnabled : 1;
    247     bool m_allowStaleResources : 1;
    248 };
    249 
    250 class ResourceCacheValidationSuppressor {
    251     WTF_MAKE_NONCOPYABLE(ResourceCacheValidationSuppressor);
    252     WTF_MAKE_FAST_ALLOCATED;
    253 public:
    254     ResourceCacheValidationSuppressor(ResourceFetcher* loader)
    255         : m_loader(loader)
    256         , m_previousState(false)
    257     {
    258         if (m_loader) {
    259             m_previousState = m_loader->m_allowStaleResources;
    260             m_loader->m_allowStaleResources = true;
    261         }
    262     }
    263     ~ResourceCacheValidationSuppressor()
    264     {
    265         if (m_loader)
    266             m_loader->m_allowStaleResources = m_previousState;
    267     }
    268 private:
    269     ResourceFetcher* m_loader;
    270     bool m_previousState;
    271 };
    272 
    273 } // namespace WebCore
    274 
    275 #endif
    276