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