• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef ApplicationCacheGroup_h
27 #define ApplicationCacheGroup_h
28 
29 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
30 
31 #include <wtf/Noncopyable.h>
32 #include <wtf/HashMap.h>
33 #include <wtf/HashSet.h>
34 
35 #include "DOMApplicationCache.h"
36 #include "KURL.h"
37 #include "PlatformString.h"
38 #include "ResourceHandle.h"
39 #include "ResourceHandleClient.h"
40 #include "SharedBuffer.h"
41 
42 namespace WebCore {
43 
44 class ApplicationCache;
45 class ApplicationCacheResource;
46 class Document;
47 class DocumentLoader;
48 class Frame;
49 
50 enum ApplicationCacheUpdateOption {
51     ApplicationCacheUpdateWithBrowsingContext,
52     ApplicationCacheUpdateWithoutBrowsingContext
53 };
54 
55 class ApplicationCacheGroup : public Noncopyable, ResourceHandleClient {
56 public:
57     ApplicationCacheGroup(const KURL& manifestURL, bool isCopy = false);
58     ~ApplicationCacheGroup();
59 
60     enum UpdateStatus { Idle, Checking, Downloading };
61 
62     static ApplicationCache* cacheForMainRequest(const ResourceRequest&, DocumentLoader*);
63     static ApplicationCache* fallbackCacheForMainRequest(const ResourceRequest&, DocumentLoader*);
64 
65     static void selectCache(Frame*, const KURL& manifestURL);
66     static void selectCacheWithoutManifestURL(Frame*);
67 
manifestURL()68     const KURL& manifestURL() const { return m_manifestURL; }
updateStatus()69     UpdateStatus updateStatus() const { return m_updateStatus; }
70 
setStorageID(unsigned storageID)71     void setStorageID(unsigned storageID) { m_storageID = storageID; }
storageID()72     unsigned storageID() const { return m_storageID; }
73     void clearStorageID();
74 
75     void update(Frame*, ApplicationCacheUpdateOption); // FIXME: Frame should not bee needed when updating witout browsing context.
76     void cacheDestroyed(ApplicationCache*);
77 
cacheIsBeingUpdated(const ApplicationCache * cache)78     bool cacheIsBeingUpdated(const ApplicationCache* cache) const { return cache == m_cacheBeingUpdated; }
79 
newestCache()80     ApplicationCache* newestCache() const { return m_newestCache.get(); }
81     void setNewestCache(PassRefPtr<ApplicationCache>);
82 
83     void makeObsolete();
isObsolete()84     bool isObsolete() const { return m_isObsolete; }
85 
86     void finishedLoadingMainResource(DocumentLoader*);
87     void failedLoadingMainResource(DocumentLoader*);
88 
89     void disassociateDocumentLoader(DocumentLoader*);
90 
isCopy()91     bool isCopy() const { return m_isCopy; }
92 
93 private:
94     static void postListenerTask(ApplicationCacheHost::EventID, const HashSet<DocumentLoader*>&);
95     static void postListenerTask(ApplicationCacheHost::EventID, DocumentLoader*);
96     void scheduleReachedMaxAppCacheSizeCallback();
97 
98     PassRefPtr<ResourceHandle> createResourceHandle(const KURL&, ApplicationCacheResource* newestCachedResource);
99 
100     // For normal resource loading, WebKit client is asked about each resource individually. Since application cache does not belong to any particular document,
101     // the existing client callback cannot be used, so assume that any client that enables application cache also wants it to use credential storage.
shouldUseCredentialStorage(ResourceHandle *)102     virtual bool shouldUseCredentialStorage(ResourceHandle*) { return true; }
103 
104     virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
105     virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
106     virtual void didFinishLoading(ResourceHandle*);
107     virtual void didFail(ResourceHandle*, const ResourceError&);
108 
109     void didReceiveManifestResponse(const ResourceResponse&);
110     void didReceiveManifestData(const char*, int);
111     void didFinishLoadingManifest();
112     void didReachMaxAppCacheSize();
113 
114     void startLoadingEntry();
115     void deliverDelayedMainResources();
116     void checkIfLoadIsComplete();
117     void cacheUpdateFailed();
118     void manifestNotFound();
119 
120     void addEntry(const String&, unsigned type);
121 
122     void associateDocumentLoaderWithCache(DocumentLoader*, ApplicationCache*);
123 
124     void stopLoading();
125 
126     KURL m_manifestURL;
127     UpdateStatus m_updateStatus;
128 
129     // This is the newest complete cache in the group.
130     RefPtr<ApplicationCache> m_newestCache;
131 
132     // All complete caches in this cache group.
133     HashSet<ApplicationCache*> m_caches;
134 
135     // The cache being updated (if any). Note that cache updating does not immediately create a new
136     // ApplicationCache object, so this may be null even when update status is not Idle.
137     RefPtr<ApplicationCache> m_cacheBeingUpdated;
138 
139     // List of pending master entries, used during the update process to ensure that new master entries are cached.
140     HashSet<DocumentLoader*> m_pendingMasterResourceLoaders;
141     // How many of the above pending master entries have not yet finished downloading.
142     int m_downloadingPendingMasterResourceLoadersCount;
143 
144     // These are all the document loaders that are associated with a cache in this group.
145     HashSet<DocumentLoader*> m_associatedDocumentLoaders;
146 
147     // The URLs and types of pending cache entries.
148     typedef HashMap<String, unsigned> EntryMap;
149     EntryMap m_pendingEntries;
150 
151     // Frame used for fetching resources when updating.
152     // FIXME: An update started by a particular frame should not stop if it is destroyed, but there are other frames associated with the same cache group.
153     Frame* m_frame;
154 
155     // An obsolete cache group is never stored, but the opposite is not true - storing may fail for multiple reasons, such as exceeding disk quota.
156     unsigned m_storageID;
157     bool m_isObsolete;
158 
159     // During update, this is used to handle asynchronously arriving results.
160     enum CompletionType {
161         None,
162         NoUpdate,
163         Failure,
164         Completed
165     };
166     CompletionType m_completionType;
167 
168     // Whether this cache group is a copy that's only used for transferring the cache to another file.
169     bool m_isCopy;
170 
171     // This flag is set immediately after the ChromeClient::reachedMaxAppCacheSize() callback is invoked as a result of the storage layer failing to save a cache
172     // due to reaching the maximum size of the application cache database file. This flag is used by ApplicationCacheGroup::checkIfLoadIsComplete() to decide
173     // the course of action in case of this failure (i.e. call the ChromeClient callback or run the failure steps).
174     bool m_calledReachedMaxAppCacheSize;
175 
176     RefPtr<ResourceHandle> m_currentHandle;
177     RefPtr<ApplicationCacheResource> m_currentResource;
178 
179     RefPtr<ApplicationCacheResource> m_manifestResource;
180     RefPtr<ResourceHandle> m_manifestHandle;
181 
182     friend class ChromeClientCallbackTimer;
183 };
184 
185 } // namespace WebCore
186 
187 #endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
188 
189 #endif // ApplicationCacheGroup_h
190