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