• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3     Copyright (C) 2001 Dirk Mueller <mueller@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:
create(DocumentLoader * documentLoader)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;
allResources()109     const DocumentResourceMap& allResources() const { return m_documentResources; }
110 
autoLoadImages()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;
document()120     Document* document() const { return m_document; } // Can be null
setDocument(Document * document)121     void setDocument(Document* document) { m_document = document; }
122 
documentLoader()123     DocumentLoader* documentLoader() const { return m_documentLoader; }
clearDocumentLoader()124     void clearDocumentLoader() { m_documentLoader = 0; }
125 
126     void garbageCollectDocumentResources();
127 
requestCount()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:
ResourceCacheValidationSuppressor(ResourceFetcher * loader)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     }
~ResourceCacheValidationSuppressor()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