• 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     virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
101     virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
102     virtual void didFinishLoading(ResourceHandle*);
103     virtual void didFail(ResourceHandle*, const ResourceError&);
104 
105     void didReceiveManifestResponse(const ResourceResponse&);
106     void didReceiveManifestData(const char*, int);
107     void didFinishLoadingManifest();
108     void didReachMaxAppCacheSize();
109 
110     void startLoadingEntry();
111     void deliverDelayedMainResources();
112     void checkIfLoadIsComplete();
113     void cacheUpdateFailed();
114     void manifestNotFound();
115 
116     void addEntry(const String&, unsigned type);
117 
118     void associateDocumentLoaderWithCache(DocumentLoader*, ApplicationCache*);
119 
120     void stopLoading();
121 
122     KURL m_manifestURL;
123     UpdateStatus m_updateStatus;
124 
125     // This is the newest complete cache in the group.
126     RefPtr<ApplicationCache> m_newestCache;
127 
128     // All complete caches in this cache group.
129     HashSet<ApplicationCache*> m_caches;
130 
131     // The cache being updated (if any). Note that cache updating does not immediately create a new
132     // ApplicationCache object, so this may be null even when update status is not Idle.
133     RefPtr<ApplicationCache> m_cacheBeingUpdated;
134 
135     // List of pending master entries, used during the update process to ensure that new master entries are cached.
136     HashSet<DocumentLoader*> m_pendingMasterResourceLoaders;
137     // How many of the above pending master entries have not yet finished downloading.
138     int m_downloadingPendingMasterResourceLoadersCount;
139 
140     // These are all the document loaders that are associated with a cache in this group.
141     HashSet<DocumentLoader*> m_associatedDocumentLoaders;
142 
143     // The URLs and types of pending cache entries.
144     typedef HashMap<String, unsigned> EntryMap;
145     EntryMap m_pendingEntries;
146 
147     // Frame used for fetching resources when updating.
148     // 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.
149     Frame* m_frame;
150 
151     // An obsolete cache group is never stored, but the opposite is not true - storing may fail for multiple reasons, such as exceeding disk quota.
152     unsigned m_storageID;
153     bool m_isObsolete;
154 
155     // During update, this is used to handle asynchronously arriving results.
156     enum CompletionType {
157         None,
158         NoUpdate,
159         Failure,
160         Completed
161     };
162     CompletionType m_completionType;
163 
164     // Whether this cache group is a copy that's only used for transferring the cache to another file.
165     bool m_isCopy;
166 
167     // This flag is set immediately after the ChromeClient::reachedMaxAppCacheSize() callback is invoked as a result of the storage layer failing to save a cache
168     // due to reaching the maximum size of the application cache database file. This flag is used by ApplicationCacheGroup::checkIfLoadIsComplete() to decide
169     // the course of action in case of this failure (i.e. call the ChromeClient callback or run the failure steps).
170     bool m_calledReachedMaxAppCacheSize;
171 
172     RefPtr<ResourceHandle> m_currentHandle;
173     RefPtr<ApplicationCacheResource> m_currentResource;
174 
175     RefPtr<ApplicationCacheResource> m_manifestResource;
176     RefPtr<ResourceHandle> m_manifestHandle;
177 
178     friend class ChromeClientCallbackTimer;
179 };
180 
181 } // namespace WebCore
182 
183 #endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
184 
185 #endif // ApplicationCacheGroup_h
186