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 CachedResourceLoader_h
27#define CachedResourceLoader_h
28
29#include "CachePolicy.h"
30#include "CachedResource.h"
31#include "CachedResourceHandle.h"
32#include "CachedResourceRequest.h"
33#include "ResourceLoadPriority.h"
34#include "Timer.h"
35#include <wtf/Deque.h>
36#include <wtf/HashMap.h>
37#include <wtf/HashSet.h>
38#include <wtf/ListHashSet.h>
39#include <wtf/text/StringHash.h>
40
41namespace WebCore {
42
43class CachedCSSStyleSheet;
44class CachedSVGDocument;
45class CachedFont;
46class CachedImage;
47class CachedRawResource;
48class CachedScript;
49class CachedTextTrack;
50class CachedXSLStyleSheet;
51class Document;
52class DocumentLoader;
53class Frame;
54class ImageLoader;
55class URL;
56
57// The CachedResourceLoader provides a per-context interface to the MemoryCache
58// and enforces a bunch of security checks and rules for resource revalidation.
59// Its lifetime is roughly per-DocumentLoader, in that it is generally created
60// in the DocumentLoader constructor and loses its ability to generate network
61// requests when the DocumentLoader is destroyed. Documents also hold a
62// RefPtr<CachedResourceLoader> for their lifetime (and will create one if they
63// are initialized without a Frame), so a Document can keep a CachedResourceLoader
64// alive past detach if scripts still reference the Document.
65class CachedResourceLoader : public RefCounted<CachedResourceLoader> {
66    WTF_MAKE_NONCOPYABLE(CachedResourceLoader); WTF_MAKE_FAST_ALLOCATED;
67friend class ImageLoader;
68friend class ResourceCacheValidationSuppressor;
69
70public:
71    static PassRef<CachedResourceLoader> create(DocumentLoader* documentLoader) { return adoptRef(*new CachedResourceLoader(documentLoader)); }
72    ~CachedResourceLoader();
73
74    CachedResourceHandle<CachedImage> requestImage(CachedResourceRequest&);
75    CachedResourceHandle<CachedCSSStyleSheet> requestCSSStyleSheet(CachedResourceRequest&);
76    CachedResourceHandle<CachedCSSStyleSheet> requestUserCSSStyleSheet(CachedResourceRequest&);
77    CachedResourceHandle<CachedScript> requestScript(CachedResourceRequest&);
78    CachedResourceHandle<CachedFont> requestFont(CachedResourceRequest&);
79    CachedResourceHandle<CachedRawResource> requestRawResource(CachedResourceRequest&);
80    CachedResourceHandle<CachedRawResource> requestMainResource(CachedResourceRequest&);
81    CachedResourceHandle<CachedSVGDocument> requestSVGDocument(CachedResourceRequest&);
82#if ENABLE(XSLT)
83    CachedResourceHandle<CachedXSLStyleSheet> requestXSLStyleSheet(CachedResourceRequest&);
84#endif
85#if ENABLE(LINK_PREFETCH)
86    CachedResourceHandle<CachedResource> requestLinkResource(CachedResource::Type, CachedResourceRequest&);
87#endif
88#if ENABLE(VIDEO_TRACK)
89    CachedResourceHandle<CachedTextTrack> requestTextTrack(CachedResourceRequest&);
90#endif
91
92    // Logs an access denied message to the console for the specified URL.
93    void printAccessDeniedMessage(const URL& url) const;
94
95    CachedResource* cachedResource(const String& url) const;
96    CachedResource* cachedResource(const URL& url) const;
97
98    typedef HashMap<String, CachedResourceHandle<CachedResource>> DocumentResourceMap;
99    const DocumentResourceMap& allCachedResources() const { return m_documentResources; }
100
101    bool autoLoadImages() const { return m_autoLoadImages; }
102    void setAutoLoadImages(bool);
103
104    void setImagesEnabled(bool);
105
106    bool shouldDeferImageLoad(const URL&) const;
107
108    CachePolicy cachePolicy(CachedResource::Type) const;
109
110    Frame* frame() const; // Can be null
111    Document* document() const { return m_document; } // Can be null
112    void setDocument(Document* document) { m_document = document; }
113    void clearDocumentLoader() { m_documentLoader = 0; }
114    SessionID sessionID() const;
115
116    void removeCachedResource(CachedResource*) const;
117
118    void loadDone(CachedResource*, bool shouldPerformPostLoadActions = true);
119
120    void garbageCollectDocumentResources();
121
122    void incrementRequestCount(const CachedResource*);
123    void decrementRequestCount(const CachedResource*);
124    int requestCount() const { return m_requestCount; }
125
126    bool isPreloaded(const String& urlString) const;
127    void clearPreloads();
128    void clearPendingPreloads();
129    void preload(CachedResource::Type, CachedResourceRequest&, const String& charset);
130    void checkForPendingPreloads();
131    void printPreloadStats();
132    bool canRequest(CachedResource::Type, const URL&, const ResourceLoaderOptions&, bool forPreload = false);
133
134    static const ResourceLoaderOptions& defaultCachedResourceOptions();
135
136    void documentDidFinishLoadEvent();
137
138private:
139    explicit CachedResourceLoader(DocumentLoader*);
140
141    CachedResourceHandle<CachedResource> requestResource(CachedResource::Type, CachedResourceRequest&);
142    CachedResourceHandle<CachedResource> revalidateResource(const CachedResourceRequest&, CachedResource*);
143    CachedResourceHandle<CachedResource> loadResource(CachedResource::Type, CachedResourceRequest&);
144#if ENABLE(RESOURCE_TIMING)
145    void storeResourceTimingInitiatorInformation(const CachedResourceHandle<CachedResource>&, const CachedResourceRequest&);
146#endif
147    void requestPreload(CachedResource::Type, CachedResourceRequest&, const String& charset);
148
149    enum RevalidationPolicy { Use, Revalidate, Reload, Load };
150    RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, ResourceRequest&, bool forPreload, CachedResource* existingResource, CachedResourceRequest::DeferOption) const;
151
152    bool shouldContinueAfterNotifyingLoadedFromMemoryCache(const CachedResourceRequest&, CachedResource*);
153    bool checkInsecureContent(CachedResource::Type, const URL&) const;
154
155    void garbageCollectDocumentResourcesTimerFired(Timer<CachedResourceLoader>&);
156    void performPostLoadActions();
157
158    bool clientDefersImage(const URL&) const;
159    void reloadImagesIfNotDeferred();
160
161    HashSet<String> m_validatedURLs;
162    mutable DocumentResourceMap m_documentResources;
163    Document* m_document;
164    DocumentLoader* m_documentLoader;
165
166    int m_requestCount;
167
168    OwnPtr<ListHashSet<CachedResource*>> m_preloads;
169    struct PendingPreload {
170        CachedResource::Type m_type;
171        CachedResourceRequest m_request;
172        String m_charset;
173    };
174    Deque<PendingPreload> m_pendingPreloads;
175
176    Timer<CachedResourceLoader> m_garbageCollectDocumentResourcesTimer;
177
178#if ENABLE(RESOURCE_TIMING)
179    struct InitiatorInfo {
180        AtomicString name;
181        double startTime;
182    };
183    HashMap<CachedResource*, InitiatorInfo> m_initiatorMap;
184#endif
185
186    // 29 bits left
187    bool m_autoLoadImages : 1;
188    bool m_imagesEnabled : 1;
189    bool m_allowStaleResources : 1;
190};
191
192class ResourceCacheValidationSuppressor {
193    WTF_MAKE_NONCOPYABLE(ResourceCacheValidationSuppressor);
194    WTF_MAKE_FAST_ALLOCATED;
195public:
196    ResourceCacheValidationSuppressor(CachedResourceLoader* loader)
197        : m_loader(loader)
198        , m_previousState(false)
199    {
200        if (m_loader) {
201            m_previousState = m_loader->m_allowStaleResources;
202            m_loader->m_allowStaleResources = true;
203        }
204    }
205    ~ResourceCacheValidationSuppressor()
206    {
207        if (m_loader)
208            m_loader->m_allowStaleResources = m_previousState;
209    }
210private:
211    CachedResourceLoader* m_loader;
212    bool m_previousState;
213};
214
215} // namespace WebCore
216
217#endif
218