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 ShaderResource;
     53 class XSLStyleSheetResource;
     54 class Document;
     55 class DocumentLoader;
     56 class Frame;
     57 class FrameLoader;
     58 class ImageLoader;
     59 class KURL;
     60 class ResourceTimingInfo;
     61 class ResourceLoaderSet;
     62 
     63 enum CORSEnabled {
     64     NotCORSEnabled,
     65     PotentiallyCORSEnabled // Indicates "potentially CORS-enabled fetch" in HTML standard.
     66 };
     67 
     68 // The ResourceFetcher provides a per-context interface to the MemoryCache
     69 // and enforces a bunch of security checks and rules for resource revalidation.
     70 // Its lifetime is roughly per-DocumentLoader, in that it is generally created
     71 // in the DocumentLoader constructor and loses its ability to generate network
     72 // requests when the DocumentLoader is destroyed. Documents also hold a
     73 // RefPtr<ResourceFetcher> for their lifetime (and will create one if they
     74 // are initialized without a Frame), so a Document can keep a ResourceFetcher
     75 // alive past detach if scripts still reference the Document.
     76 class ResourceFetcher : public RefCounted<ResourceFetcher>, public ResourceLoaderHost {
     77     WTF_MAKE_NONCOPYABLE(ResourceFetcher); WTF_MAKE_FAST_ALLOCATED;
     78 friend class ImageLoader;
     79 friend class ResourceCacheValidationSuppressor;
     80 
     81 public:
     82     static PassRefPtr<ResourceFetcher> create(DocumentLoader* documentLoader) { return adoptRef(new ResourceFetcher(documentLoader)); }
     83     virtual ~ResourceFetcher();
     84 
     85     using RefCounted<ResourceFetcher>::ref;
     86     using RefCounted<ResourceFetcher>::deref;
     87 
     88     ResourcePtr<Resource> fetchSynchronously(FetchRequest&);
     89     ResourcePtr<ImageResource> fetchImage(FetchRequest&);
     90     ResourcePtr<CSSStyleSheetResource> fetchCSSStyleSheet(FetchRequest&);
     91     ResourcePtr<CSSStyleSheetResource> fetchUserCSSStyleSheet(FetchRequest&);
     92     ResourcePtr<ScriptResource> fetchScript(FetchRequest&);
     93     ResourcePtr<FontResource> fetchFont(FetchRequest&);
     94     ResourcePtr<RawResource> fetchRawResource(FetchRequest&);
     95     ResourcePtr<RawResource> fetchMainResource(FetchRequest&);
     96     ResourcePtr<DocumentResource> fetchSVGDocument(FetchRequest&);
     97     ResourcePtr<XSLStyleSheetResource> fetchXSLStyleSheet(FetchRequest&);
     98     ResourcePtr<Resource> fetchLinkResource(Resource::Type, FetchRequest&);
     99     ResourcePtr<ShaderResource> fetchShader(FetchRequest&);
    100     ResourcePtr<RawResource> fetchImport(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 String& url) const;
    106     Resource* cachedResource(const KURL&) const;
    107 
    108     typedef HashMap<String, ResourcePtr<Resource> > DocumentResourceMap;
    109     const DocumentResourceMap& allResources() const { return m_documentResources; }
    110 
    111     bool autoLoadImages() const { return m_autoLoadImages; }
    112     void setAutoLoadImages(bool);
    113 
    114     void setImagesEnabled(bool);
    115 
    116     bool shouldDeferImageLoad(const KURL&) const;
    117 
    118     Frame* frame() const; // Can be null
    119     FetchContext& context() const;
    120     Document* document() const { return m_document; } // Can be null
    121     void setDocument(Document* document) { m_document = document; }
    122 
    123     DocumentLoader* documentLoader() const { return m_documentLoader; }
    124     void clearDocumentLoader() { m_documentLoader = 0; }
    125 
    126     void garbageCollectDocumentResources();
    127 
    128     int requestCount() const { return m_requestCount; }
    129 
    130     bool isPreloaded(const String& urlString) const;
    131     void clearPreloads();
    132     void clearPendingPreloads();
    133     void preload(Resource::Type, FetchRequest&, const String& charset);
    134     void checkForPendingPreloads();
    135     void printPreloadStats();
    136     bool canAccess(Resource*, CORSEnabled, FetchRequest::OriginRestriction = FetchRequest::UseDefaultOriginRestrictionForType);
    137 
    138     void setDefersLoading(bool);
    139     void stopFetching();
    140     bool isFetching() const;
    141 
    142     // ResourceLoaderHost
    143     virtual void incrementRequestCount(const Resource*) OVERRIDE;
    144     virtual void decrementRequestCount(const Resource*) OVERRIDE;
    145     virtual void didLoadResource(Resource*) OVERRIDE;
    146     virtual void redirectReceived(Resource*, const ResourceResponse&) OVERRIDE;
    147     virtual void didFinishLoading(const Resource*, double finishTime, const ResourceLoaderOptions&) OVERRIDE;
    148     virtual void didChangeLoadingPriority(const Resource*, ResourceLoadPriority) OVERRIDE;
    149     virtual void didFailLoading(const Resource*, const ResourceError&, const ResourceLoaderOptions&) OVERRIDE;
    150     virtual void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const ResourceLoaderOptions&) OVERRIDE;
    151     virtual void didReceiveResponse(const Resource*, const ResourceResponse&, const ResourceLoaderOptions&) OVERRIDE;
    152     virtual void didReceiveData(const Resource*, const char* data, int dataLength, int encodedDataLength, const ResourceLoaderOptions&) OVERRIDE;
    153     virtual void didDownloadData(const Resource*, int dataLength, int encodedDataLength, const ResourceLoaderOptions&) OVERRIDE;
    154     virtual void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*) OVERRIDE;
    155     virtual void didInitializeResourceLoader(ResourceLoader*) OVERRIDE;
    156     virtual void willTerminateResourceLoader(ResourceLoader*) OVERRIDE;
    157     virtual void willStartLoadingResource(ResourceRequest&) OVERRIDE;
    158     virtual bool defersLoading() const OVERRIDE;
    159     virtual bool isLoadedBy(ResourceLoaderHost*) const OVERRIDE;
    160     virtual bool shouldRequest(Resource*, const ResourceRequest&, const ResourceLoaderOptions&) OVERRIDE;
    161     virtual void refResourceLoaderHost() OVERRIDE;
    162     virtual void derefResourceLoaderHost() OVERRIDE;
    163 
    164     static const ResourceLoaderOptions& defaultResourceOptions();
    165 private:
    166 
    167     explicit ResourceFetcher(DocumentLoader*);
    168 
    169     bool shouldLoadNewResource() const;
    170 
    171     ResourcePtr<Resource> requestResource(Resource::Type, FetchRequest&);
    172     ResourcePtr<Resource> revalidateResource(const FetchRequest&, Resource*);
    173     ResourcePtr<Resource> loadResource(Resource::Type, FetchRequest&, const String& charset);
    174     void preCacheDataURIImage(const FetchRequest&);
    175     void storeResourceTimingInitiatorInformation(const ResourcePtr<Resource>&, const FetchRequest&);
    176     void requestPreload(Resource::Type, FetchRequest&, const String& charset);
    177 
    178     enum RevalidationPolicy { Use, Revalidate, Reload, Load };
    179     RevalidationPolicy determineRevalidationPolicy(Resource::Type, ResourceRequest&, bool forPreload, Resource* existingResource, FetchRequest::DeferOption) const;
    180 
    181     void determineTargetType(ResourceRequest&, Resource::Type);
    182     ResourceRequestCachePolicy resourceRequestCachePolicy(const ResourceRequest&, Resource::Type);
    183     void addAdditionalRequestHeaders(ResourceRequest&, Resource::Type);
    184 
    185     bool canRequest(Resource::Type, const KURL&, const ResourceLoaderOptions&, bool forPreload, FetchRequest::OriginRestriction);
    186     bool checkInsecureContent(Resource::Type, const KURL&, MixedContentBlockingTreatment) const;
    187 
    188     static bool resourceNeedsLoad(Resource*, const FetchRequest&, RevalidationPolicy);
    189 
    190     void notifyLoadedFromMemoryCache(Resource*);
    191 
    192     void garbageCollectDocumentResourcesTimerFired(Timer<ResourceFetcher>*);
    193 
    194     void resourceTimingReportTimerFired(Timer<ResourceFetcher>*);
    195 
    196     void performPostLoadActions();
    197 
    198     bool clientDefersImage(const KURL&) const;
    199     void reloadImagesIfNotDeferred();
    200 
    201     HashSet<String> m_validatedURLs;
    202     mutable DocumentResourceMap m_documentResources;
    203     Document* m_document;
    204     DocumentLoader* m_documentLoader;
    205 
    206     int m_requestCount;
    207 
    208     OwnPtr<ListHashSet<Resource*> > m_preloads;
    209     struct PendingPreload {
    210         Resource::Type m_type;
    211         FetchRequest m_request;
    212         String m_charset;
    213     };
    214     Deque<PendingPreload> m_pendingPreloads;
    215 
    216     Timer<ResourceFetcher> m_garbageCollectDocumentResourcesTimer;
    217     Timer<ResourceFetcher> m_resourceTimingReportTimer;
    218 
    219     typedef HashMap<Resource*, RefPtr<ResourceTimingInfo> > ResourceTimingInfoMap;
    220     ResourceTimingInfoMap m_resourceTimingInfoMap;
    221 
    222     HashMap<RefPtr<ResourceTimingInfo>, bool> m_scheduledResourceTimingReports;
    223 
    224     OwnPtr<ResourceLoaderSet> m_loaders;
    225     OwnPtr<ResourceLoaderSet> m_multipartLoaders;
    226 
    227     // 29 bits left
    228     bool m_autoLoadImages : 1;
    229     bool m_imagesEnabled : 1;
    230     bool m_allowStaleResources : 1;
    231 };
    232 
    233 class ResourceCacheValidationSuppressor {
    234     WTF_MAKE_NONCOPYABLE(ResourceCacheValidationSuppressor);
    235     WTF_MAKE_FAST_ALLOCATED;
    236 public:
    237     ResourceCacheValidationSuppressor(ResourceFetcher* loader)
    238         : m_loader(loader)
    239         , m_previousState(false)
    240     {
    241         if (m_loader) {
    242             m_previousState = m_loader->m_allowStaleResources;
    243             m_loader->m_allowStaleResources = true;
    244         }
    245     }
    246     ~ResourceCacheValidationSuppressor()
    247     {
    248         if (m_loader)
    249             m_loader->m_allowStaleResources = m_previousState;
    250     }
    251 private:
    252     ResourceFetcher* m_loader;
    253     bool m_previousState;
    254 };
    255 
    256 } // namespace WebCore
    257 
    258 #endif
    259