• 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 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:
create(DocumentLoader * documentLoader)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;
allResources()108     const DocumentResourceMap& allResources() const { return m_documentResources; }
109 
autoLoadImages()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;
document()119     Document* document() const { return m_document; } // Can be null
setDocument(RawPtr<Document> document)120     void setDocument(RawPtr<Document> document) { m_document = document; }
121 
documentLoader()122     DocumentLoader* documentLoader() const { return m_documentLoader; }
clearDocumentLoader()123     void clearDocumentLoader() { m_documentLoader = 0; }
124 
125     void garbageCollectDocumentResources();
126 
requestCount()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:
ResourceCacheValidationSuppressor(ResourceFetcher * loader)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     }
~ResourceCacheValidationSuppressor()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