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