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/
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.
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.
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.
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.
26 #ifndef ResourceFetcher_h
27 #define ResourceFetcher_h
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"
45 class CSSStyleSheetResource;
46 class DocumentResource;
53 class XSLStyleSheetResource;
60 class ResourceTimingInfo;
61 class ResourceLoaderSet;
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;
78 static PassRefPtrWillBeRawPtr<ResourceFetcher> create(DocumentLoader* documentLoader) { return adoptRefWillBeNoop(new ResourceFetcher(documentLoader)); }
79 virtual ~ResourceFetcher();
80 virtual void trace(Visitor*);
83 using RefCounted<ResourceFetcher>::ref;
84 using RefCounted<ResourceFetcher>::deref;
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&);
102 // Logs an access denied message to the console for the specified URL.
103 void printAccessDeniedMessage(const KURL&) const;
105 Resource* cachedResource(const KURL&) const;
107 typedef HashMap<String, ResourcePtr<Resource> > DocumentResourceMap;
108 const DocumentResourceMap& allResources() const { return m_documentResources; }
110 bool autoLoadImages() const { return m_autoLoadImages; }
111 void setAutoLoadImages(bool);
113 void setImagesEnabled(bool);
115 bool shouldDeferImageLoad(const KURL&) const;
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; }
122 DocumentLoader* documentLoader() const { return m_documentLoader; }
123 void clearDocumentLoader() { m_documentLoader = 0; }
125 void garbageCollectDocumentResources();
127 int requestCount() const { return m_requestCount; }
129 bool isPreloaded(const String& urlString) const;
130 void clearPreloads();
131 void preload(Resource::Type, FetchRequest&, const String& charset);
132 void printPreloadStats();
134 void setDefersLoading(bool);
136 bool isFetching() const;
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;
160 virtual void refResourceLoaderHost() OVERRIDE;
161 virtual void derefResourceLoaderHost() OVERRIDE;
164 enum ResourceLoadStartType {
165 ResourceLoadingFromNetwork,
166 ResourceLoadingFromCache
168 void requestLoadStarted(Resource*, const FetchRequest&, ResourceLoadStartType);
169 static const ResourceLoaderOptions& defaultResourceOptions();
172 explicit ResourceFetcher(DocumentLoader*);
174 bool shouldLoadNewResource(Resource::Type) const;
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);
184 enum RevalidationPolicy { Use, Revalidate, Reload, Load };
185 RevalidationPolicy determineRevalidationPolicy(Resource::Type, ResourceRequest&, bool forPreload, Resource* existingResource, FetchRequest::DeferOption, const ResourceLoaderOptions&) const;
187 void determineTargetType(ResourceRequest&, Resource::Type);
188 ResourceRequestCachePolicy resourceRequestCachePolicy(const ResourceRequest&, Resource::Type);
189 void addAdditionalRequestHeaders(ResourceRequest&, Resource::Type);
191 bool canRequest(Resource::Type, const KURL&, const ResourceLoaderOptions&, bool forPreload, FetchRequest::OriginRestriction) const;
192 bool checkInsecureContent(Resource::Type, const KURL&, MixedContentBlockingTreatment) const;
194 static bool resourceNeedsLoad(Resource*, const FetchRequest&, RevalidationPolicy);
196 void notifyLoadedFromMemoryCache(Resource*);
198 void garbageCollectDocumentResourcesTimerFired(Timer<ResourceFetcher>*);
199 void scheduleDocumentResourcesGC();
201 void resourceTimingReportTimerFired(Timer<ResourceFetcher>*);
203 bool clientDefersImage(const KURL&) const;
204 void reloadImagesIfNotDeferred();
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;
216 OwnPtr<ListHashSet<Resource*> > m_preloads;
218 Timer<ResourceFetcher> m_garbageCollectDocumentResourcesTimer;
219 Timer<ResourceFetcher> m_resourceTimingReportTimer;
221 typedef HashMap<Resource*, RefPtr<ResourceTimingInfo> > ResourceTimingInfoMap;
222 ResourceTimingInfoMap m_resourceTimingInfoMap;
224 HashMap<RefPtr<ResourceTimingInfo>, bool> m_scheduledResourceTimingReports;
226 OwnPtr<ResourceLoaderSet> m_loaders;
227 OwnPtr<ResourceLoaderSet> m_multipartLoaders;
229 // Used in hit rate histograms.
230 class DeadResourceStatsRecorder {
232 DeadResourceStatsRecorder();
233 ~DeadResourceStatsRecorder();
235 void update(RevalidationPolicy);
239 int m_revalidateCount;
242 DeadResourceStatsRecorder m_deadStatsRecorder;
245 bool m_autoLoadImages : 1;
246 bool m_imagesEnabled : 1;
247 bool m_allowStaleResources : 1;
250 class ResourceCacheValidationSuppressor {
251 WTF_MAKE_NONCOPYABLE(ResourceCacheValidationSuppressor);
252 WTF_MAKE_FAST_ALLOCATED;
254 ResourceCacheValidationSuppressor(ResourceFetcher* loader)
256 , m_previousState(false)
259 m_previousState = m_loader->m_allowStaleResources;
260 m_loader->m_allowStaleResources = true;
263 ~ResourceCacheValidationSuppressor()
266 m_loader->m_allowStaleResources = m_previousState;
269 ResourceFetcher* m_loader;
270 bool m_previousState;
273 } // namespace WebCore