diff options
Diffstat (limited to 'WebCore/loader/appcache')
-rw-r--r-- | WebCore/loader/appcache/ApplicationCache.cpp | 192 | ||||
-rw-r--r-- | WebCore/loader/appcache/ApplicationCache.h | 103 | ||||
-rw-r--r-- | WebCore/loader/appcache/ApplicationCacheGroup.cpp | 715 | ||||
-rw-r--r-- | WebCore/loader/appcache/ApplicationCacheGroup.h | 152 | ||||
-rw-r--r-- | WebCore/loader/appcache/ApplicationCacheResource.cpp | 71 | ||||
-rw-r--r-- | WebCore/loader/appcache/ApplicationCacheResource.h | 74 | ||||
-rw-r--r-- | WebCore/loader/appcache/ApplicationCacheStorage.cpp | 663 | ||||
-rw-r--r-- | WebCore/loader/appcache/ApplicationCacheStorage.h | 96 | ||||
-rw-r--r-- | WebCore/loader/appcache/DOMApplicationCache.cpp | 286 | ||||
-rw-r--r-- | WebCore/loader/appcache/DOMApplicationCache.h | 140 | ||||
-rw-r--r-- | WebCore/loader/appcache/DOMApplicationCache.idl | 74 | ||||
-rw-r--r-- | WebCore/loader/appcache/ManifestParser.cpp | 166 | ||||
-rw-r--r-- | WebCore/loader/appcache/ManifestParser.h | 52 |
13 files changed, 0 insertions, 2784 deletions
diff --git a/WebCore/loader/appcache/ApplicationCache.cpp b/WebCore/loader/appcache/ApplicationCache.cpp deleted file mode 100644 index d29eda8..0000000 --- a/WebCore/loader/appcache/ApplicationCache.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ApplicationCache.h" - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include "ApplicationCacheGroup.h" -#include "ApplicationCacheResource.h" -#include "ApplicationCacheStorage.h" -#include "ResourceRequest.h" -#include <stdio.h> - -namespace WebCore { - -ApplicationCache::ApplicationCache() - : m_group(0) - , m_manifest(0) - , m_storageID(0) -{ -} - -ApplicationCache::~ApplicationCache() -{ - if (m_group && !m_group->isCopy()) - m_group->cacheDestroyed(this); -} - -void ApplicationCache::setGroup(ApplicationCacheGroup* group) -{ - ASSERT(!m_group); - m_group = group; -} - -void ApplicationCache::setManifestResource(PassRefPtr<ApplicationCacheResource> manifest) -{ - ASSERT(manifest); - ASSERT(!m_manifest); - ASSERT(manifest->type() & ApplicationCacheResource::Manifest); - - m_manifest = manifest.get(); - - addResource(manifest); -} - -void ApplicationCache::addResource(PassRefPtr<ApplicationCacheResource> resource) -{ - ASSERT(resource); - - const String& url = resource->url(); - - ASSERT(!m_resources.contains(url)); - - if (m_storageID) { - ASSERT(!resource->storageID()); - - // Add the resource to the storage. - cacheStorage().store(resource.get(), this); - } - - m_resources.set(url, resource); -} - -unsigned ApplicationCache::removeResource(const String& url) -{ - HashMap<String, RefPtr<ApplicationCacheResource> >::iterator it = m_resources.find(url); - if (it == m_resources.end()) - return 0; - - // The resource exists, get its type so we can return it. - unsigned type = it->second->type(); - - m_resources.remove(it); - - return type; -} - -ApplicationCacheResource* ApplicationCache::resourceForURL(const String& url) -{ - return m_resources.get(url).get(); -} - -bool ApplicationCache::requestIsHTTPOrHTTPSGet(const ResourceRequest& request) -{ - if (!request.url().protocolIs("http") && !request.url().protocolIs("https")) - return false; - - if (!equalIgnoringCase(request.httpMethod(), "GET")) - return false; - - return true; -} - -ApplicationCacheResource* ApplicationCache::resourceForRequest(const ResourceRequest& request) -{ - // We only care about HTTP/HTTPS GET requests. - if (!requestIsHTTPOrHTTPSGet(request)) - return false; - - return resourceForURL(request.url()); -} - -unsigned ApplicationCache::numDynamicEntries() const -{ - // FIXME: Implement - return 0; -} - -String ApplicationCache::dynamicEntry(unsigned index) const -{ - // FIXME: Implement - return String(); -} - -bool ApplicationCache::addDynamicEntry(const String& url) -{ - if (!equalIgnoringCase(m_group->manifestURL().protocol(), - KURL(url).protocol())) - return false; - - // FIXME: Implement - return true; -} - -void ApplicationCache::removeDynamicEntry(const String& url) -{ - // FIXME: Implement -} - -void ApplicationCache::setOnlineWhitelist(const HashSet<String>& onlineWhitelist) -{ - ASSERT(m_onlineWhitelist.isEmpty()); - m_onlineWhitelist = onlineWhitelist; -} - -bool ApplicationCache::isURLInOnlineWhitelist(const KURL& url) -{ - if (!url.hasRef()) - return m_onlineWhitelist.contains(url); - - KURL copy(url); - copy.setRef(String()); - return m_onlineWhitelist.contains(copy); -} - -void ApplicationCache::clearStorageID() -{ - m_storageID = 0; - - ResourceMap::const_iterator end = m_resources.end(); - for (ResourceMap::const_iterator it = m_resources.begin(); it != end; ++it) - it->second->clearStorageID(); -} - -#ifndef NDEBUG -void ApplicationCache::dump() -{ - HashMap<String, RefPtr<ApplicationCacheResource> >::const_iterator end = m_resources.end(); - - for (HashMap<String, RefPtr<ApplicationCacheResource> >::const_iterator it = m_resources.begin(); it != end; ++it) { - printf("%s ", it->first.ascii().data()); - ApplicationCacheResource::dumpType(it->second->type()); - } -} -#endif - -} - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) diff --git a/WebCore/loader/appcache/ApplicationCache.h b/WebCore/loader/appcache/ApplicationCache.h deleted file mode 100644 index e536cbe..0000000 --- a/WebCore/loader/appcache/ApplicationCache.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ApplicationCache_h -#define ApplicationCache_h - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include <wtf/HashMap.h> -#include <wtf/HashSet.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> - -#include "StringHash.h" -#include "PlatformString.h" - -namespace WebCore { - -class ApplicationCacheGroup; -class ApplicationCacheResource; -class DocumentLoader; -class KURL; -class ResourceRequest; - -class ApplicationCache : public RefCounted<ApplicationCache> { -public: - static PassRefPtr<ApplicationCache> create() { return adoptRef(new ApplicationCache); } - ~ApplicationCache(); - - void addResource(PassRefPtr<ApplicationCacheResource> resource); - unsigned removeResource(const String& url); - - void setManifestResource(PassRefPtr<ApplicationCacheResource> manifest); - ApplicationCacheResource* manifestResource() const { return m_manifest; } - - void setGroup(ApplicationCacheGroup*); - ApplicationCacheGroup* group() const { return m_group; } - - ApplicationCacheResource* resourceForRequest(const ResourceRequest&); - ApplicationCacheResource* resourceForURL(const String& url); - - unsigned numDynamicEntries() const; - String dynamicEntry(unsigned index) const; - - bool addDynamicEntry(const String& url); - void removeDynamicEntry(const String& url); - - void setOnlineWhitelist(const HashSet<String>& onlineWhitelist); - const HashSet<String>& onlineWhitelist() const { return m_onlineWhitelist; } - bool isURLInOnlineWhitelist(const KURL&); - -#ifndef NDEBUG - void dump(); -#endif - - typedef HashMap<String, RefPtr<ApplicationCacheResource> > ResourceMap; - ResourceMap::const_iterator begin() const { return m_resources.begin(); } - ResourceMap::const_iterator end() const { return m_resources.end(); } - - void setStorageID(unsigned storageID) { m_storageID = storageID; } - unsigned storageID() const { return m_storageID; } - void clearStorageID(); - - static bool requestIsHTTPOrHTTPSGet(const ResourceRequest&); -private: - ApplicationCache(); - - ApplicationCacheGroup* m_group; - ResourceMap m_resources; - ApplicationCacheResource* m_manifest; - - HashSet<String> m_onlineWhitelist; - - unsigned m_storageID; -}; - -} // namespace WebCore - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) - -#endif // ApplicationCache_h diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/WebCore/loader/appcache/ApplicationCacheGroup.cpp deleted file mode 100644 index ff26767..0000000 --- a/WebCore/loader/appcache/ApplicationCacheGroup.cpp +++ /dev/null @@ -1,715 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ApplicationCacheGroup.h" - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include "ApplicationCache.h" -#include "ApplicationCacheResource.h" -#include "ApplicationCacheStorage.h" -#include "DocumentLoader.h" -#include "DOMApplicationCache.h" -#include "DOMWindow.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "MainResourceLoader.h" -#include "ManifestParser.h" -#include "Page.h" -#include "Settings.h" -#include <wtf/HashMap.h> - -namespace WebCore { - -ApplicationCacheGroup::ApplicationCacheGroup(const KURL& manifestURL, bool isCopy) - : m_manifestURL(manifestURL) - , m_status(Idle) - , m_savedNewestCachePointer(0) - , m_frame(0) - , m_storageID(0) - , m_isCopy(isCopy) -{ -} - -ApplicationCacheGroup::~ApplicationCacheGroup() -{ - if (m_isCopy) { - ASSERT(m_newestCache); - ASSERT(m_caches.size() == 1); - ASSERT(m_caches.contains(m_newestCache.get())); - ASSERT(!m_cacheBeingUpdated); - ASSERT(m_associatedDocumentLoaders.isEmpty()); - ASSERT(m_cacheCandidates.isEmpty()); - ASSERT(m_newestCache->group() == this); - - return; - } - - ASSERT(!m_newestCache); - ASSERT(m_caches.isEmpty()); - - stopLoading(); - - cacheStorage().cacheGroupDestroyed(this); -} - -ApplicationCache* ApplicationCacheGroup::cacheForMainRequest(const ResourceRequest& request, DocumentLoader* loader) -{ - if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request)) - return 0; - - ASSERT(loader->frame()); - ASSERT(loader->frame()->page()); - if (loader->frame() != loader->frame()->page()->mainFrame()) - return 0; - - if (ApplicationCacheGroup* group = cacheStorage().cacheGroupForURL(request.url())) { - ASSERT(group->newestCache()); - - return group->newestCache(); - } - - return 0; -} - -void ApplicationCacheGroup::selectCache(Frame* frame, const KURL& manifestURL) -{ - ASSERT(frame && frame->page()); - - if (!frame->settings()->offlineWebApplicationCacheEnabled()) - return; - - DocumentLoader* documentLoader = frame->loader()->documentLoader(); - ASSERT(!documentLoader->applicationCache()); - - if (manifestURL.isNull()) { - selectCacheWithoutManifestURL(frame); - return; - } - - ApplicationCache* mainResourceCache = documentLoader->mainResourceApplicationCache(); - - // Check if the main resource is being loaded as part of navigation of the main frame - bool isMainFrame = frame->page()->mainFrame() == frame; - - if (!isMainFrame) { - if (mainResourceCache && manifestURL != mainResourceCache->group()->manifestURL()) { - ApplicationCacheResource* resource = mainResourceCache->resourceForURL(documentLoader->originalURL()); - ASSERT(resource); - - resource->addType(ApplicationCacheResource::Foreign); - } - - return; - } - - if (mainResourceCache) { - if (manifestURL == mainResourceCache->group()->m_manifestURL) { - mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache); - mainResourceCache->group()->update(frame); - } else { - // FIXME: If the resource being loaded was loaded from an application cache and the URI of - // that application cache's manifest is not the same as the manifest URI with which the algorithm was invoked - // then we should "undo" the navigation. - } - - return; - } - - // The resource was loaded from the network, check if it is a HTTP/HTTPS GET. - const ResourceRequest& request = frame->loader()->activeDocumentLoader()->request(); - - if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request)) { - selectCacheWithoutManifestURL(frame); - return; - } - - // Check that the resource URL has the same scheme/host/port as the manifest URL. - if (!protocolHostAndPortAreEqual(manifestURL, request.url())) { - selectCacheWithoutManifestURL(frame); - return; - } - - ApplicationCacheGroup* group = cacheStorage().findOrCreateCacheGroup(manifestURL); - - if (ApplicationCache* cache = group->newestCache()) { - ASSERT(cache->manifestResource()); - - group->associateDocumentLoaderWithCache(frame->loader()->documentLoader(), cache); - - if (!frame->loader()->documentLoader()->isLoadingMainResource()) - group->finishedLoadingMainResource(frame->loader()->documentLoader()); - - group->update(frame); - } else { - bool isUpdating = group->m_cacheBeingUpdated; - - if (!isUpdating) - group->m_cacheBeingUpdated = ApplicationCache::create(); - documentLoader->setCandidateApplicationCacheGroup(group); - group->m_cacheCandidates.add(documentLoader); - - const KURL& url = frame->loader()->documentLoader()->originalURL(); - - unsigned type = 0; - - // If the resource has already been downloaded, remove it so that it will be replaced with the implicit resource - if (isUpdating) - type = group->m_cacheBeingUpdated->removeResource(url); - - // Add the main resource URL as an implicit entry. - group->addEntry(url, type | ApplicationCacheResource::Implicit); - - if (!frame->loader()->documentLoader()->isLoadingMainResource()) - group->finishedLoadingMainResource(frame->loader()->documentLoader()); - - if (!isUpdating) - group->update(frame); - } -} - -void ApplicationCacheGroup::selectCacheWithoutManifestURL(Frame* frame) -{ - if (!frame->settings()->offlineWebApplicationCacheEnabled()) - return; - - DocumentLoader* documentLoader = frame->loader()->documentLoader(); - ASSERT(!documentLoader->applicationCache()); - - ApplicationCache* mainResourceCache = documentLoader->mainResourceApplicationCache(); - bool isMainFrame = frame->page()->mainFrame() == frame; - - if (isMainFrame && mainResourceCache) { - mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache); - mainResourceCache->group()->update(frame); - } -} - -void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader) -{ - const KURL& url = loader->originalURL(); - - if (ApplicationCache* cache = loader->applicationCache()) { - RefPtr<ApplicationCacheResource> resource = ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Implicit, loader->mainResourceData()); - cache->addResource(resource.release()); - - if (!m_cacheBeingUpdated) - return; - } - - ASSERT(m_pendingEntries.contains(url)); - - EntryMap::iterator it = m_pendingEntries.find(url); - ASSERT(it->second & ApplicationCacheResource::Implicit); - - RefPtr<ApplicationCacheResource> resource = ApplicationCacheResource::create(url, loader->response(), it->second, loader->mainResourceData()); - - ASSERT(m_cacheBeingUpdated); - m_cacheBeingUpdated->addResource(resource.release()); - - m_pendingEntries.remove(it); - - checkIfLoadIsComplete(); -} - -void ApplicationCacheGroup::failedLoadingMainResource(DocumentLoader* loader) -{ - ASSERT(m_cacheCandidates.contains(loader) || m_associatedDocumentLoaders.contains(loader)); - - // Note that cacheUpdateFailed() can cause the cache group to be deleted. - cacheUpdateFailed(); -} - -void ApplicationCacheGroup::stopLoading() -{ - if (m_manifestHandle) { - ASSERT(!m_currentHandle); - ASSERT(!m_cacheBeingUpdated); - - m_manifestHandle->setClient(0); - m_manifestHandle->cancel(); - m_manifestHandle = 0; - } - - if (m_currentHandle) { - ASSERT(!m_manifestHandle); - ASSERT(m_cacheBeingUpdated); - - m_currentHandle->setClient(0); - m_currentHandle->cancel(); - m_currentHandle = 0; - } - - m_cacheBeingUpdated = 0; -} - -void ApplicationCacheGroup::documentLoaderDestroyed(DocumentLoader* loader) -{ - HashSet<DocumentLoader*>::iterator it = m_associatedDocumentLoaders.find(loader); - - if (it != m_associatedDocumentLoaders.end()) { - ASSERT(!m_cacheCandidates.contains(loader)); - - m_associatedDocumentLoaders.remove(it); - } else { - ASSERT(m_cacheCandidates.contains(loader)); - m_cacheCandidates.remove(loader); - } - - if (!m_associatedDocumentLoaders.isEmpty() || !m_cacheCandidates.isEmpty()) - return; - - // We should only have the newest cache remaining, or there is an initial cache attempt in progress. - ASSERT(m_caches.size() == 1 || m_cacheBeingUpdated); - - // If a cache update is in progress, stop it. - if (m_caches.size() == 1) { - ASSERT(m_caches.contains(m_newestCache.get())); - - // Release our reference to the newest cache. - m_savedNewestCachePointer = m_newestCache.get(); - - // This could cause us to be deleted. - m_newestCache = 0; - - return; - } - - // There is an initial cache attempt in progress - ASSERT(m_cacheBeingUpdated); - ASSERT(m_caches.size() == 0); - - // Delete ourselves, causing the cache attempt to be stopped. - delete this; -} - -void ApplicationCacheGroup::cacheDestroyed(ApplicationCache* cache) -{ - ASSERT(m_caches.contains(cache)); - - m_caches.remove(cache); - - if (cache != m_savedNewestCachePointer) - cacheStorage().remove(cache); - - if (m_caches.isEmpty()) - delete this; -} - -void ApplicationCacheGroup::setNewestCache(PassRefPtr<ApplicationCache> newestCache) -{ - ASSERT(!m_newestCache); - ASSERT(!m_caches.contains(newestCache.get())); - ASSERT(!newestCache->group()); - - m_newestCache = newestCache; - m_caches.add(m_newestCache.get()); - m_newestCache->setGroup(this); -} - -void ApplicationCacheGroup::update(Frame* frame) -{ - if (m_status == Checking || m_status == Downloading) - return; - - ASSERT(!m_frame); - m_frame = frame; - - m_status = Checking; - - callListenersOnAssociatedDocuments(&DOMApplicationCache::callCheckingListener); - - ASSERT(!m_manifestHandle); - ASSERT(!m_manifestResource); - - // FIXME: Handle defer loading - - ResourceRequest request(m_manifestURL); - m_frame->loader()->applyUserAgent(request); - - m_manifestHandle = ResourceHandle::create(request, this, m_frame, false, true, false); -} - -void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response) -{ - if (handle == m_manifestHandle) { - didReceiveManifestResponse(response); - return; - } - - ASSERT(handle == m_currentHandle); - - int statusCode = response.httpStatusCode() / 100; - if (statusCode == 4 || statusCode == 5) { - // Note that cacheUpdateFailed() can cause the cache group to be deleted. - cacheUpdateFailed(); - return; - } - - const KURL& url = handle->request().url(); - - ASSERT(!m_currentResource); - ASSERT(m_pendingEntries.contains(url)); - - unsigned type = m_pendingEntries.get(url); - - // If this is an initial cache attempt, we should not get implicit resources delivered here. - if (!m_newestCache) - ASSERT(!(type & ApplicationCacheResource::Implicit)); - - m_currentResource = ApplicationCacheResource::create(url, response, type); -} - -void ApplicationCacheGroup::didReceiveData(ResourceHandle* handle, const char* data, int length, int lengthReceived) -{ - if (handle == m_manifestHandle) { - didReceiveManifestData(data, length); - return; - } - - ASSERT(handle == m_currentHandle); - - ASSERT(m_currentResource); - m_currentResource->data()->append(data, length); -} - -void ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle) -{ - if (handle == m_manifestHandle) { - didFinishLoadingManifest(); - return; - } - - ASSERT(m_currentHandle == handle); - ASSERT(m_pendingEntries.contains(handle->request().url())); - - m_pendingEntries.remove(handle->request().url()); - - ASSERT(m_cacheBeingUpdated); - - m_cacheBeingUpdated->addResource(m_currentResource.release()); - m_currentHandle = 0; - - // Load the next file. - if (!m_pendingEntries.isEmpty()) { - startLoadingEntry(); - return; - } - - checkIfLoadIsComplete(); -} - -void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError&) -{ - if (handle == m_manifestHandle) { - didFailToLoadManifest(); - return; - } - - // Note that cacheUpdateFailed() can cause the cache group to be deleted. - cacheUpdateFailed(); -} - -void ApplicationCacheGroup::didReceiveManifestResponse(const ResourceResponse& response) -{ - int statusCode = response.httpStatusCode() / 100; - - if (statusCode == 4 || statusCode == 5 || - !equalIgnoringCase(response.mimeType(), "text/cache-manifest")) { - didFailToLoadManifest(); - return; - } - - ASSERT(!m_manifestResource); - ASSERT(m_manifestHandle); - m_manifestResource = ApplicationCacheResource::create(m_manifestHandle->request().url(), response, - ApplicationCacheResource::Manifest); -} - -void ApplicationCacheGroup::didReceiveManifestData(const char* data, int length) -{ - ASSERT(m_manifestResource); - m_manifestResource->data()->append(data, length); -} - -void ApplicationCacheGroup::didFinishLoadingManifest() -{ - if (!m_manifestResource) { - didFailToLoadManifest(); - return; - } - - bool isUpgradeAttempt = m_newestCache; - - m_manifestHandle = 0; - - // Check if the manifest is byte-for-byte identical. - if (isUpgradeAttempt) { - ApplicationCacheResource* newestManifest = m_newestCache->manifestResource(); - ASSERT(newestManifest); - - if (newestManifest->data()->size() == m_manifestResource->data()->size() && - !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size())) { - - callListenersOnAssociatedDocuments(&DOMApplicationCache::callNoUpdateListener); - - m_status = Idle; - m_frame = 0; - m_manifestResource = 0; - return; - } - } - - Manifest manifest; - if (!parseManifest(m_manifestURL, m_manifestResource->data()->data(), m_manifestResource->data()->size(), manifest)) { - didFailToLoadManifest(); - return; - } - - // FIXME: Add the opportunistic caching namespaces and their fallbacks. - - // We have the manifest, now download the resources. - m_status = Downloading; - - callListenersOnAssociatedDocuments(&DOMApplicationCache::callDownloadingListener); - -#ifndef NDEBUG - // We should only have implicit entries. - { - EntryMap::const_iterator end = m_pendingEntries.end(); - for (EntryMap::const_iterator it = m_pendingEntries.begin(); it != end; ++it) - ASSERT(it->second & ApplicationCacheResource::Implicit); - } -#endif - - if (isUpgradeAttempt) { - ASSERT(!m_cacheBeingUpdated); - - m_cacheBeingUpdated = ApplicationCache::create(); - - ApplicationCache::ResourceMap::const_iterator end = m_newestCache->end(); - for (ApplicationCache::ResourceMap::const_iterator it = m_newestCache->begin(); it != end; ++it) { - unsigned type = it->second->type(); - if (type & (ApplicationCacheResource::Opportunistic | ApplicationCacheResource::Implicit | ApplicationCacheResource::Dynamic)) - addEntry(it->first, type); - } - } - - HashSet<String>::const_iterator end = manifest.explicitURLs.end(); - for (HashSet<String>::const_iterator it = manifest.explicitURLs.begin(); it != end; ++it) - addEntry(*it, ApplicationCacheResource::Explicit); - - m_cacheBeingUpdated->setOnlineWhitelist(manifest.onlineWhitelistedURLs); - - startLoadingEntry(); -} - -void ApplicationCacheGroup::cacheUpdateFailed() -{ - stopLoading(); - - callListenersOnAssociatedDocuments(&DOMApplicationCache::callErrorListener); - - m_pendingEntries.clear(); - m_manifestResource = 0; - - while (!m_cacheCandidates.isEmpty()) { - HashSet<DocumentLoader*>::iterator it = m_cacheCandidates.begin(); - - ASSERT((*it)->candidateApplicationCacheGroup() == this); - (*it)->setCandidateApplicationCacheGroup(0); - m_cacheCandidates.remove(it); - } - - m_status = Idle; - m_frame = 0; - - // If there are no associated caches, delete ourselves - if (m_associatedDocumentLoaders.isEmpty()) - delete this; -} - - -void ApplicationCacheGroup::didFailToLoadManifest() -{ - // Note that cacheUpdateFailed() can cause the cache group to be deleted. - cacheUpdateFailed(); -} - -void ApplicationCacheGroup::checkIfLoadIsComplete() -{ - ASSERT(m_cacheBeingUpdated); - - if (m_manifestHandle) - return; - - if (!m_pendingEntries.isEmpty()) - return; - - // We're done - bool isUpgradeAttempt = m_newestCache; - - m_cacheBeingUpdated->setManifestResource(m_manifestResource.release()); - - m_status = Idle; - m_frame = 0; - - Vector<RefPtr<DocumentLoader> > documentLoaders; - - if (isUpgradeAttempt) { - ASSERT(m_cacheCandidates.isEmpty()); - - copyToVector(m_associatedDocumentLoaders, documentLoaders); - } else { - while (!m_cacheCandidates.isEmpty()) { - HashSet<DocumentLoader*>::iterator it = m_cacheCandidates.begin(); - - DocumentLoader* loader = *it; - ASSERT(!loader->applicationCache()); - ASSERT(loader->candidateApplicationCacheGroup() == this); - - associateDocumentLoaderWithCache(loader, m_cacheBeingUpdated.get()); - - documentLoaders.append(loader); - - m_cacheCandidates.remove(it); - } - } - - setNewestCache(m_cacheBeingUpdated.release()); - - // Store the cache - cacheStorage().storeNewestCache(this); - - callListeners(isUpgradeAttempt ? &DOMApplicationCache::callUpdateReadyListener : &DOMApplicationCache::callCachedListener, - documentLoaders); -} - -void ApplicationCacheGroup::startLoadingEntry() -{ - ASSERT(m_cacheBeingUpdated); - - if (m_pendingEntries.isEmpty()) { - checkIfLoadIsComplete(); - return; - } - - EntryMap::const_iterator it = m_pendingEntries.begin(); - - // If this is an initial cache attempt, we do not want to fetch any implicit entries, - // since those are fed to us by the normal loader machinery. - if (!m_newestCache) { - // Get the first URL in the entry table that is not implicit - EntryMap::const_iterator end = m_pendingEntries.end(); - - while (it->second & ApplicationCacheResource::Implicit) { - ++it; - - if (it == end) - return; - } - } - - callListenersOnAssociatedDocuments(&DOMApplicationCache::callProgressListener); - - // FIXME: If this is an upgrade attempt, the newest cache should be used as an HTTP cache. - - ASSERT(!m_currentHandle); - - ResourceRequest request(it->first); - m_frame->loader()->applyUserAgent(request); - - m_currentHandle = ResourceHandle::create(request, this, m_frame, false, true, false); -} - -void ApplicationCacheGroup::addEntry(const String& url, unsigned type) -{ - ASSERT(m_cacheBeingUpdated); - - // Don't add the URL if we already have an implicit resource in the cache - if (ApplicationCacheResource* resource = m_cacheBeingUpdated->resourceForURL(url)) { - ASSERT(resource->type() & ApplicationCacheResource::Implicit); - - resource->addType(type); - return; - } - - // Don't add the URL if it's the same as the manifest URL. - if (m_manifestResource && m_manifestResource->url() == url) { - m_manifestResource->addType(type); - return; - } - - pair<EntryMap::iterator, bool> result = m_pendingEntries.add(url, type); - - if (!result.second) - result.first->second |= type; -} - -void ApplicationCacheGroup::associateDocumentLoaderWithCache(DocumentLoader* loader, ApplicationCache* cache) -{ - loader->setApplicationCache(cache); - - ASSERT(!m_associatedDocumentLoaders.contains(loader)); - m_associatedDocumentLoaders.add(loader); -} - -void ApplicationCacheGroup::callListenersOnAssociatedDocuments(ListenerFunction listenerFunction) -{ - Vector<RefPtr<DocumentLoader> > loaders; - copyToVector(m_associatedDocumentLoaders, loaders); - - callListeners(listenerFunction, loaders); -} - -void ApplicationCacheGroup::callListeners(ListenerFunction listenerFunction, const Vector<RefPtr<DocumentLoader> >& loaders) -{ - for (unsigned i = 0; i < loaders.size(); i++) { - Frame* frame = loaders[i]->frame(); - if (!frame) - continue; - - ASSERT(frame->loader()->documentLoader() == loaders[i]); - DOMWindow* window = frame->domWindow(); - - if (DOMApplicationCache* domCache = window->optionalApplicationCache()) - (domCache->*listenerFunction)(); - } -} - -void ApplicationCacheGroup::clearStorageID() -{ - m_storageID = 0; - - HashSet<ApplicationCache*>::const_iterator end = m_caches.end(); - for (HashSet<ApplicationCache*>::const_iterator it = m_caches.begin(); it != end; ++it) - (*it)->clearStorageID(); -} - - -} - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.h b/WebCore/loader/appcache/ApplicationCacheGroup.h deleted file mode 100644 index d5b7563..0000000 --- a/WebCore/loader/appcache/ApplicationCacheGroup.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ApplicationCacheGroup_h -#define ApplicationCacheGroup_h - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include <wtf/Noncopyable.h> -#include <wtf/HashMap.h> -#include <wtf/HashSet.h> - -#include "KURL.h" -#include "PlatformString.h" -#include "ResourceHandle.h" -#include "ResourceHandleClient.h" -#include "SharedBuffer.h" - -namespace WebCore { - -class ApplicationCache; -class ApplicationCacheResource; -class DOMApplicationCache; -class Document; -class DocumentLoader; -class Frame; - -class ApplicationCacheGroup : Noncopyable, ResourceHandleClient { -public: - ApplicationCacheGroup(const KURL& manifestURL, bool isCopy = false); - ~ApplicationCacheGroup(); - - enum Status { Idle, Checking, Downloading }; - - static ApplicationCache* cacheForMainRequest(const ResourceRequest&, DocumentLoader*); - - static void selectCache(Frame*, const KURL& manifestURL); - static void selectCacheWithoutManifestURL(Frame*); - - const KURL& manifestURL() const { return m_manifestURL; } - Status status() const { return m_status; } - - void setStorageID(unsigned storageID) { m_storageID = storageID; } - unsigned storageID() const { return m_storageID; } - void clearStorageID(); - - void update(Frame*); - void cacheDestroyed(ApplicationCache*); - - ApplicationCache* newestCache() const { return m_newestCache.get(); } - ApplicationCache* savedNewestCachePointer() const { return m_savedNewestCachePointer; } - - void finishedLoadingMainResource(DocumentLoader*); - void failedLoadingMainResource(DocumentLoader*); - void documentLoaderDestroyed(DocumentLoader*); - - void setNewestCache(PassRefPtr<ApplicationCache> newestCache); - - bool isCopy() const { return m_isCopy; } -private: - typedef void (DOMApplicationCache::*ListenerFunction)(); - void callListenersOnAssociatedDocuments(ListenerFunction); - void callListeners(ListenerFunction, const Vector<RefPtr<DocumentLoader> >& loaders); - - virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); - virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived); - virtual void didFinishLoading(ResourceHandle*); - virtual void didFail(ResourceHandle*, const ResourceError&); - - void didReceiveManifestResponse(const ResourceResponse&); - void didReceiveManifestData(const char*, int); - void didFinishLoadingManifest(); - void didFailToLoadManifest(); - - void startLoadingEntry(); - void checkIfLoadIsComplete(); - void cacheUpdateFailed(); - - void addEntry(const String&, unsigned type); - - void associateDocumentLoaderWithCache(DocumentLoader*, ApplicationCache*); - - void stopLoading(); - - KURL m_manifestURL; - Status m_status; - - // This is the newest cache in the group. - RefPtr<ApplicationCache> m_newestCache; - - // During tear-down we save the pointer to the newest cache to prevent reference cycles. - ApplicationCache* m_savedNewestCachePointer; - - // The caches in this cache group. - HashSet<ApplicationCache*> m_caches; - - // The cache being updated (if any). - RefPtr<ApplicationCache> m_cacheBeingUpdated; - - // When a cache group does not yet have a complete cache, this contains the document loaders - // that should be associated with the cache once it has been downloaded. - HashSet<DocumentLoader*> m_cacheCandidates; - - // These are all the document loaders that are associated with a cache in this group. - HashSet<DocumentLoader*> m_associatedDocumentLoaders; - - // The URLs and types of pending cache entries. - typedef HashMap<String, unsigned> EntryMap; - EntryMap m_pendingEntries; - - // Frame used for fetching resources when updating - Frame* m_frame; - - unsigned m_storageID; - - // Whether this cache group is a copy that's only used for transferring the cache to another file. - bool m_isCopy; - - RefPtr<ResourceHandle> m_currentHandle; - RefPtr<ApplicationCacheResource> m_currentResource; - - RefPtr<ApplicationCacheResource> m_manifestResource; - RefPtr<ResourceHandle> m_manifestHandle; -}; - -} // namespace WebCore - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) - -#endif // ApplicationCacheGroup_h diff --git a/WebCore/loader/appcache/ApplicationCacheResource.cpp b/WebCore/loader/appcache/ApplicationCacheResource.cpp deleted file mode 100644 index ee82ff5..0000000 --- a/WebCore/loader/appcache/ApplicationCacheResource.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ApplicationCacheResource.h" -#include <stdio.h> - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -namespace WebCore { - -ApplicationCacheResource::ApplicationCacheResource(const KURL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> data) - : SubstituteResource(url, response, data) - , m_type(type) - , m_storageID(0) -{ -} - -void ApplicationCacheResource::addType(unsigned type) -{ - ASSERT(!m_storageID); - m_type |= type; -} - -#ifndef NDEBUG -void ApplicationCacheResource::dumpType(unsigned type) -{ - if (type & Implicit) - printf("implicit "); - if (type & Manifest) - printf("manifest "); - if (type & Explicit) - printf("explicit "); - if (type & Foreign) - printf("foreign "); - if (type & Fallback) - printf("fallback "); - if (type & Opportunistic) - printf("opportunistic "); - if (type & Dynamic) - printf("dynamic "); - - printf("\n"); -} -#endif - -} // namespace WebCore - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) diff --git a/WebCore/loader/appcache/ApplicationCacheResource.h b/WebCore/loader/appcache/ApplicationCacheResource.h deleted file mode 100644 index 1d7b853..0000000 --- a/WebCore/loader/appcache/ApplicationCacheResource.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ApplicationCacheResource_h -#define ApplicationCacheResource_h - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include "SubstituteResource.h" - -namespace WebCore { - -class ApplicationCacheResource : public SubstituteResource { -public: - enum Type { - Implicit = 1 << 0, - Manifest = 1 << 1, - Explicit = 1 << 2, - Foreign = 1 << 3, - Fallback = 1 << 4, - Opportunistic = 1 << 5, - Dynamic = 1 << 6 - }; - - static PassRefPtr<ApplicationCacheResource> create(const KURL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> buffer = SharedBuffer::create()) - { - return adoptRef(new ApplicationCacheResource(url, response, type, buffer)); - } - - unsigned type() const { return m_type; } - void addType(unsigned type); - - void setStorageID(unsigned storageID) { m_storageID = storageID; } - unsigned storageID() const { return m_storageID; } - void clearStorageID() { m_storageID = 0; } - -#ifndef NDEBUG - static void dumpType(unsigned type); -#endif - -private: - ApplicationCacheResource(const KURL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> buffer); - - unsigned m_type; - unsigned m_storageID; -}; - -} // namespace WebCore - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) - -#endif // ApplicationCacheResource_h diff --git a/WebCore/loader/appcache/ApplicationCacheStorage.cpp b/WebCore/loader/appcache/ApplicationCacheStorage.cpp deleted file mode 100644 index 910d00c..0000000 --- a/WebCore/loader/appcache/ApplicationCacheStorage.cpp +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ApplicationCacheStorage.h" - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include "ApplicationCache.h" -#include "ApplicationCacheGroup.h" -#include "ApplicationCacheResource.h" -#include "FileSystem.h" -#include "CString.h" -#include "KURL.h" -#include "SQLiteStatement.h" -#include "SQLiteTransaction.h" - -namespace WebCore { - -static unsigned urlHostHash(const KURL& url) -{ - unsigned hostStart = url.hostStart(); - unsigned hostEnd = url.hostEnd(); - - return AlreadyHashed::avoidDeletedValue(StringImpl::computeHash(url.string().characters() + hostStart, hostEnd - hostStart)); -} - -ApplicationCacheGroup* ApplicationCacheStorage::loadCacheGroup(const KURL& manifestURL) -{ - openDatabase(false); - if (!m_database.isOpen()) - return 0; - - SQLiteStatement statement(m_database, "SELECT id, manifestURL, newestCache FROM CacheGroups WHERE newestCache IS NOT NULL AND manifestURL=?"); - if (statement.prepare() != SQLResultOk) - return 0; - - statement.bindText(1, manifestURL); - - int result = statement.step(); - if (result == SQLResultDone) - return 0; - - if (result != SQLResultRow) { - LOG_ERROR("Could not load cache group, error \"%s\"", m_database.lastErrorMsg()); - return 0; - } - - unsigned newestCacheStorageID = (unsigned)statement.getColumnInt64(2); - - RefPtr<ApplicationCache> cache = loadCache(newestCacheStorageID); - if (!cache) - return 0; - - ApplicationCacheGroup* group = new ApplicationCacheGroup(manifestURL); - - group->setStorageID((unsigned)statement.getColumnInt64(0)); - group->setNewestCache(cache.release()); - - return group; -} - -ApplicationCacheGroup* ApplicationCacheStorage::findOrCreateCacheGroup(const KURL& manifestURL) -{ - std::pair<CacheGroupMap::iterator, bool> result = m_cachesInMemory.add(manifestURL, 0); - - if (!result.second) { - ASSERT(result.first->second); - - return result.first->second; - } - - // Look up the group in the database - ApplicationCacheGroup* group = loadCacheGroup(manifestURL); - - // If the group was not found we need to create it - if (!group) { - group = new ApplicationCacheGroup(manifestURL); - m_cacheHostSet.add(urlHostHash(manifestURL)); - } - - result.first->second = group; - - return group; -} - -void ApplicationCacheStorage::loadManifestHostHashes() -{ - static bool hasLoadedHashes = false; - - if (hasLoadedHashes) - return; - - // We set this flag to true before the database has been opened - // to avoid trying to open the database over and over if it doesn't exist. - hasLoadedHashes = true; - - openDatabase(false); - if (!m_database.isOpen()) - return; - - // Fetch the host hashes. - SQLiteStatement statement(m_database, "SELECT manifestHostHash FROM CacheGroups"); - if (statement.prepare() != SQLResultOk) - return; - - int result; - while ((result = statement.step()) == SQLResultRow) - m_cacheHostSet.add((unsigned)statement.getColumnInt64(0)); -} - -ApplicationCacheGroup* ApplicationCacheStorage::cacheGroupForURL(const KURL& url) -{ - loadManifestHostHashes(); - - // Hash the host name and see if there's a manifest with the same host. - if (!m_cacheHostSet.contains(urlHostHash(url))) - return 0; - - // Check if a cache already exists in memory. - CacheGroupMap::const_iterator end = m_cachesInMemory.end(); - for (CacheGroupMap::const_iterator it = m_cachesInMemory.begin(); it != end; ++it) { - ApplicationCacheGroup* group = it->second; - - if (!protocolHostAndPortAreEqual(url, group->manifestURL())) - continue; - - if (ApplicationCache* cache = group->newestCache()) { - if (cache->resourceForURL(url)) - return group; - } - } - - if (!m_database.isOpen()) - return 0; - - // Check the database. Look for all cache groups with a newest cache. - SQLiteStatement statement(m_database, "SELECT id, manifestURL, newestCache FROM CacheGroups WHERE newestCache IS NOT NULL"); - if (statement.prepare() != SQLResultOk) - return 0; - - int result; - while ((result = statement.step()) == SQLResultRow) { - KURL manifestURL = KURL(statement.getColumnText(1)); - - if (!protocolHostAndPortAreEqual(url, manifestURL)) - continue; - - // We found a cache group that matches. Now check if the newest cache has a resource with - // a matching URL. - unsigned newestCacheID = (unsigned)statement.getColumnInt64(2); - RefPtr<ApplicationCache> cache = loadCache(newestCacheID); - - if (!cache->resourceForURL(url)) - continue; - - ApplicationCacheGroup* group = new ApplicationCacheGroup(manifestURL); - - group->setStorageID((unsigned)statement.getColumnInt64(0)); - group->setNewestCache(cache.release()); - - ASSERT(!m_cachesInMemory.contains(manifestURL)); - m_cachesInMemory.set(group->manifestURL(), group); - - return group; - } - - if (result != SQLResultDone) - LOG_ERROR("Could not load cache group, error \"%s\"", m_database.lastErrorMsg()); - - return 0; -} - -void ApplicationCacheStorage::cacheGroupDestroyed(ApplicationCacheGroup* group) -{ - ASSERT(m_cachesInMemory.get(group->manifestURL()) == group); - - m_cachesInMemory.remove(group->manifestURL()); - - // If the cache is half-created, we don't want it in the saved set. - if (!group->savedNewestCachePointer()) - m_cacheHostSet.remove(urlHostHash(group->manifestURL())); -} - -void ApplicationCacheStorage::setCacheDirectory(const String& cacheDirectory) -{ - ASSERT(m_cacheDirectory.isNull()); - ASSERT(!cacheDirectory.isNull()); - - m_cacheDirectory = cacheDirectory; -} - -bool ApplicationCacheStorage::executeSQLCommand(const String& sql) -{ - ASSERT(m_database.isOpen()); - - bool result = m_database.executeCommand(sql); - if (!result) - LOG_ERROR("Application Cache Storage: failed to execute statement \"%s\" error \"%s\"", - sql.utf8().data(), m_database.lastErrorMsg()); - - return result; -} - -static const int SchemaVersion = 2; - -void ApplicationCacheStorage::verifySchemaVersion() -{ - if (m_database.tableExists("SchemaVersion")) { - int version = SQLiteStatement(m_database, "SELECT version from SchemaVersion").getColumnInt(0); - - if (version == SchemaVersion) - return; - } - - m_database.clearAllTables(); - - SQLiteTransaction createSchemaVersionTable(m_database); - createSchemaVersionTable.begin(); - - executeSQLCommand("CREATE TABLE SchemaVersion (version INTEGER NOT NULL)"); - SQLiteStatement statement(m_database, "INSERT INTO SchemaVersion (version) VALUES (?)"); - if (statement.prepare() != SQLResultOk) - return; - - statement.bindInt64(1, SchemaVersion); - executeStatement(statement); - createSchemaVersionTable.commit(); -} - -void ApplicationCacheStorage::openDatabase(bool createIfDoesNotExist) -{ - if (m_database.isOpen()) - return; - - // The cache directory should never be null, but if it for some weird reason is we bail out. - if (m_cacheDirectory.isNull()) - return; - - String applicationCachePath = pathByAppendingComponent(m_cacheDirectory, "ApplicationCache.db"); - if (!createIfDoesNotExist && !fileExists(applicationCachePath)) - return; - - makeAllDirectories(m_cacheDirectory); - m_database.open(applicationCachePath); - - if (!m_database.isOpen()) - return; - - verifySchemaVersion(); - - // Create tables - executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheGroups (id INTEGER PRIMARY KEY AUTOINCREMENT, " - "manifestHostHash INTEGER NOT NULL ON CONFLICT FAIL, manifestURL TEXT UNIQUE ON CONFLICT FAIL, newestCache INTEGER)"); - executeSQLCommand("CREATE TABLE IF NOT EXISTS Caches (id INTEGER PRIMARY KEY AUTOINCREMENT, cacheGroup INTEGER)"); - executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheWhitelistURLs (url TEXT NOT NULL ON CONFLICT FAIL, cache INTEGER NOT NULL ON CONFLICT FAIL)"); - executeSQLCommand("CREATE TABLE IF NOT EXISTS FallbackURLs (namespace TEXT NOT NULL ON CONFLICT FAIL, fallbackURL TEXT NOT NULL ON CONFLICT FAIL, " - "cache INTEGER NOT NULL ON CONFLICT FAIL)"); - executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheEntries (cache INTEGER NOT NULL ON CONFLICT FAIL, type INTEGER, resource INTEGER NOT NULL)"); - executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResources (id INTEGER PRIMARY KEY AUTOINCREMENT, url TEXT NOT NULL ON CONFLICT FAIL, " - "statusCode INTEGER NOT NULL, responseURL TEXT NOT NULL, mimeType TEXT, textEncodingName TEXT, headers TEXT, data INTEGER NOT NULL ON CONFLICT FAIL)"); - executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResourceData (id INTEGER PRIMARY KEY AUTOINCREMENT, data BLOB)"); - - // When a cache is deleted, all its entries and its whitelist should be deleted. - executeSQLCommand("CREATE TRIGGER IF NOT EXISTS CacheDeleted AFTER DELETE ON Caches" - " FOR EACH ROW BEGIN" - " DELETE FROM CacheEntries WHERE cache = OLD.id;" - " DELETE FROM CacheWhitelistURLs WHERE cache = OLD.id;" - " DELETE FROM FallbackURLs WHERE cache = OLD.id;" - " END"); - - // When a cache resource is deleted, its data blob should also be deleted. - executeSQLCommand("CREATE TRIGGER IF NOT EXISTS CacheResourceDeleted AFTER DELETE ON CacheResources" - " FOR EACH ROW BEGIN" - " DELETE FROM CacheResourceData WHERE id = OLD.data;" - " END"); -} - -bool ApplicationCacheStorage::executeStatement(SQLiteStatement& statement) -{ - bool result = statement.executeCommand(); - if (!result) - LOG_ERROR("Application Cache Storage: failed to execute statement \"%s\" error \"%s\"", - statement.query().utf8().data(), m_database.lastErrorMsg()); - - return result; -} - -bool ApplicationCacheStorage::store(ApplicationCacheGroup* group) -{ - ASSERT(group->storageID() == 0); - - SQLiteStatement statement(m_database, "INSERT INTO CacheGroups (manifestHostHash, manifestURL) VALUES (?, ?)"); - if (statement.prepare() != SQLResultOk) - return false; - - statement.bindInt64(1, urlHostHash(group->manifestURL())); - statement.bindText(2, group->manifestURL()); - - if (!executeStatement(statement)) - return false; - - group->setStorageID((unsigned)m_database.lastInsertRowID()); - return true; -} - -bool ApplicationCacheStorage::store(ApplicationCache* cache) -{ - ASSERT(cache->storageID() == 0); - ASSERT(cache->group()->storageID() != 0); - - SQLiteStatement statement(m_database, "INSERT INTO Caches (cacheGroup) VALUES (?)"); - if (statement.prepare() != SQLResultOk) - return false; - - statement.bindInt64(1, cache->group()->storageID()); - - if (!executeStatement(statement)) - return false; - - unsigned cacheStorageID = (unsigned)m_database.lastInsertRowID(); - - // Store all resources - { - ApplicationCache::ResourceMap::const_iterator end = cache->end(); - for (ApplicationCache::ResourceMap::const_iterator it = cache->begin(); it != end; ++it) { - if (!store(it->second.get(), cacheStorageID)) - return false; - } - } - - // Store the online whitelist - const HashSet<String>& onlineWhitelist = cache->onlineWhitelist(); - { - HashSet<String>::const_iterator end = onlineWhitelist.end(); - for (HashSet<String>::const_iterator it = onlineWhitelist.begin(); it != end; ++it) { - SQLiteStatement statement(m_database, "INSERT INTO CacheWhitelistURLs (url, cache) VALUES (?, ?)"); - statement.prepare(); - - statement.bindText(1, *it); - statement.bindInt64(2, cacheStorageID); - - if (!executeStatement(statement)) - return false; - } - } - - cache->setStorageID(cacheStorageID); - return true; -} - -bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, unsigned cacheStorageID) -{ - ASSERT(cacheStorageID); - ASSERT(!resource->storageID()); - - openDatabase(true); - - // First, insert the data - SQLiteStatement dataStatement(m_database, "INSERT INTO CacheResourceData (data) VALUES (?)"); - if (dataStatement.prepare() != SQLResultOk) - return false; - - if (resource->data()->size()) - dataStatement.bindBlob(1, resource->data()->data(), resource->data()->size()); - - if (!dataStatement.executeCommand()) - return false; - - unsigned dataId = (unsigned)m_database.lastInsertRowID(); - - // Then, insert the resource - - // Serialize the headers - Vector<UChar> stringBuilder; - - HTTPHeaderMap::const_iterator end = resource->response().httpHeaderFields().end(); - for (HTTPHeaderMap::const_iterator it = resource->response().httpHeaderFields().begin(); it!= end; ++it) { - stringBuilder.append(it->first.characters(), it->first.length()); - stringBuilder.append((UChar)':'); - stringBuilder.append(it->second.characters(), it->second.length()); - stringBuilder.append((UChar)'\n'); - } - - String headers = String::adopt(stringBuilder); - - SQLiteStatement resourceStatement(m_database, "INSERT INTO CacheResources (url, statusCode, responseURL, headers, data, mimeType, textEncodingName) VALUES (?, ?, ?, ?, ?, ?, ?)"); - if (resourceStatement.prepare() != SQLResultOk) - return false; - - resourceStatement.bindText(1, resource->url()); - resourceStatement.bindInt64(2, resource->response().httpStatusCode()); - resourceStatement.bindText(3, resource->response().url()); - resourceStatement.bindText(4, headers); - resourceStatement.bindInt64(5, dataId); - resourceStatement.bindText(6, resource->response().mimeType()); - resourceStatement.bindText(7, resource->response().textEncodingName()); - - if (!executeStatement(resourceStatement)) - return false; - - unsigned resourceId = (unsigned)m_database.lastInsertRowID(); - - // Finally, insert the cache entry - SQLiteStatement entryStatement(m_database, "INSERT INTO CacheEntries (cache, type, resource) VALUES (?, ?, ?)"); - if (entryStatement.prepare() != SQLResultOk) - return false; - - entryStatement.bindInt64(1, cacheStorageID); - entryStatement.bindInt64(2, resource->type()); - entryStatement.bindInt64(3, resourceId); - - if (!executeStatement(entryStatement)) - return false; - - resource->setStorageID(resourceId); - return true; -} - -void ApplicationCacheStorage::store(ApplicationCacheResource* resource, ApplicationCache* cache) -{ - ASSERT(cache->storageID()); - - openDatabase(true); - - SQLiteTransaction storeResourceTransaction(m_database); - storeResourceTransaction.begin(); - - if (!store(resource, cache->storageID())) - return; - - storeResourceTransaction.commit(); -} - -bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group) -{ - openDatabase(true); - - SQLiteTransaction storeCacheTransaction(m_database); - - storeCacheTransaction.begin(); - - if (!group->storageID()) { - // Store the group - if (!store(group)) - return false; - } - - ASSERT(group->newestCache()); - ASSERT(!group->newestCache()->storageID()); - - // Store the newest cache - if (!store(group->newestCache())) - return false; - - // Update the newest cache in the group. - - SQLiteStatement statement(m_database, "UPDATE CacheGroups SET newestCache=? WHERE id=?"); - if (statement.prepare() != SQLResultOk) - return false; - - statement.bindInt64(1, group->newestCache()->storageID()); - statement.bindInt64(2, group->storageID()); - - if (!executeStatement(statement)) - return false; - - storeCacheTransaction.commit(); - return true; -} - -static inline void parseHeader(const UChar* header, size_t headerLength, ResourceResponse& response) -{ - int pos = find(header, headerLength, ':'); - ASSERT(pos != -1); - - String headerName = String(header, pos); - String headerValue = String(header + pos + 1, headerLength - pos - 1); - - response.setHTTPHeaderField(headerName, headerValue); -} - -static inline void parseHeaders(const String& headers, ResourceResponse& response) -{ - int startPos = 0; - int endPos; - while ((endPos = headers.find('\n', startPos)) != -1) { - ASSERT(startPos != endPos); - - parseHeader(headers.characters() + startPos, endPos - startPos, response); - - startPos = endPos + 1; - } - - if (startPos != static_cast<int>(headers.length())) - parseHeader(headers.characters(), headers.length(), response); -} - -PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storageID) -{ - SQLiteStatement cacheStatement(m_database, - "SELECT url, type, mimeType, textEncodingName, headers, CacheResourceData.data FROM CacheEntries INNER JOIN CacheResources ON CacheEntries.resource=CacheResources.id " - "INNER JOIN CacheResourceData ON CacheResourceData.id=CacheResources.data WHERE CacheEntries.cache=?"); - if (cacheStatement.prepare() != SQLResultOk) { - LOG_ERROR("Could not prepare cache statement, error \"%s\"", m_database.lastErrorMsg()); - return 0; - } - - cacheStatement.bindInt64(1, storageID); - - RefPtr<ApplicationCache> cache = ApplicationCache::create(); - - int result; - while ((result = cacheStatement.step()) == SQLResultRow) { - KURL url(cacheStatement.getColumnText(0)); - - unsigned type = (unsigned)cacheStatement.getColumnInt64(1); - - Vector<char> blob; - cacheStatement.getColumnBlobAsVector(5, blob); - - RefPtr<SharedBuffer> data = SharedBuffer::adoptVector(blob); - - String mimeType = cacheStatement.getColumnText(2); - String textEncodingName = cacheStatement.getColumnText(3); - - ResourceResponse response(url, mimeType, data->size(), textEncodingName, ""); - - String headers = cacheStatement.getColumnText(4); - parseHeaders(headers, response); - - RefPtr<ApplicationCacheResource> resource = ApplicationCacheResource::create(url, response, type, data.release()); - - if (type & ApplicationCacheResource::Manifest) - cache->setManifestResource(resource.release()); - else - cache->addResource(resource.release()); - } - - if (result != SQLResultDone) - LOG_ERROR("Could not load cache resources, error \"%s\"", m_database.lastErrorMsg()); - - // Load the online whitelist - SQLiteStatement whitelistStatement(m_database, "SELECT url FROM CacheWhitelistURLs WHERE cache=?"); - if (whitelistStatement.prepare() != SQLResultOk) - return 0; - whitelistStatement.bindInt64(1, storageID); - - HashSet<String> whitelist; - while ((result = whitelistStatement.step()) == SQLResultRow) - whitelist.add(whitelistStatement.getColumnText(0)); - - if (result != SQLResultDone) - LOG_ERROR("Could not load cache online whitelist, error \"%s\"", m_database.lastErrorMsg()); - - cache->setOnlineWhitelist(whitelist); - - cache->setStorageID(storageID); - - return cache.release(); -} - -void ApplicationCacheStorage::remove(ApplicationCache* cache) -{ - if (!cache->storageID()) - return; - - openDatabase(false); - if (!m_database.isOpen()) - return; - - SQLiteStatement statement(m_database, "DELETE FROM Caches WHERE id=?"); - if (statement.prepare() != SQLResultOk) - return; - - statement.bindInt64(1, cache->storageID()); - executeStatement(statement); -} - -void ApplicationCacheStorage::empty() -{ - openDatabase(false); - - if (!m_database.isOpen()) - return; - - // Clear cache groups, caches and cache resources. - executeSQLCommand("DELETE FROM CacheGroups"); - executeSQLCommand("DELETE FROM Caches"); - executeSQLCommand("DELETE FROM CacheResources"); - - // Clear the storage IDs for the caches in memory. - // The caches will still work, but cached resources will not be saved to disk - // until a cache update process has been initiated. - CacheGroupMap::const_iterator end = m_cachesInMemory.end(); - for (CacheGroupMap::const_iterator it = m_cachesInMemory.begin(); it != end; ++it) - it->second->clearStorageID(); -} - -bool ApplicationCacheStorage::storeCopyOfCache(const String& cacheDirectory, ApplicationCache* cache) -{ - // Create a new cache. - RefPtr<ApplicationCache> cacheCopy = ApplicationCache::create(); - - // Set the online whitelist - cacheCopy->setOnlineWhitelist(cache->onlineWhitelist()); - - // Traverse the cache and add copies of all resources. - ApplicationCache::ResourceMap::const_iterator end = cache->end(); - for (ApplicationCache::ResourceMap::const_iterator it = cache->begin(); it != end; ++it) { - ApplicationCacheResource* resource = it->second.get(); - - RefPtr<ApplicationCacheResource> resourceCopy = ApplicationCacheResource::create(resource->url(), resource->response(), resource->type(), resource->data()); - - cacheCopy->addResource(resourceCopy.release()); - } - - // Now create a new cache group. - OwnPtr<ApplicationCacheGroup> groupCopy(new ApplicationCacheGroup(cache->group()->manifestURL(), true)); - - groupCopy->setNewestCache(cacheCopy); - - ApplicationCacheStorage copyStorage; - copyStorage.setCacheDirectory(cacheDirectory); - - // Empty the cache in case something was there before. - copyStorage.empty(); - - return copyStorage.storeNewestCache(groupCopy.get()); -} - -ApplicationCacheStorage& cacheStorage() -{ - static ApplicationCacheStorage storage; - - return storage; -} - -} // namespace WebCore - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) diff --git a/WebCore/loader/appcache/ApplicationCacheStorage.h b/WebCore/loader/appcache/ApplicationCacheStorage.h deleted file mode 100644 index 6bd9ba1..0000000 --- a/WebCore/loader/appcache/ApplicationCacheStorage.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ApplicationCacheStorage_h -#define ApplicationCacheStorage_h - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include "PlatformString.h" -#include "SQLiteDatabase.h" -#include "StringHash.h" - -#include <wtf/HashCountedSet.h> - -namespace WebCore { - -class ApplicationCache; -class ApplicationCacheGroup; -class ApplicationCacheResource; -class KURL; - -class ApplicationCacheStorage { -public: - void setCacheDirectory(const String&); - - ApplicationCacheGroup* cacheGroupForURL(const KURL&); - - ApplicationCacheGroup* findOrCreateCacheGroup(const KURL& manifestURL); - void cacheGroupDestroyed(ApplicationCacheGroup*); - - bool storeNewestCache(ApplicationCacheGroup*); - void store(ApplicationCacheResource*, ApplicationCache*); - - void remove(ApplicationCache*); - - void empty(); - - static bool storeCopyOfCache(const String& cacheDirectory, ApplicationCache*); -private: - PassRefPtr<ApplicationCache> loadCache(unsigned storageID); - ApplicationCacheGroup* loadCacheGroup(const KURL& manifestURL); - - bool store(ApplicationCacheGroup*); - bool store(ApplicationCache*); - bool store(ApplicationCacheResource*, unsigned cacheStorageID); - - void loadManifestHostHashes(); - - void verifySchemaVersion(); - - void openDatabase(bool createIfDoesNotExist); - - bool executeStatement(SQLiteStatement&); - bool executeSQLCommand(const String&); - - String m_cacheDirectory; - - SQLiteDatabase m_database; - - // In order to quickly determinate if a given resource exists in an application cache, - // we keep a hash set of the hosts of the manifest URLs of all cache groups. - HashCountedSet<unsigned, AlreadyHashed> m_cacheHostSet; - - typedef HashMap<String, ApplicationCacheGroup*> CacheGroupMap; - CacheGroupMap m_cachesInMemory; -}; - -ApplicationCacheStorage& cacheStorage(); - -} // namespace WebCore - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) - -#endif // ApplicationCacheStorage_h diff --git a/WebCore/loader/appcache/DOMApplicationCache.cpp b/WebCore/loader/appcache/DOMApplicationCache.cpp deleted file mode 100644 index f872a50..0000000 --- a/WebCore/loader/appcache/DOMApplicationCache.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "DOMApplicationCache.h" - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include "ApplicationCache.h" -#include "ApplicationCacheGroup.h" -#include "DocumentLoader.h" -#include "Event.h" -#include "EventException.h" -#include "EventListener.h" -#include "EventNames.h" -#include "Frame.h" -#include "FrameLoader.h" - -namespace WebCore { - -DOMApplicationCache::DOMApplicationCache(Frame* frame) - : m_frame(frame) -{ -} - -void DOMApplicationCache::disconnectFrame() -{ - m_frame = 0; -} - -ApplicationCache* DOMApplicationCache::associatedCache() const -{ - if (!m_frame) - return 0; - - return m_frame->loader()->documentLoader()->topLevelApplicationCache(); -} - -unsigned short DOMApplicationCache::status() const -{ - ApplicationCache* cache = associatedCache(); - if (!cache) - return UNCACHED; - - switch (cache->group()->status()) { - case ApplicationCacheGroup::Checking: - return CHECKING; - case ApplicationCacheGroup::Downloading: - return DOWNLOADING; - case ApplicationCacheGroup::Idle: { - if (cache != cache->group()->newestCache()) - return UPDATEREADY; - - return IDLE; - } - default: - ASSERT_NOT_REACHED(); - } - - return 0; -} - -void DOMApplicationCache::update(ExceptionCode& ec) -{ - ApplicationCache* cache = associatedCache(); - if (!cache) { - ec = INVALID_STATE_ERR; - return; - } - - cache->group()->update(m_frame); -} - -bool DOMApplicationCache::swapCache() -{ - if (!m_frame) - return false; - - ApplicationCache* cache = m_frame->loader()->documentLoader()->applicationCache(); - if (!cache) - return false; - - // Check if we already have the newest cache - ApplicationCache* newestCache = cache->group()->newestCache(); - if (cache == newestCache) - return false; - - ASSERT(cache->group() == newestCache->group()); - m_frame->loader()->documentLoader()->setApplicationCache(newestCache); - - return true; -} - -void DOMApplicationCache::swapCache(ExceptionCode& ec) -{ - if (!swapCache()) - ec = INVALID_STATE_ERR; -} - -unsigned DOMApplicationCache::length() const -{ - ApplicationCache* cache = associatedCache(); - if (!cache) - return 0; - - return cache->numDynamicEntries(); -} - -String DOMApplicationCache::item(unsigned item, ExceptionCode& ec) -{ - ApplicationCache* cache = associatedCache(); - if (!cache) { - ec = INVALID_STATE_ERR; - return String(); - } - - if (item >= length()) { - ec = INDEX_SIZE_ERR; - return String(); - } - - return cache->dynamicEntry(item); -} - -void DOMApplicationCache::add(const KURL& url, ExceptionCode& ec) -{ - ApplicationCache* cache = associatedCache(); - if (!cache) { - ec = INVALID_STATE_ERR; - return; - } - - if (!url.isValid()) { - ec = SYNTAX_ERR; - return; - } - - if (!cache->addDynamicEntry(url)) { - // This should use the (currently not specified) security exceptions in HTML5 4.3.4 - ec = SECURITY_ERR; - } -} - -void DOMApplicationCache::remove(const KURL& url, ExceptionCode& ec) -{ - ApplicationCache* cache = associatedCache(); - if (!cache) { - ec = INVALID_STATE_ERR; - return; - } - - cache->removeDynamicEntry(url); -} - -ScriptExecutionContext* DOMApplicationCache::scriptExecutionContext() const -{ - return m_frame->document(); -} - -void DOMApplicationCache::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) { - ListenerVector listeners; - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } else { - ListenerVector& listeners = iter->second; - for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (*listenerIter == eventListener) - return; - } - - listeners.append(eventListener); - m_eventListeners.add(eventType, listeners); - } -} - -void DOMApplicationCache::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool useCapture) -{ - EventListenersMap::iterator iter = m_eventListeners.find(eventType); - if (iter == m_eventListeners.end()) - return; - - ListenerVector& listeners = iter->second; - for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) { - if (*listenerIter == eventListener) { - listeners.remove(listenerIter - listeners.begin()); - return; - } - } -} - -bool DOMApplicationCache::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) -{ - if (event->type().isEmpty()) { - ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; - return true; - } - - ListenerVector listenersCopy = m_eventListeners.get(event->type()); - for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) { - event->setTarget(this); - event->setCurrentTarget(this); - listenerIter->get()->handleEvent(event.get(), false); - } - - return !event->defaultPrevented(); -} - -void DOMApplicationCache::callListener(const AtomicString& eventType, EventListener* listener) -{ - ASSERT(m_frame); - - RefPtr<Event> event = Event::create(eventType, false, false); - if (listener) { - event->setTarget(this); - event->setCurrentTarget(this); - listener->handleEvent(event.get(), false); - } - - ExceptionCode ec = 0; - dispatchEvent(event.release(), ec); - ASSERT(!ec); -} - -void DOMApplicationCache::callCheckingListener() -{ - callListener(eventNames().checkingEvent, m_onCheckingListener.get()); -} - -void DOMApplicationCache::callErrorListener() -{ - callListener(eventNames().errorEvent, m_onErrorListener.get()); -} - -void DOMApplicationCache::callNoUpdateListener() -{ - callListener(eventNames().noupdateEvent, m_onNoUpdateListener.get()); -} - -void DOMApplicationCache::callDownloadingListener() -{ - callListener(eventNames().downloadingEvent, m_onDownloadingListener.get()); -} - -void DOMApplicationCache::callProgressListener() -{ - callListener(eventNames().progressEvent, m_onProgressListener.get()); -} - -void DOMApplicationCache::callUpdateReadyListener() -{ - callListener(eventNames().updatereadyEvent, m_onUpdateReadyListener.get()); -} - -void DOMApplicationCache::callCachedListener() -{ - callListener(eventNames().cachedEvent, m_onCachedListener.get()); -} - -} // namespace WebCore - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) diff --git a/WebCore/loader/appcache/DOMApplicationCache.h b/WebCore/loader/appcache/DOMApplicationCache.h deleted file mode 100644 index 30c0b7e..0000000 --- a/WebCore/loader/appcache/DOMApplicationCache.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef DOMApplicationCache_h -#define DOMApplicationCache_h - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include "AtomicStringHash.h" -#include "EventTarget.h" -#include "EventListener.h" -#include <wtf/HashMap.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> - -namespace WebCore { - -class ApplicationCache; -class AtomicStringImpl; -class Frame; -class KURL; -class String; - -class DOMApplicationCache : public RefCounted<DOMApplicationCache>, public EventTarget { -public: - static PassRefPtr<DOMApplicationCache> create(Frame* frame) { return adoptRef(new DOMApplicationCache(frame)); } - void disconnectFrame(); - - enum Status { - UNCACHED = 0, - IDLE = 1, - CHECKING = 2, - DOWNLOADING = 3, - UPDATEREADY = 4, - }; - - unsigned short status() const; - - void update(ExceptionCode&); - void swapCache(ExceptionCode&); - - unsigned length() const; - String item(unsigned item, ExceptionCode&); - void add(const KURL&, ExceptionCode&); - void remove(const KURL&, ExceptionCode&); - - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); - - typedef Vector<RefPtr<EventListener> > ListenerVector; - typedef HashMap<AtomicString, ListenerVector> EventListenersMap; - EventListenersMap& eventListeners() { return m_eventListeners; } - - using RefCounted<DOMApplicationCache>::ref; - using RefCounted<DOMApplicationCache>::deref; - - void setOnchecking(PassRefPtr<EventListener> eventListener) { m_onCheckingListener = eventListener; } - EventListener* onchecking() const { return m_onCheckingListener.get(); } - - void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; } - EventListener* onerror() const { return m_onErrorListener.get(); } - - void setOnnoupdate(PassRefPtr<EventListener> eventListener) { m_onNoUpdateListener = eventListener; } - EventListener* onnoupdate() const { return m_onNoUpdateListener.get(); } - - void setOndownloading(PassRefPtr<EventListener> eventListener) { m_onDownloadingListener = eventListener; } - EventListener* ondownloading() const { return m_onDownloadingListener.get(); } - - void setOnprogress(PassRefPtr<EventListener> eventListener) { m_onProgressListener = eventListener; } - EventListener* onprogress() const { return m_onProgressListener.get(); } - - void setOnupdateready(PassRefPtr<EventListener> eventListener) { m_onUpdateReadyListener = eventListener; } - EventListener* onupdateready() const { return m_onUpdateReadyListener.get(); } - - void setOncached(PassRefPtr<EventListener> eventListener) { m_onCachedListener = eventListener; } - EventListener* oncached() const { return m_onCachedListener.get(); } - - virtual ScriptExecutionContext* scriptExecutionContext() const; - DOMApplicationCache* toDOMApplicationCache() { return this; } - - void callCheckingListener(); - void callErrorListener(); - void callNoUpdateListener(); - void callDownloadingListener(); - void callProgressListener(); - void callUpdateReadyListener(); - void callCachedListener(); - -private: - DOMApplicationCache(Frame*); - void callListener(const AtomicString& eventType, EventListener*); - - virtual void refEventTarget() { ref(); } - virtual void derefEventTarget() { deref(); } - - ApplicationCache* associatedCache() const; - bool swapCache(); - - RefPtr<EventListener> m_onCheckingListener; - RefPtr<EventListener> m_onErrorListener; - RefPtr<EventListener> m_onNoUpdateListener; - RefPtr<EventListener> m_onDownloadingListener; - RefPtr<EventListener> m_onProgressListener; - RefPtr<EventListener> m_onUpdateReadyListener; - RefPtr<EventListener> m_onCachedListener; - - EventListenersMap m_eventListeners; - - Frame* m_frame; -}; - -} // namespace WebCore - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) - -#endif // DOMApplicationCache_h diff --git a/WebCore/loader/appcache/DOMApplicationCache.idl b/WebCore/loader/appcache/DOMApplicationCache.idl deleted file mode 100644 index 94326f3..0000000 --- a/WebCore/loader/appcache/DOMApplicationCache.idl +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -module offline { - - interface [ - Conditional=OFFLINE_WEB_APPLICATIONS, - CustomMarkFunction - ] DOMApplicationCache { - // update status - const unsigned short UNCACHED = 0; - const unsigned short IDLE = 1; - const unsigned short CHECKING = 2; - const unsigned short DOWNLOADING = 3; - const unsigned short UPDATEREADY = 4; - readonly attribute unsigned short status; - - void update() - raises(DOMException); - void swapCache() - raises(DOMException); - - // dynamic entries - readonly attribute unsigned long length; - DOMString item(in [IsIndex] unsigned long index) - raises(DOMException); - [Custom] void add(in DOMString uri) - raises(DOMException); - [Custom] void remove(in DOMString uri) - raises(DOMException); - - // events - attribute EventListener onchecking; - attribute EventListener onerror; - attribute EventListener onnoupdate; - attribute EventListener ondownloading; - attribute EventListener onprogress; - attribute EventListener onupdateready; - attribute EventListener oncached; - - // EventTarget interface - [Custom] void addEventListener(in DOMString type, - in EventListener listener, - in boolean useCapture); - [Custom] void removeEventListener(in DOMString type, - in EventListener listener, - in boolean useCapture); - boolean dispatchEvent(in Event evt) - raises(EventException); - }; - -} diff --git a/WebCore/loader/appcache/ManifestParser.cpp b/WebCore/loader/appcache/ManifestParser.cpp deleted file mode 100644 index 778d22d..0000000 --- a/WebCore/loader/appcache/ManifestParser.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ManifestParser.h" - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include "CharacterNames.h" -#include "KURL.h" -#include "TextEncoding.h" - -namespace WebCore { - -enum Mode { Explicit, Fallback, OnlineWhitelist }; - -bool parseManifest(const KURL& manifestURL, const char* data, int length, Manifest& manifest) -{ - ASSERT(manifest.explicitURLs.isEmpty()); - ASSERT(manifest.onlineWhitelistedURLs.isEmpty()); - ASSERT(manifest.fallbackURLs.isEmpty()); - - Mode mode = Explicit; - String s = UTF8Encoding().decode(data, length); - - if (s.isEmpty()) - return false; - - // Replace nulls with U+FFFD REPLACEMENT CHARACTER - s.replace(0, replacementCharacter); - - // Look for the magic signature - if (!s.startsWith("CACHE MANIFEST")) { - // The magic signature was not found. - return false; - } - - const UChar* end = s.characters() + s.length(); - const UChar* p = s.characters() + 14; // "CACHE MANIFEST" is 14 characters. - - while (p < end) { - // Skip whitespace - if (*p == ' ' || *p == '\t') { - p++; - } else - break; - } - - if (p < end && *p != '\n' && *p != '\r') { - // The magic signature was invalid - return false; - } - - while (1) { - // Skip whitespace - while (p < end && (*p == '\n' || *p == '\r' || *p == ' ' || *p == '\t')) - p++; - - if (p == end) - break; - - const UChar* lineStart = p; - - // Find the end of the line - while (p < end && *p != '\r' && *p != '\n') - p++; - - // Check if we have a comment - if (*lineStart == '#') - continue; - - // Get rid of trailing whitespace - const UChar* tmp = p - 1; - while (tmp > lineStart && (*tmp == ' ' || *tmp == '\t')) - tmp--; - - String line(lineStart, tmp - lineStart + 1); - - if (line == "CACHE:") - mode = Explicit; - else if (line == "FALLBACK:") - mode = Fallback; - else if (line == "NETWORK:") - mode = OnlineWhitelist; - else if (mode == Explicit || mode == OnlineWhitelist) { - KURL url(manifestURL, line); - - if (!url.isValid()) - continue; - - if (url.hasRef()) - url.setRef(String()); - - if (!equalIgnoringCase(url.protocol(), manifestURL.protocol())) - continue; - - if (mode == Explicit) - manifest.explicitURLs.add(url.string()); - else - manifest.onlineWhitelistedURLs.add(url.string()); - - } else if (mode == Fallback) { - const UChar *p = line.characters(); - const UChar *lineEnd = p + line.length(); - - // Look for whitespace separating the two URLs - while (p < lineEnd && *p != '\t' && *p != ' ') - p++; - - if (p == lineEnd) { - // There was no whitespace separating the URLs. - continue; - } - - KURL namespaceURL(manifestURL, String(line.characters(), p - line.characters())); - if (!namespaceURL.isValid()) - continue; - - // Check that the namespace URL has the same scheme/host/port as the manifest URL. - if (!protocolHostAndPortAreEqual(manifestURL, namespaceURL)) - continue; - - while (p < lineEnd && (*p == '\t' || *p == ' ')) - p++; - - KURL fallbackURL(String(p, line.length() - (p - line.characters()))); - - if (!fallbackURL.isValid()) - continue; - - if (!equalIgnoringCase(fallbackURL.protocol(), manifestURL.protocol())) - continue; - - manifest.fallbackURLs.add(namespaceURL, fallbackURL); - } else - ASSERT_NOT_REACHED(); - } - - return true; -} - -} - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) diff --git a/WebCore/loader/appcache/ManifestParser.h b/WebCore/loader/appcache/ManifestParser.h deleted file mode 100644 index f4fe31a..0000000 --- a/WebCore/loader/appcache/ManifestParser.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ManifestParser_h -#define ManifestParser_h - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - -#include <wtf/HashMap.h> -#include <wtf/HashSet.h> -#include "StringHash.h" -#include "PlatformString.h" - -namespace WebCore { - -class KURL; - -struct Manifest { - HashSet<String> onlineWhitelistedURLs; - HashSet<String> explicitURLs; - HashMap<String, String> fallbackURLs; -}; - -bool parseManifest(const KURL& manifestURL, const char* data, int length, Manifest&); - -} - -#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) - -#endif // ManifestParser_h |