diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/loader/appcache')
14 files changed, 766 insertions, 323 deletions
diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCache.cpp b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCache.cpp index d221bdb19..c0cd3ea6d 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCache.cpp +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCache.cpp @@ -111,7 +111,7 @@ unsigned ApplicationCache::removeResource(const String& url) ApplicationCacheResource* ApplicationCache::resourceForURL(const String& url) { - ASSERT(!KURL(url).hasRef()); + ASSERT(!KURL(ParsedURLString, url).hasFragmentIdentifier()); return m_resources.get(url).get(); } @@ -133,8 +133,8 @@ ApplicationCacheResource* ApplicationCache::resourceForRequest(const ResourceReq return false; KURL url(request.url()); - if (url.hasRef()) - url.removeRef(); + if (url.hasFragmentIdentifier()) + url.removeFragmentIdentifier(); return resourceForURL(url); } @@ -147,6 +147,9 @@ void ApplicationCache::setOnlineWhitelist(const Vector<KURL>& onlineWhitelist) bool ApplicationCache::isURLInOnlineWhitelist(const KURL& url) { + if (m_allowAllNetworkRequests) + return true; + size_t whitelistSize = m_onlineWhitelist.size(); for (size_t i = 0; i < whitelistSize; ++i) { if (protocolHostAndPortAreEqual(url, m_onlineWhitelist[i]) && url.string().startsWith(m_onlineWhitelist[i].string())) diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCache.h b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCache.h index b1753be14..d1444c0b7 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCache.h +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCache.h @@ -65,6 +65,8 @@ public: ApplicationCacheResource* resourceForRequest(const ResourceRequest&); ApplicationCacheResource* resourceForURL(const String& url); + void setAllowsAllNetworkRequests(bool value) { m_allowAllNetworkRequests = value; } + bool allowsAllNetworkRequests() const { return m_allowAllNetworkRequests; } void setOnlineWhitelist(const Vector<KURL>& onlineWhitelist); const Vector<KURL>& onlineWhitelist() const { return m_onlineWhitelist; } bool isURLInOnlineWhitelist(const KURL&); // There is an entry in online whitelist that has the same origin as the resource's URL and that is a prefix match for the resource's URL. @@ -96,6 +98,7 @@ private: ResourceMap m_resources; ApplicationCacheResource* m_manifest; + bool m_allowAllNetworkRequests; Vector<KURL> m_onlineWhitelist; FallbackURLVector m_fallbackURLs; diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.cpp index dc7335353..c66f36f0e 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.cpp +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.cpp @@ -29,6 +29,7 @@ #if ENABLE(OFFLINE_WEB_APPLICATIONS) #include "ApplicationCache.h" +#include "ApplicationCacheHost.h" #include "ApplicationCacheResource.h" #include "ApplicationCacheStorage.h" #include "ChromeClient.h" @@ -86,8 +87,8 @@ ApplicationCache* ApplicationCacheGroup::cacheForMainRequest(const ResourceReque return 0; KURL url(request.url()); - if (url.hasRef()) - url.removeRef(); + if (url.hasFragmentIdentifier()) + url.removeFragmentIdentifier(); if (ApplicationCacheGroup* group = cacheStorage().cacheGroupForURL(url)) { ASSERT(group->newestCache()); @@ -105,8 +106,8 @@ ApplicationCache* ApplicationCacheGroup::fallbackCacheForMainRequest(const Resou return 0; KURL url(request.url()); - if (url.hasRef()) - url.removeRef(); + if (url.hasFragmentIdentifier()) + url.removeFragmentIdentifier(); if (ApplicationCacheGroup* group = cacheStorage().fallbackCacheGroupForURL(url)) { ASSERT(group->newestCache()); @@ -126,7 +127,7 @@ void ApplicationCacheGroup::selectCache(Frame* frame, const KURL& passedManifest return; DocumentLoader* documentLoader = frame->loader()->documentLoader(); - ASSERT(!documentLoader->applicationCache()); + ASSERT(!documentLoader->applicationCacheHost()->applicationCache()); if (passedManifestURL.isNull()) { selectCacheWithoutManifestURL(frame); @@ -134,10 +135,10 @@ void ApplicationCacheGroup::selectCache(Frame* frame, const KURL& passedManifest } KURL manifestURL(passedManifestURL); - if (manifestURL.hasRef()) - manifestURL.removeRef(); + if (manifestURL.hasFragmentIdentifier()) + manifestURL.removeFragmentIdentifier(); - ApplicationCache* mainResourceCache = documentLoader->mainResourceApplicationCache(); + ApplicationCache* mainResourceCache = documentLoader->applicationCacheHost()->mainResourceApplicationCache(); if (mainResourceCache) { if (manifestURL == mainResourceCache->group()->m_manifestURL) { @@ -146,8 +147,8 @@ void ApplicationCacheGroup::selectCache(Frame* frame, const KURL& passedManifest } else { // The main resource was loaded from cache, so the cache must have an entry for it. Mark it as foreign. KURL documentURL(documentLoader->url()); - if (documentURL.hasRef()) - documentURL.removeRef(); + if (documentURL.hasFragmentIdentifier()) + documentURL.removeFragmentIdentifier(); ApplicationCacheResource* resource = mainResourceCache->resourceForURL(documentURL); bool inStorage = resource->storageID(); resource->addType(ApplicationCacheResource::Foreign); @@ -157,7 +158,7 @@ void ApplicationCacheGroup::selectCache(Frame* frame, const KURL& passedManifest // Restart the current navigation from the top of the navigation algorithm, undoing any changes that were made // as part of the initial load. // The navigation will not result in the same resource being loaded, because "foreign" entries are never picked during navigation. - frame->loader()->scheduleLocationChange(documentLoader->url(), frame->loader()->referrer(), true); + frame->redirectScheduler()->scheduleLocationChange(documentLoader->url(), frame->loader()->referrer(), true); } return; @@ -175,14 +176,14 @@ void ApplicationCacheGroup::selectCache(Frame* frame, const KURL& passedManifest // Don't change anything on disk if private browsing is enabled. if (!frame->settings() || frame->settings()->privateBrowsingEnabled()) { - postListenerTask(&DOMApplicationCache::callCheckingListener, documentLoader); - postListenerTask(&DOMApplicationCache::callErrorListener, documentLoader); + postListenerTask(ApplicationCacheHost::CHECKING_EVENT, documentLoader); + postListenerTask(ApplicationCacheHost::ERROR_EVENT, documentLoader); return; } ApplicationCacheGroup* group = cacheStorage().findOrCreateCacheGroup(manifestURL); - documentLoader->setCandidateApplicationCacheGroup(group); + documentLoader->applicationCacheHost()->setCandidateApplicationCacheGroup(group); group->m_pendingMasterResourceLoaders.add(documentLoader); group->m_downloadingPendingMasterResourceLoadersCount++; @@ -196,9 +197,9 @@ void ApplicationCacheGroup::selectCacheWithoutManifestURL(Frame* frame) return; DocumentLoader* documentLoader = frame->loader()->documentLoader(); - ASSERT(!documentLoader->applicationCache()); + ASSERT(!documentLoader->applicationCacheHost()->applicationCache()); - ApplicationCache* mainResourceCache = documentLoader->mainResourceApplicationCache(); + ApplicationCache* mainResourceCache = documentLoader->applicationCacheHost()->mainResourceApplicationCache(); if (mainResourceCache) { mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache); @@ -211,8 +212,8 @@ void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader) ASSERT(m_pendingMasterResourceLoaders.contains(loader)); ASSERT(m_completionType == None || m_pendingEntries.isEmpty()); KURL url = loader->url(); - if (url.hasRef()) - url.removeRef(); + if (url.hasFragmentIdentifier()) + url.removeFragmentIdentifier(); switch (m_completionType) { case None: @@ -235,9 +236,9 @@ void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader) // Cache update has been a failure, so there is no reason to keep the document associated with the incomplete cache // (its main resource was not cached yet, so it is likely that the application changed significantly server-side). ASSERT(!m_cacheBeingUpdated); // Already cleared out by stopLoading(). - loader->setApplicationCache(0); // Will unset candidate, too. + loader->applicationCacheHost()->setApplicationCache(0); // Will unset candidate, too. m_associatedDocumentLoaders.remove(loader); - postListenerTask(&DOMApplicationCache::callErrorListener, loader); + postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader); break; case Completed: ASSERT(m_associatedDocumentLoaders.contains(loader)); @@ -271,28 +272,28 @@ void ApplicationCacheGroup::failedLoadingMainResource(DocumentLoader* loader) // The manifest didn't change, and we have a relevant cache - but the main resource download failed mid-way, so it cannot be stored to the cache, // and the loader does not get associated to it. If there are other main resources being downloaded for this cache group, they may still succeed. - postListenerTask(&DOMApplicationCache::callErrorListener, loader); + postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader); break; case Failure: // Cache update failed, too. ASSERT(!m_cacheBeingUpdated); // Already cleared out by stopLoading(). - ASSERT(!loader->applicationCache() || loader->applicationCache() == m_cacheBeingUpdated); + ASSERT(!loader->applicationCacheHost()->applicationCache() || loader->applicationCacheHost()->applicationCache() == m_cacheBeingUpdated); - loader->setApplicationCache(0); // Will unset candidate, too. + loader->applicationCacheHost()->setApplicationCache(0); // Will unset candidate, too. m_associatedDocumentLoaders.remove(loader); - postListenerTask(&DOMApplicationCache::callErrorListener, loader); + postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader); break; case Completed: // The cache manifest didn't list this main resource, and all cache entries were already updated successfully - but the main resource failed to load, // so it cannot be stored to the cache. If there are other main resources being downloaded for this cache group, they may still succeed. ASSERT(m_associatedDocumentLoaders.contains(loader)); - ASSERT(loader->applicationCache() == m_cacheBeingUpdated); - ASSERT(!loader->candidateApplicationCacheGroup()); + ASSERT(loader->applicationCacheHost()->applicationCache() == m_cacheBeingUpdated); + ASSERT(!loader->applicationCacheHost()->candidateApplicationCacheGroup()); m_associatedDocumentLoaders.remove(loader); - loader->setApplicationCache(0); + loader->applicationCacheHost()->setApplicationCache(0); - postListenerTask(&DOMApplicationCache::callErrorListener, loader); + postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader); break; } @@ -332,7 +333,7 @@ void ApplicationCacheGroup::disassociateDocumentLoader(DocumentLoader* loader) m_pendingMasterResourceLoaders.remove(loader); - loader->setApplicationCache(0); // Will set candidate to 0, too. + loader->applicationCacheHost()->setApplicationCache(0); // Will set candidate to 0, too. if (!m_associatedDocumentLoaders.isEmpty() || !m_pendingMasterResourceLoaders.isEmpty()) return; @@ -388,9 +389,9 @@ void ApplicationCacheGroup::update(Frame* frame, ApplicationCacheUpdateOption up { if (m_updateStatus == Checking || m_updateStatus == Downloading) { if (updateOption == ApplicationCacheUpdateWithBrowsingContext) { - postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader()); + postListenerTask(ApplicationCacheHost::CHECKING_EVENT, frame->loader()->documentLoader()); if (m_updateStatus == Downloading) - postListenerTask(&DOMApplicationCache::callDownloadingListener, frame->loader()->documentLoader()); + postListenerTask(ApplicationCacheHost::DOWNLOADING_EVENT, frame->loader()->documentLoader()); } return; } @@ -400,8 +401,8 @@ void ApplicationCacheGroup::update(Frame* frame, ApplicationCacheUpdateOption up ASSERT(m_pendingMasterResourceLoaders.isEmpty()); ASSERT(m_pendingEntries.isEmpty()); ASSERT(!m_cacheBeingUpdated); - postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader()); - postListenerTask(&DOMApplicationCache::callNoUpdateListener, frame->loader()->documentLoader()); + postListenerTask(ApplicationCacheHost::CHECKING_EVENT, frame->loader()->documentLoader()); + postListenerTask(ApplicationCacheHost::NOUPDATE_EVENT, frame->loader()->documentLoader()); return; } @@ -410,10 +411,10 @@ void ApplicationCacheGroup::update(Frame* frame, ApplicationCacheUpdateOption up m_updateStatus = Checking; - postListenerTask(&DOMApplicationCache::callCheckingListener, m_associatedDocumentLoaders); + postListenerTask(ApplicationCacheHost::CHECKING_EVENT, m_associatedDocumentLoaders); if (!m_newestCache) { ASSERT(updateOption == ApplicationCacheUpdateWithBrowsingContext); - postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader()); + postListenerTask(ApplicationCacheHost::CHECKING_EVENT, frame->loader()->documentLoader()); } ASSERT(!m_manifestHandle); @@ -454,8 +455,8 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res ASSERT(handle == m_currentHandle); KURL url(handle->request().url()); - if (url.hasRef()) - url.removeRef(); + if (url.hasFragmentIdentifier()) + url.removeFragmentIdentifier(); ASSERT(!m_currentResource); ASSERT(m_pendingEntries.contains(url)); @@ -553,8 +554,8 @@ void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError& unsigned type = m_currentResource ? m_currentResource->type() : m_pendingEntries.get(handle->request().url()); KURL url(handle->request().url()); - if (url.hasRef()) - url.removeRef(); + if (url.hasFragmentIdentifier()) + url.removeFragmentIdentifier(); ASSERT(!m_currentResource || !m_pendingEntries.contains(url)); m_currentResource = 0; @@ -648,7 +649,7 @@ void ApplicationCacheGroup::didFinishLoadingManifest() // We have the manifest, now download the resources. m_updateStatus = Downloading; - postListenerTask(&DOMApplicationCache::callDownloadingListener, m_associatedDocumentLoaders); + postListenerTask(ApplicationCacheHost::DOWNLOADING_EVENT, m_associatedDocumentLoaders); ASSERT(m_pendingEntries.isEmpty()); @@ -671,6 +672,7 @@ void ApplicationCacheGroup::didFinishLoadingManifest() m_cacheBeingUpdated->setOnlineWhitelist(manifest.onlineWhitelistedURLs); m_cacheBeingUpdated->setFallbackURLs(manifest.fallbackURLs); + m_cacheBeingUpdated->setAllowsAllNetworkRequests(manifest.allowAllNetworkRequests); startLoadingEntry(); } @@ -698,8 +700,8 @@ void ApplicationCacheGroup::manifestNotFound() { makeObsolete(); - postListenerTask(&DOMApplicationCache::callObsoleteListener, m_associatedDocumentLoaders); - postListenerTask(&DOMApplicationCache::callErrorListener, m_pendingMasterResourceLoaders); + postListenerTask(ApplicationCacheHost::OBSOLETE_EVENT, m_associatedDocumentLoaders); + postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_pendingMasterResourceLoaders); stopLoading(); @@ -709,9 +711,9 @@ void ApplicationCacheGroup::manifestNotFound() while (!m_pendingMasterResourceLoaders.isEmpty()) { HashSet<DocumentLoader*>::iterator it = m_pendingMasterResourceLoaders.begin(); - ASSERT((*it)->candidateApplicationCacheGroup() == this); - ASSERT(!(*it)->applicationCache()); - (*it)->setCandidateApplicationCacheGroup(0); + ASSERT((*it)->applicationCacheHost()->candidateApplicationCacheGroup() == this); + ASSERT(!(*it)->applicationCacheHost()->applicationCache()); + (*it)->applicationCacheHost()->setCandidateApplicationCacheGroup(0); m_pendingMasterResourceLoaders.remove(it); } @@ -747,11 +749,11 @@ void ApplicationCacheGroup::checkIfLoadIsComplete() if (!m_storageID) cacheStorage().storeNewestCache(this); - postListenerTask(&DOMApplicationCache::callNoUpdateListener, m_associatedDocumentLoaders); + postListenerTask(ApplicationCacheHost::NOUPDATE_EVENT, m_associatedDocumentLoaders); break; case Failure: ASSERT(!m_cacheBeingUpdated); - postListenerTask(&DOMApplicationCache::callErrorListener, m_associatedDocumentLoaders); + postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders); if (m_caches.isEmpty()) { ASSERT(m_associatedDocumentLoaders.isEmpty()); delete this; @@ -772,7 +774,7 @@ void ApplicationCacheGroup::checkIfLoadIsComplete() ASSERT(cacheStorage().isMaximumSizeReached() && m_calledReachedMaxAppCacheSize); } - RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? 0 : m_newestCache; + RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? RefPtr<ApplicationCache>(0) : m_newestCache; setNewestCache(m_cacheBeingUpdated.release()); if (cacheStorage().storeNewestCache(this)) { @@ -780,7 +782,7 @@ void ApplicationCacheGroup::checkIfLoadIsComplete() if (oldNewestCache) cacheStorage().remove(oldNewestCache.get()); // Fire the success events. - postListenerTask(isUpgradeAttempt ? &DOMApplicationCache::callUpdateReadyListener : &DOMApplicationCache::callCachedListener, m_associatedDocumentLoaders); + postListenerTask(isUpgradeAttempt ? ApplicationCacheHost::UPDATEREADY_EVENT : ApplicationCacheHost::CACHED_EVENT, m_associatedDocumentLoaders); } else { if (cacheStorage().isMaximumSizeReached() && !m_calledReachedMaxAppCacheSize) { // We ran out of space. All the changes in the cache storage have @@ -800,7 +802,7 @@ void ApplicationCacheGroup::checkIfLoadIsComplete() // Run the "cache failure steps" // Fire the error events to all pending master entries, as well any other cache hosts // currently associated with a cache in this group. - postListenerTask(&DOMApplicationCache::callErrorListener, m_associatedDocumentLoaders); + postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders); // Disassociate the pending master entries from the failed new cache. Note that // all other loaders in the m_associatedDocumentLoaders are still associated with // some other cache in this group. They are not associated with the failed new cache. @@ -846,11 +848,11 @@ void ApplicationCacheGroup::startLoadingEntry() EntryMap::const_iterator it = m_pendingEntries.begin(); - postListenerTask(&DOMApplicationCache::callProgressListener, m_associatedDocumentLoaders); + postListenerTask(ApplicationCacheHost::PROGRESS_EVENT, m_associatedDocumentLoaders); ASSERT(!m_currentHandle); - m_currentHandle = createResourceHandle(KURL(it->first), m_newestCache ? m_newestCache->resourceForURL(it->first) : 0); + m_currentHandle = createResourceHandle(KURL(ParsedURLString, it->first), m_newestCache ? m_newestCache->resourceForURL(it->first) : 0); } void ApplicationCacheGroup::deliverDelayedMainResources() @@ -877,7 +879,7 @@ void ApplicationCacheGroup::deliverDelayedMainResources() void ApplicationCacheGroup::addEntry(const String& url, unsigned type) { ASSERT(m_cacheBeingUpdated); - ASSERT(!KURL(url).hasRef()); + ASSERT(!KURL(ParsedURLString, url).hasFragmentIdentifier()); // Don't add the URL if we already have an master resource in the cache // (i.e., the main resource finished loading before the manifest). @@ -910,7 +912,7 @@ void ApplicationCacheGroup::associateDocumentLoaderWithCache(DocumentLoader* loa ASSERT(!m_isObsolete); - loader->setApplicationCache(cache); + loader->applicationCacheHost()->setApplicationCache(cache); ASSERT(!m_associatedDocumentLoaders.contains(loader)); m_associatedDocumentLoaders.add(loader); @@ -944,39 +946,44 @@ void ApplicationCacheGroup::scheduleReachedMaxAppCacheSizeCallback() } class CallCacheListenerTask : public ScriptExecutionContext::Task { - typedef void (DOMApplicationCache::*ListenerFunction)(); public: - static PassRefPtr<CallCacheListenerTask> create(ListenerFunction listenerFunction) + static PassRefPtr<CallCacheListenerTask> create(PassRefPtr<DocumentLoader> loader, ApplicationCacheHost::EventID eventID) { - return adoptRef(new CallCacheListenerTask(listenerFunction)); + return adoptRef(new CallCacheListenerTask(loader, eventID)); } virtual void performTask(ScriptExecutionContext* context) { - ASSERT(context->isDocument()); - if (DOMWindow* window = static_cast<Document*>(context)->domWindow()) { - if (DOMApplicationCache* domCache = window->optionalApplicationCache()) - (domCache->*m_listenerFunction)(); - } + + ASSERT_UNUSED(context, context->isDocument()); + Frame* frame = m_documentLoader->frame(); + if (!frame) + return; + + ASSERT(frame->loader()->documentLoader() == m_documentLoader.get()); + + m_documentLoader->applicationCacheHost()->notifyDOMApplicationCache(m_eventID); } private: - CallCacheListenerTask(ListenerFunction listenerFunction) - : m_listenerFunction(listenerFunction) + CallCacheListenerTask(PassRefPtr<DocumentLoader> loader, ApplicationCacheHost::EventID eventID) + : m_documentLoader(loader) + , m_eventID(eventID) { } - ListenerFunction m_listenerFunction; + RefPtr<DocumentLoader> m_documentLoader; + ApplicationCacheHost::EventID m_eventID; }; -void ApplicationCacheGroup::postListenerTask(ListenerFunction listenerFunction, const HashSet<DocumentLoader*>& loaderSet) +void ApplicationCacheGroup::postListenerTask(ApplicationCacheHost::EventID eventID, const HashSet<DocumentLoader*>& loaderSet) { HashSet<DocumentLoader*>::const_iterator loaderSetEnd = loaderSet.end(); for (HashSet<DocumentLoader*>::const_iterator iter = loaderSet.begin(); iter != loaderSetEnd; ++iter) - postListenerTask(listenerFunction, *iter); + postListenerTask(eventID, *iter); } -void ApplicationCacheGroup::postListenerTask(ListenerFunction listenerFunction, DocumentLoader* loader) +void ApplicationCacheGroup::postListenerTask(ApplicationCacheHost::EventID eventID, DocumentLoader* loader) { Frame* frame = loader->frame(); if (!frame) @@ -984,7 +991,7 @@ void ApplicationCacheGroup::postListenerTask(ListenerFunction listenerFunction, ASSERT(frame->loader()->documentLoader() == loader); - frame->document()->postTask(CallCacheListenerTask::create(listenerFunction)); + frame->document()->postTask(CallCacheListenerTask::create(loader, eventID)); } void ApplicationCacheGroup::clearStorageID() diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.h b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.h index 375bd178b..8df52ccf2 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.h +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheGroup.h @@ -32,6 +32,7 @@ #include <wtf/HashMap.h> #include <wtf/HashSet.h> +#include "DOMApplicationCache.h" #include "KURL.h" #include "PlatformString.h" #include "ResourceHandle.h" @@ -42,7 +43,6 @@ namespace WebCore { class ApplicationCache; class ApplicationCacheResource; -class DOMApplicationCache; class Document; class DocumentLoader; class Frame; @@ -91,14 +91,16 @@ public: bool isCopy() const { return m_isCopy; } private: - typedef void (DOMApplicationCache::*ListenerFunction)(); - static void postListenerTask(ListenerFunction, const HashSet<DocumentLoader*>&); - static void postListenerTask(ListenerFunction, const Vector<RefPtr<DocumentLoader> >& loaders); - static void postListenerTask(ListenerFunction, DocumentLoader*); + static void postListenerTask(ApplicationCacheHost::EventID, const HashSet<DocumentLoader*>&); + static void postListenerTask(ApplicationCacheHost::EventID, DocumentLoader*); void scheduleReachedMaxAppCacheSizeCallback(); PassRefPtr<ResourceHandle> createResourceHandle(const KURL&, ApplicationCacheResource* newestCachedResource); + // For normal resource loading, WebKit client is asked about each resource individually. Since application cache does not belong to any particular document, + // the existing client callback cannot be used, so assume that any client that enables application cache also wants it to use credential storage. + virtual bool shouldUseCredentialStorage(ResourceHandle*) { return true; } + virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived); virtual void didFinishLoading(ResourceHandle*); diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.cpp b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.cpp new file mode 100644 index 000000000..751efc15e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.cpp @@ -0,0 +1,385 @@ +/* + * Copyright (C) 2008, 2009 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 "ApplicationCacheHost.h" + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + +#include "ApplicationCache.h" +#include "ApplicationCacheGroup.h" +#include "ApplicationCacheResource.h" +#include "DocumentLoader.h" +#include "DOMApplicationCache.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "FrameLoaderClient.h" +#include "MainResourceLoader.h" +#include "ResourceLoader.h" +#include "ResourceRequest.h" +#include "Settings.h" + +namespace WebCore { + +ApplicationCacheHost::ApplicationCacheHost(DocumentLoader* documentLoader) + : m_domApplicationCache(0) + , m_documentLoader(documentLoader) + , m_candidateApplicationCacheGroup(0) +{ + ASSERT(m_documentLoader); +} + +ApplicationCacheHost::~ApplicationCacheHost() +{ + if (m_applicationCache) + m_applicationCache->group()->disassociateDocumentLoader(m_documentLoader); + else if (m_candidateApplicationCacheGroup) + m_candidateApplicationCacheGroup->disassociateDocumentLoader(m_documentLoader); +} + +void ApplicationCacheHost::selectCacheWithoutManifest() +{ + ApplicationCacheGroup::selectCacheWithoutManifestURL(m_documentLoader->frame()); +} + +void ApplicationCacheHost::selectCacheWithManifest(const KURL& manifestURL) +{ + ApplicationCacheGroup::selectCache(m_documentLoader->frame(), manifestURL); +} + +void ApplicationCacheHost::maybeLoadMainResource(ResourceRequest& request, SubstituteData& substituteData) +{ + // Check if this request should be loaded from the application cache + if (!substituteData.isValid() && isApplicationCacheEnabled()) { + ASSERT(!m_mainResourceApplicationCache); + + m_mainResourceApplicationCache = ApplicationCacheGroup::cacheForMainRequest(request, m_documentLoader); + + if (m_mainResourceApplicationCache) { + // Get the resource from the application cache. By definition, cacheForMainRequest() returns a cache that contains the resource. + ApplicationCacheResource* resource = m_mainResourceApplicationCache->resourceForRequest(request); + substituteData = SubstituteData(resource->data(), + resource->response().mimeType(), + resource->response().textEncodingName(), KURL()); + } + } +} + +bool ApplicationCacheHost::maybeLoadFallbackForMainResponse(const ResourceRequest& request, const ResourceResponse& r) +{ + if (r.httpStatusCode() / 100 == 4 || r.httpStatusCode() / 100 == 5) { + ASSERT(!m_mainResourceApplicationCache); + if (isApplicationCacheEnabled()) { + m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, documentLoader()); + + if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get())) + return true; + } + } + return false; +} + +bool ApplicationCacheHost::maybeLoadFallbackForMainError(const ResourceRequest& request, const ResourceError& error) +{ + if (!error.isCancellation()) { + ASSERT(!m_mainResourceApplicationCache); + if (isApplicationCacheEnabled()) { + m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, m_documentLoader); + + if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get())) + return true; + } + } + return false; +} + +void ApplicationCacheHost::mainResourceDataReceived(const char*, int, long long, bool) +{ + // This method is here to facilitate alternate implemetations of this interface by the host browser. +} + +void ApplicationCacheHost::failedLoadingMainResource() +{ + ApplicationCacheGroup* group = m_candidateApplicationCacheGroup; + if (!group && m_applicationCache) { + ASSERT(!mainResourceApplicationCache()); // If the main resource were loaded from a cache, it wouldn't fail. + group = m_applicationCache->group(); + } + + if (group) + group->failedLoadingMainResource(m_documentLoader); +} + +void ApplicationCacheHost::finishedLoadingMainResource() +{ + ApplicationCacheGroup* group = candidateApplicationCacheGroup(); + if (!group && applicationCache() && !mainResourceApplicationCache()) + group = applicationCache()->group(); + + if (group) + group->finishedLoadingMainResource(m_documentLoader); +} + +bool ApplicationCacheHost::maybeLoadResource(ResourceLoader* loader, ResourceRequest& request, const KURL& originalURL) +{ + if (!isApplicationCacheEnabled()) + return false; + + if (request.url() != originalURL) + return false; + + ApplicationCacheResource* resource; + if (!shouldLoadResourceFromApplicationCache(request, resource)) + return false; + + m_documentLoader->m_pendingSubstituteResources.set(loader, resource); + m_documentLoader->deliverSubstituteResourcesAfterDelay(); + + return true; +} + +bool ApplicationCacheHost::maybeLoadFallbackForRedirect(ResourceLoader* resourceLoader, ResourceRequest& request, const ResourceResponse& redirectResponse) +{ + if (!redirectResponse.isNull() && !protocolHostAndPortAreEqual(request.url(), redirectResponse.url())) + if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader)) + return true; + return false; +} + +bool ApplicationCacheHost::maybeLoadFallbackForResponse(ResourceLoader* resourceLoader, const ResourceResponse& response) +{ + if (response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5) + if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader)) + return true; + return false; +} + +bool ApplicationCacheHost::maybeLoadFallbackForError(ResourceLoader* resourceLoader, const ResourceError& error) +{ + if (!error.isCancellation()) + if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader)) + return true; + return false; +} + +bool ApplicationCacheHost::maybeLoadSynchronously(ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data) +{ + ApplicationCacheResource* resource; + if (shouldLoadResourceFromApplicationCache(request, resource)) { + if (resource) { + response = resource->response(); + data.append(resource->data()->data(), resource->data()->size()); + } else { + error = documentLoader()->frameLoader()->client()->cannotShowURLError(request); + } + return true; + } + return false; +} + +void ApplicationCacheHost::maybeLoadFallbackSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data) +{ + // If normal loading results in a redirect to a resource with another origin (indicative of a captive portal), or a 4xx or 5xx status code or equivalent, + // or if there were network errors (but not if the user canceled the download), then instead get, from the cache, the resource of the fallback entry + // corresponding to the matched namespace. + if ((!error.isNull() && !error.isCancellation()) + || response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5 + || !protocolHostAndPortAreEqual(request.url(), response.url())) { + ApplicationCacheResource* resource; + if (getApplicationCacheFallbackResource(request, resource)) { + response = resource->response(); + data.clear(); + data.append(resource->data()->data(), resource->data()->size()); + } + } +} + +bool ApplicationCacheHost::canCacheInPageCache() const +{ + return !applicationCache() && !candidateApplicationCacheGroup(); +} + +void ApplicationCacheHost::setDOMApplicationCache(DOMApplicationCache* domApplicationCache) +{ + ASSERT(!m_domApplicationCache || !domApplicationCache); + m_domApplicationCache = domApplicationCache; +} + +void ApplicationCacheHost::notifyDOMApplicationCache(EventID id) +{ + if (m_domApplicationCache) { + ExceptionCode ec = 0; + m_domApplicationCache->dispatchEvent(Event::create(DOMApplicationCache::toEventType(id), false, false), ec); + ASSERT(!ec); + } +} + +void ApplicationCacheHost::setCandidateApplicationCacheGroup(ApplicationCacheGroup* group) +{ + ASSERT(!m_applicationCache); + m_candidateApplicationCacheGroup = group; +} + +void ApplicationCacheHost::setApplicationCache(PassRefPtr<ApplicationCache> applicationCache) +{ + if (m_candidateApplicationCacheGroup) { + ASSERT(!m_applicationCache); + m_candidateApplicationCacheGroup = 0; + } + + m_applicationCache = applicationCache; +} + +bool ApplicationCacheHost::shouldLoadResourceFromApplicationCache(const ResourceRequest& request, ApplicationCacheResource*& resource) +{ + ApplicationCache* cache = applicationCache(); + if (!cache || !cache->isComplete()) + return false; + + // If the resource is not to be fetched using the HTTP GET mechanism or equivalent, or if its URL has a different + // <scheme> component than the application cache's manifest, then fetch the resource normally. + if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request) || !equalIgnoringCase(request.url().protocol(), cache->manifestResource()->url().protocol())) + return false; + + // If the resource's URL is an master entry, the manifest, an explicit entry, or a fallback entry + // in the application cache, then get the resource from the cache (instead of fetching it). + resource = cache->resourceForURL(request.url()); + + // Resources that match fallback namespaces or online whitelist entries are fetched from the network, + // unless they are also cached. + if (!resource && (cache->urlMatchesFallbackNamespace(request.url()) || cache->isURLInOnlineWhitelist(request.url()))) + return false; + + // Resources that are not present in the manifest will always fail to load (at least, after the + // cache has been primed the first time), making the testing of offline applications simpler. + return true; +} + +bool ApplicationCacheHost::getApplicationCacheFallbackResource(const ResourceRequest& request, ApplicationCacheResource*& resource, ApplicationCache* cache) +{ + if (!cache) { + cache = applicationCache(); + if (!cache) + return false; + } + if (!cache->isComplete()) + return false; + + // If the resource is not a HTTP/HTTPS GET, then abort + if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request)) + return false; + + KURL fallbackURL; + if (!cache->urlMatchesFallbackNamespace(request.url(), &fallbackURL)) + return false; + + resource = cache->resourceForURL(fallbackURL); + ASSERT(resource); + + return true; +} + +bool ApplicationCacheHost::scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader* loader, ApplicationCache* cache) +{ + if (!isApplicationCacheEnabled()) + return false; + + ApplicationCacheResource* resource; + if (!getApplicationCacheFallbackResource(loader->request(), resource, cache)) + return false; + + m_documentLoader->m_pendingSubstituteResources.set(loader, resource); + m_documentLoader->deliverSubstituteResourcesAfterDelay(); + + loader->handle()->cancel(); + + return true; +} + +ApplicationCacheHost::Status ApplicationCacheHost::status() const +{ + ApplicationCache* cache = applicationCache(); + if (!cache) + return UNCACHED; + + switch (cache->group()->updateStatus()) { + case ApplicationCacheGroup::Checking: + return CHECKING; + case ApplicationCacheGroup::Downloading: + return DOWNLOADING; + case ApplicationCacheGroup::Idle: { + if (cache->group()->isObsolete()) + return OBSOLETE; + if (cache != cache->group()->newestCache()) + return UPDATEREADY; + return IDLE; + } + } + + ASSERT_NOT_REACHED(); + return UNCACHED; +} + +bool ApplicationCacheHost::update() +{ + ApplicationCache* cache = applicationCache(); + if (!cache) + return false; + cache->group()->update(m_documentLoader->frame(), ApplicationCacheUpdateWithoutBrowsingContext); + return true; +} + +bool ApplicationCacheHost::swapCache() +{ + ApplicationCache* cache = applicationCache(); + if (!cache) + return false; + + // If the group of application caches to which cache belongs has the lifecycle status obsolete, unassociate document from cache. + if (cache->group()->isObsolete()) { + cache->group()->disassociateDocumentLoader(m_documentLoader); + return true; + } + + // If there is no newer cache, raise an INVALID_STATE_ERR exception. + ApplicationCache* newestCache = cache->group()->newestCache(); + if (cache == newestCache) + return false; + + ASSERT(cache->group() == newestCache->group()); + setApplicationCache(newestCache); + + return true; +} + +bool ApplicationCacheHost::isApplicationCacheEnabled() +{ + return m_documentLoader->frame()->settings() + && m_documentLoader->frame()->settings()->offlineWebApplicationCacheEnabled(); +} + +} // namespace WebCore + +#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.h b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.h new file mode 100644 index 000000000..236013d1b --- /dev/null +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheHost.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2009, Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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 ApplicationCacheHost_h +#define ApplicationCacheHost_h + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + + class DOMApplicationCache; + class DocumentLoader; + class KURL; + class ResourceLoader; + class ResourceError; + struct ResourceRequest; + class ResourceResponse; + class SubstituteData; +#if PLATFORM(CHROMIUM) + class ApplicationCacheHostInternal; +#else + class ApplicationCache; + class ApplicationCacheGroup; + class ApplicationCacheResource; + class ApplicationCacheStorage; +#endif + + class ApplicationCacheHost { + public: + // The Status numeric values are specified in the HTML5 spec. + enum Status { + UNCACHED = 0, + IDLE = 1, + CHECKING = 2, + DOWNLOADING = 3, + UPDATEREADY = 4, + OBSOLETE = 5 + }; + + enum EventID { + CHECKING_EVENT = 0, + ERROR_EVENT, + NOUPDATE_EVENT, + DOWNLOADING_EVENT, + PROGRESS_EVENT, + UPDATEREADY_EVENT, + CACHED_EVENT, + OBSOLETE_EVENT // Must remain the last value, this is used to size arrays. + }; + + ApplicationCacheHost(DocumentLoader*); + ~ApplicationCacheHost(); + + void selectCacheWithoutManifest(); + void selectCacheWithManifest(const KURL& manifestURL); + + void maybeLoadMainResource(ResourceRequest&, SubstituteData&); + bool maybeLoadFallbackForMainResponse(const ResourceRequest&, const ResourceResponse&); + bool maybeLoadFallbackForMainError(const ResourceRequest&, const ResourceError&); + void mainResourceDataReceived(const char* data, int length, long long lengthReceived, bool allAtOnce); + void finishedLoadingMainResource(); + void failedLoadingMainResource(); + + bool maybeLoadResource(ResourceLoader*, ResourceRequest&, const KURL& originalURL); + bool maybeLoadFallbackForRedirect(ResourceLoader*, ResourceRequest&, const ResourceResponse&); + bool maybeLoadFallbackForResponse(ResourceLoader*, const ResourceResponse&); + bool maybeLoadFallbackForError(ResourceLoader*, const ResourceError&); + + bool maybeLoadSynchronously(ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data); + void maybeLoadFallbackSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data); + + bool canCacheInPageCache() const; + + Status status() const; + bool update(); + bool swapCache(); + + void setDOMApplicationCache(DOMApplicationCache* domApplicationCache); + void notifyDOMApplicationCache(EventID id); + + private: + bool isApplicationCacheEnabled(); + DocumentLoader* documentLoader() { return m_documentLoader; } + + DOMApplicationCache* m_domApplicationCache; + DocumentLoader* m_documentLoader; + +#if PLATFORM(CHROMIUM) + friend class ApplicationCacheHostInternal; + OwnPtr<ApplicationCacheHostInternal> m_internal; +#else + friend class ApplicationCacheGroup; + friend class ApplicationCacheStorage; + + bool scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader*, ApplicationCache* = 0); + bool shouldLoadResourceFromApplicationCache(const ResourceRequest&, ApplicationCacheResource*&); + bool getApplicationCacheFallbackResource(const ResourceRequest&, ApplicationCacheResource*&, ApplicationCache* = 0); + void setCandidateApplicationCacheGroup(ApplicationCacheGroup* group); + ApplicationCacheGroup* candidateApplicationCacheGroup() const { return m_candidateApplicationCacheGroup; } + void setApplicationCache(PassRefPtr<ApplicationCache> applicationCache); + ApplicationCache* applicationCache() const { return m_applicationCache.get(); } + ApplicationCache* mainResourceApplicationCache() const { return m_mainResourceApplicationCache.get(); } + + + // The application cache that the document loader is associated with (if any). + RefPtr<ApplicationCache> m_applicationCache; + + // Before an application cache has finished loading, this will be the candidate application + // group that the document loader is associated with. + ApplicationCacheGroup* m_candidateApplicationCacheGroup; + + // This is the application cache the main resource was loaded from (if any). + RefPtr<ApplicationCache> m_mainResourceApplicationCache; +#endif + }; + +} // namespace WebCore + +#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) +#endif // ApplicationCacheHost_h diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheResource.h b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheResource.h index cffc51bf3..2ca784663 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheResource.h +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheResource.h @@ -44,7 +44,7 @@ public: static PassRefPtr<ApplicationCacheResource> create(const KURL& url, const ResourceResponse& response, unsigned type, PassRefPtr<SharedBuffer> buffer = SharedBuffer::create()) { - ASSERT(!url.hasRef()); + ASSERT(!url.hasFragmentIdentifier()); return adoptRef(new ApplicationCacheResource(url, response, type, buffer)); } diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheStorage.cpp b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheStorage.cpp index 18a0ed4d9..d6ee72390 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheStorage.cpp +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheStorage.cpp @@ -29,6 +29,7 @@ #if ENABLE(OFFLINE_WEB_APPLICATIONS) #include "ApplicationCache.h" +#include "ApplicationCacheHost.h" #include "ApplicationCacheGroup.h" #include "ApplicationCacheResource.h" #include "CString.h" @@ -127,7 +128,7 @@ ApplicationCacheGroup* ApplicationCacheStorage::loadCacheGroup(const KURL& manif ApplicationCacheGroup* ApplicationCacheStorage::findOrCreateCacheGroup(const KURL& manifestURL) { - ASSERT(!manifestURL.hasRef()); + ASSERT(!manifestURL.hasFragmentIdentifier()); std::pair<CacheGroupMap::iterator, bool> result = m_cachesInMemory.add(manifestURL, 0); @@ -177,7 +178,7 @@ void ApplicationCacheStorage::loadManifestHostHashes() ApplicationCacheGroup* ApplicationCacheStorage::cacheGroupForURL(const KURL& url) { - ASSERT(!url.hasRef()); + ASSERT(!url.hasFragmentIdentifier()); loadManifestHostHashes(); @@ -215,7 +216,7 @@ ApplicationCacheGroup* ApplicationCacheStorage::cacheGroupForURL(const KURL& url int result; while ((result = statement.step()) == SQLResultRow) { - KURL manifestURL = KURL(statement.getColumnText(1)); + KURL manifestURL = KURL(ParsedURLString, statement.getColumnText(1)); if (m_cachesInMemory.contains(manifestURL)) continue; @@ -254,7 +255,7 @@ ApplicationCacheGroup* ApplicationCacheStorage::cacheGroupForURL(const KURL& url ApplicationCacheGroup* ApplicationCacheStorage::fallbackCacheGroupForURL(const KURL& url) { - ASSERT(!url.hasRef()); + ASSERT(!url.hasFragmentIdentifier()); // Check if an appropriate cache already exists in memory. CacheGroupMap::const_iterator end = m_cachesInMemory.end(); @@ -283,7 +284,7 @@ ApplicationCacheGroup* ApplicationCacheStorage::fallbackCacheGroupForURL(const K int result; while ((result = statement.step()) == SQLResultRow) { - KURL manifestURL = KURL(statement.getColumnText(1)); + KURL manifestURL = KURL(ParsedURLString, statement.getColumnText(1)); if (m_cachesInMemory.contains(manifestURL)) continue; @@ -426,7 +427,7 @@ bool ApplicationCacheStorage::executeSQLCommand(const String& sql) return result; } -static const int schemaVersion = 4; +static const int schemaVersion = 5; void ApplicationCacheStorage::verifySchemaVersion() { @@ -478,6 +479,7 @@ void ApplicationCacheStorage::openDatabase(bool createIfDoesNotExist) "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, size 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 CacheAllowsAllNetworkRequests (wildcard INTEGER 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)"); @@ -490,6 +492,7 @@ void ApplicationCacheStorage::openDatabase(bool createIfDoesNotExist) " FOR EACH ROW BEGIN" " DELETE FROM CacheEntries WHERE cache = OLD.id;" " DELETE FROM CacheWhitelistURLs WHERE cache = OLD.id;" + " DELETE FROM CacheAllowsAllNetworkRequests WHERE cache = OLD.id;" " DELETE FROM FallbackURLs WHERE cache = OLD.id;" " END"); @@ -583,6 +586,18 @@ bool ApplicationCacheStorage::store(ApplicationCache* cache, ResourceStorageIDJo return false; } } + + // Store online whitelist wildcard flag. + { + SQLiteStatement statement(m_database, "INSERT INTO CacheAllowsAllNetworkRequests (wildcard, cache) VALUES (?, ?)"); + statement.prepare(); + + statement.bindInt64(1, cache->allowsAllNetworkRequests()); + statement.bindInt64(2, cacheStorageID); + + if (!executeStatement(statement)) + return false; + } // Store fallback URLs. const FallbackURLVector& fallbackURLs = cache->fallbackURLs(); @@ -820,7 +835,7 @@ PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storage int result; while ((result = cacheStatement.step()) == SQLResultRow) { - KURL url(cacheStatement.getColumnText(0)); + KURL url(ParsedURLString, cacheStatement.getColumnText(0)); unsigned type = static_cast<unsigned>(cacheStatement.getColumnInt64(1)); @@ -856,13 +871,28 @@ PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storage Vector<KURL> whitelist; while ((result = whitelistStatement.step()) == SQLResultRow) - whitelist.append(whitelistStatement.getColumnText(0)); + whitelist.append(KURL(ParsedURLString, whitelistStatement.getColumnText(0))); if (result != SQLResultDone) LOG_ERROR("Could not load cache online whitelist, error \"%s\"", m_database.lastErrorMsg()); cache->setOnlineWhitelist(whitelist); + // Load online whitelist wildcard flag. + SQLiteStatement whitelistWildcardStatement(m_database, "SELECT wildcard FROM CacheAllowsAllNetworkRequests WHERE cache=?"); + if (whitelistWildcardStatement.prepare() != SQLResultOk) + return 0; + whitelistWildcardStatement.bindInt64(1, storageID); + + result = whitelistWildcardStatement.step(); + if (result != SQLResultRow) + LOG_ERROR("Could not load cache online whitelist wildcard flag, error \"%s\"", m_database.lastErrorMsg()); + + cache->setAllowsAllNetworkRequests(whitelistWildcardStatement.getColumnInt64(0)); + + if (whitelistWildcardStatement.step() != SQLResultDone) + LOG_ERROR("Too many rows for online whitelist wildcard flag"); + // Load fallback URLs. SQLiteStatement fallbackStatement(m_database, "SELECT namespace, fallbackURL FROM FallbackURLs WHERE cache=?"); if (fallbackStatement.prepare() != SQLResultOk) @@ -871,7 +901,7 @@ PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storage FallbackURLVector fallbackURLs; while ((result = fallbackStatement.step()) == SQLResultRow) - fallbackURLs.append(make_pair(fallbackStatement.getColumnText(0), fallbackStatement.getColumnText(1))); + fallbackURLs.append(make_pair(KURL(ParsedURLString, fallbackStatement.getColumnText(0)), KURL(ParsedURLString, fallbackStatement.getColumnText(1)))); if (result != SQLResultDone) LOG_ERROR("Could not load fallback URLs, error \"%s\"", m_database.lastErrorMsg()); @@ -937,8 +967,12 @@ void ApplicationCacheStorage::empty() it->second->clearStorageID(); } -bool ApplicationCacheStorage::storeCopyOfCache(const String& cacheDirectory, ApplicationCache* cache) +bool ApplicationCacheStorage::storeCopyOfCache(const String& cacheDirectory, ApplicationCacheHost* cacheHost) { + ApplicationCache* cache = cacheHost->applicationCache(); + if (!cache) + return true; + // Create a new cache. RefPtr<ApplicationCache> cacheCopy = ApplicationCache::create(); @@ -982,7 +1016,7 @@ bool ApplicationCacheStorage::manifestURLs(Vector<KURL>* urls) return false; while (selectURLs.step() == SQLResultRow) - urls->append(selectURLs.getColumnText(0)); + urls->append(KURL(ParsedURLString, selectURLs.getColumnText(0))); return true; } @@ -1063,6 +1097,10 @@ bool ApplicationCacheStorage::deleteCacheGroup(const String& manifestURL) void ApplicationCacheStorage::vacuumDatabaseFile() { + openDatabase(false); + if (!m_database.isOpen()) + return; + m_database.runVacuumCommand(); } diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheStorage.h b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheStorage.h index c6d687ef7..1348aa92b 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheStorage.h +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ApplicationCacheStorage.h @@ -37,6 +37,7 @@ namespace WebCore { class ApplicationCache; +class ApplicationCacheHost; class ApplicationCacheGroup; class ApplicationCacheResource; class KURL; @@ -69,7 +70,7 @@ public: void empty(); - static bool storeCopyOfCache(const String& cacheDirectory, ApplicationCache*); + static bool storeCopyOfCache(const String& cacheDirectory, ApplicationCacheHost*); bool manifestURLs(Vector<KURL>* urls); bool cacheGroupSize(const String& manifestURL, int64_t* size); diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.cpp b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.cpp index 5ea5d4f85..29c1bd566 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.cpp +++ b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.cpp @@ -28,9 +28,7 @@ #if ENABLE(OFFLINE_WEB_APPLICATIONS) -#include "ApplicationCache.h" -#include "ApplicationCacheGroup.h" -#include "ApplicationCacheResource.h" +#include "ApplicationCacheHost.h" #include "DocumentLoader.h" #include "Event.h" #include "EventException.h" @@ -44,198 +42,87 @@ namespace WebCore { DOMApplicationCache::DOMApplicationCache(Frame* frame) : m_frame(frame) { + ASSERT(!m_frame || applicationCacheHost()); + ApplicationCacheHost* cacheHost = applicationCacheHost(); + if (cacheHost) + cacheHost->setDOMApplicationCache(this); } void DOMApplicationCache::disconnectFrame() { + ApplicationCacheHost* cacheHost = applicationCacheHost(); + if (cacheHost) + cacheHost->setDOMApplicationCache(0); m_frame = 0; } -ApplicationCache* DOMApplicationCache::associatedCache() const +ApplicationCacheHost* DOMApplicationCache::applicationCacheHost() const { - if (!m_frame) + if (!m_frame || !m_frame->loader()->documentLoader()) return 0; - - return m_frame->loader()->documentLoader()->applicationCache(); + return m_frame->loader()->documentLoader()->applicationCacheHost(); } unsigned short DOMApplicationCache::status() const { - ApplicationCache* cache = associatedCache(); - if (!cache) - return UNCACHED; - - switch (cache->group()->updateStatus()) { - case ApplicationCacheGroup::Checking: - return CHECKING; - case ApplicationCacheGroup::Downloading: - return DOWNLOADING; - case ApplicationCacheGroup::Idle: { - if (cache->group()->isObsolete()) - return OBSOLETE; - if (cache != cache->group()->newestCache()) - return UPDATEREADY; - return IDLE; - } - } - - ASSERT_NOT_REACHED(); - return 0; + ApplicationCacheHost* cacheHost = applicationCacheHost(); + if (!cacheHost) + return ApplicationCacheHost::UNCACHED; + return cacheHost->status(); } void DOMApplicationCache::update(ExceptionCode& ec) { - ApplicationCache* cache = associatedCache(); - if (!cache) { + ApplicationCacheHost* cacheHost = applicationCacheHost(); + if (!cacheHost || !cacheHost->update()) ec = INVALID_STATE_ERR; - return; - } - - cache->group()->update(m_frame, ApplicationCacheUpdateWithoutBrowsingContext); } -bool DOMApplicationCache::swapCache() -{ - if (!m_frame) - return false; - - ApplicationCache* cache = m_frame->loader()->documentLoader()->applicationCache(); - if (!cache) - return false; - - // If the group of application caches to which cache belongs has the lifecycle status obsolete, unassociate document from cache. - if (cache->group()->isObsolete()) { - cache->group()->disassociateDocumentLoader(m_frame->loader()->documentLoader()); - return true; - } - - // If there is no newer cache, raise an INVALID_STATE_ERR exception. - 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()) + ApplicationCacheHost* cacheHost = applicationCacheHost(); + if (!cacheHost || !cacheHost->swapCache()) ec = INVALID_STATE_ERR; } ScriptExecutionContext* DOMApplicationCache::scriptExecutionContext() const { + ASSERT(m_frame); 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) -{ - 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 || 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); +const AtomicString& DOMApplicationCache::toEventType(ApplicationCacheHost::EventID id) +{ + switch (id) { + case ApplicationCacheHost::CHECKING_EVENT: + return eventNames().checkingEvent; + case ApplicationCacheHost::ERROR_EVENT: + return eventNames().errorEvent; + case ApplicationCacheHost::NOUPDATE_EVENT: + return eventNames().noupdateEvent; + case ApplicationCacheHost::DOWNLOADING_EVENT: + return eventNames().downloadingEvent; + case ApplicationCacheHost::PROGRESS_EVENT: + return eventNames().progressEvent; + case ApplicationCacheHost::UPDATEREADY_EVENT: + return eventNames().updatereadyEvent; + case ApplicationCacheHost::CACHED_EVENT: + return eventNames().cachedEvent; + case ApplicationCacheHost::OBSOLETE_EVENT: + return eventNames().obsoleteEvent; } - - 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()); + ASSERT_NOT_REACHED(); + return eventNames().errorEvent; } -void DOMApplicationCache::callCachedListener() +EventTargetData* DOMApplicationCache::eventTargetData() { - callListener(eventNames().cachedEvent, m_onCachedListener.get()); + return &m_eventTargetData; } -void DOMApplicationCache::callObsoleteListener() +EventTargetData* DOMApplicationCache::ensureEventTargetData() { - callListener(eventNames().obsoleteEvent, m_onObsoleteListener.get()); + return &m_eventTargetData; } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.h b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.h index 4fe151180..077cae018 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.h +++ b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.h @@ -28,9 +28,11 @@ #if ENABLE(OFFLINE_WEB_APPLICATIONS) +#include "ApplicationCacheHost.h" #include "AtomicStringHash.h" -#include "EventTarget.h" #include "EventListener.h" +#include "EventNames.h" +#include "EventTarget.h" #include <wtf/HashMap.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -38,100 +40,55 @@ 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(); + ~DOMApplicationCache() { ASSERT(!m_frame); } - enum Status { - UNCACHED = 0, - IDLE = 1, - CHECKING = 2, - DOWNLOADING = 3, - UPDATEREADY = 4, - OBSOLETE = 5 - }; + void disconnectFrame(); unsigned short status() const; - void update(ExceptionCode&); void swapCache(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; } + + // EventTarget impl 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(); } + // Explicitly named attribute event listener helpers - 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(); } - - void setOnobsolete(PassRefPtr<EventListener> eventListener) { m_onObsoleteListener = eventListener; } - EventListener* onobsolete() const { return m_onObsoleteListener.get(); } + DEFINE_ATTRIBUTE_EVENT_LISTENER(checking); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_ATTRIBUTE_EVENT_LISTENER(noupdate); + DEFINE_ATTRIBUTE_EVENT_LISTENER(downloading); + DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(updateready); + DEFINE_ATTRIBUTE_EVENT_LISTENER(cached); + DEFINE_ATTRIBUTE_EVENT_LISTENER(obsolete); virtual ScriptExecutionContext* scriptExecutionContext() const; DOMApplicationCache* toDOMApplicationCache() { return this; } - void callCheckingListener(); - void callErrorListener(); - void callNoUpdateListener(); - void callDownloadingListener(); - void callProgressListener(); - void callUpdateReadyListener(); - void callCachedListener(); - void callObsoleteListener(); - + static const AtomicString& toEventType(ApplicationCacheHost::EventID id); + private: DOMApplicationCache(Frame*); - void callListener(const AtomicString& eventType, EventListener*); - + virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } + virtual EventTargetData* eventTargetData(); + virtual EventTargetData* ensureEventTargetData(); - 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; - RefPtr<EventListener> m_onObsoleteListener; - - EventListenersMap m_eventListeners; + ApplicationCacheHost* applicationCacheHost() const; Frame* m_frame; + EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.idl b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.idl index ebc1d19b7..dd5468ac4 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.idl +++ b/src/3rdparty/webkit/WebCore/loader/appcache/DOMApplicationCache.idl @@ -27,7 +27,7 @@ module offline { interface [ Conditional=OFFLINE_WEB_APPLICATIONS, - CustomMarkFunction + EventTarget ] DOMApplicationCache { // update status const unsigned short UNCACHED = 0; diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ManifestParser.cpp b/src/3rdparty/webkit/WebCore/loader/appcache/ManifestParser.cpp index 4169313fc..b001bffec 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ManifestParser.cpp +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ManifestParser.cpp @@ -43,7 +43,8 @@ bool parseManifest(const KURL& manifestURL, const char* data, int length, Manife ASSERT(manifest.explicitURLs.isEmpty()); ASSERT(manifest.onlineWhitelistedURLs.isEmpty()); ASSERT(manifest.fallbackURLs.isEmpty()); - + manifest.allowAllNetworkRequests = false; + Mode mode = Explicit; RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/cache-manifest", "UTF-8"); @@ -109,13 +110,19 @@ bool parseManifest(const KURL& manifestURL, const char* data, int length, Manife while (p < lineEnd && *p != '\t' && *p != ' ') p++; + if (mode == OnlineWhitelist && p - line.characters() == 1 && *line.characters() == '*') { + // Wildcard was found. + manifest.allowAllNetworkRequests = true; + continue; + } + KURL url(manifestURL, String(line.characters(), p - line.characters())); if (!url.isValid()) continue; - if (url.hasRef()) - url.setRef(String()); + if (url.hasFragmentIdentifier()) + url.removeFragmentIdentifier(); if (!equalIgnoringCase(url.protocol(), manifestURL.protocol())) continue; @@ -141,8 +148,8 @@ bool parseManifest(const KURL& manifestURL, const char* data, int length, Manife KURL namespaceURL(manifestURL, String(line.characters(), p - line.characters())); if (!namespaceURL.isValid()) continue; - if (namespaceURL.hasRef()) - namespaceURL.setRef(String()); + if (namespaceURL.hasFragmentIdentifier()) + namespaceURL.removeFragmentIdentifier(); if (!protocolHostAndPortAreEqual(manifestURL, namespaceURL)) continue; @@ -159,8 +166,8 @@ bool parseManifest(const KURL& manifestURL, const char* data, int length, Manife KURL fallbackURL(manifestURL, String(fallbackStart, p - fallbackStart)); if (!fallbackURL.isValid()) continue; - if (fallbackURL.hasRef()) - fallbackURL.setRef(String()); + if (fallbackURL.hasFragmentIdentifier()) + fallbackURL.removeFragmentIdentifier(); if (!protocolHostAndPortAreEqual(manifestURL, fallbackURL)) continue; diff --git a/src/3rdparty/webkit/WebCore/loader/appcache/ManifestParser.h b/src/3rdparty/webkit/WebCore/loader/appcache/ManifestParser.h index c03cf2728..f0369ee01 100644 --- a/src/3rdparty/webkit/WebCore/loader/appcache/ManifestParser.h +++ b/src/3rdparty/webkit/WebCore/loader/appcache/ManifestParser.h @@ -38,6 +38,7 @@ namespace WebCore { Vector<KURL> onlineWhitelistedURLs; HashSet<String> explicitURLs; FallbackURLVector fallbackURLs; + bool allowAllNetworkRequests; // Wildcard found in NETWORK section. }; bool parseManifest(const KURL& manifestURL, const char* data, int length, Manifest&); |