• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "ApplicationCache.h"
28 
29 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
30 
31 #include "ApplicationCacheGroup.h"
32 #include "ApplicationCacheResource.h"
33 #include "ApplicationCacheStorage.h"
34 #include "ResourceRequest.h"
35 #include <stdio.h>
36 
37 namespace WebCore {
38 
ApplicationCache()39 ApplicationCache::ApplicationCache()
40     : m_group(0)
41     , m_manifest(0)
42     , m_estimatedSizeInStorage(0)
43     , m_storageID(0)
44 {
45 }
46 
~ApplicationCache()47 ApplicationCache::~ApplicationCache()
48 {
49     if (m_group && !m_group->isCopy())
50         m_group->cacheDestroyed(this);
51 }
52 
setGroup(ApplicationCacheGroup * group)53 void ApplicationCache::setGroup(ApplicationCacheGroup* group)
54 {
55     ASSERT(!m_group || group == m_group);
56     m_group = group;
57 }
58 
isComplete() const59 bool ApplicationCache::isComplete() const
60 {
61     return !m_group->cacheIsBeingUpdated(this);
62 }
63 
setManifestResource(PassRefPtr<ApplicationCacheResource> manifest)64 void ApplicationCache::setManifestResource(PassRefPtr<ApplicationCacheResource> manifest)
65 {
66     ASSERT(manifest);
67     ASSERT(!m_manifest);
68     ASSERT(manifest->type() & ApplicationCacheResource::Manifest);
69 
70     m_manifest = manifest.get();
71 
72     addResource(manifest);
73 }
74 
addResource(PassRefPtr<ApplicationCacheResource> resource)75 void ApplicationCache::addResource(PassRefPtr<ApplicationCacheResource> resource)
76 {
77     ASSERT(resource);
78 
79     const String& url = resource->url();
80 
81     ASSERT(!m_resources.contains(url));
82 
83     if (m_storageID) {
84         ASSERT(!resource->storageID());
85         ASSERT(resource->type() & ApplicationCacheResource::Master);
86 
87         // Add the resource to the storage.
88         cacheStorage().store(resource.get(), this);
89     }
90 
91     m_estimatedSizeInStorage += resource->estimatedSizeInStorage();
92 
93     m_resources.set(url, resource);
94 }
95 
removeResource(const String & url)96 unsigned ApplicationCache::removeResource(const String& url)
97 {
98     HashMap<String, RefPtr<ApplicationCacheResource> >::iterator it = m_resources.find(url);
99     if (it == m_resources.end())
100         return 0;
101 
102     // The resource exists, get its type so we can return it.
103     unsigned type = it->second->type();
104 
105     m_resources.remove(it);
106 
107     m_estimatedSizeInStorage -= it->second->estimatedSizeInStorage();
108 
109     return type;
110 }
111 
resourceForURL(const String & url)112 ApplicationCacheResource* ApplicationCache::resourceForURL(const String& url)
113 {
114     ASSERT(!KURL(ParsedURLString, url).hasFragmentIdentifier());
115     return m_resources.get(url).get();
116 }
117 
requestIsHTTPOrHTTPSGet(const ResourceRequest & request)118 bool ApplicationCache::requestIsHTTPOrHTTPSGet(const ResourceRequest& request)
119 {
120     if (!request.url().protocolInHTTPFamily())
121         return false;
122 
123     if (!equalIgnoringCase(request.httpMethod(), "GET"))
124         return false;
125 
126     return true;
127 }
128 
resourceForRequest(const ResourceRequest & request)129 ApplicationCacheResource* ApplicationCache::resourceForRequest(const ResourceRequest& request)
130 {
131     // We only care about HTTP/HTTPS GET requests.
132     if (!requestIsHTTPOrHTTPSGet(request))
133         return false;
134 
135     KURL url(request.url());
136     if (url.hasFragmentIdentifier())
137         url.removeFragmentIdentifier();
138 
139     return resourceForURL(url);
140 }
141 
setOnlineWhitelist(const Vector<KURL> & onlineWhitelist)142 void ApplicationCache::setOnlineWhitelist(const Vector<KURL>& onlineWhitelist)
143 {
144     ASSERT(m_onlineWhitelist.isEmpty());
145     m_onlineWhitelist = onlineWhitelist;
146 }
147 
isURLInOnlineWhitelist(const KURL & url)148 bool ApplicationCache::isURLInOnlineWhitelist(const KURL& url)
149 {
150     if (m_allowAllNetworkRequests)
151         return true;
152 
153     size_t whitelistSize = m_onlineWhitelist.size();
154     for (size_t i = 0; i < whitelistSize; ++i) {
155         if (protocolHostAndPortAreEqual(url, m_onlineWhitelist[i]) && url.string().startsWith(m_onlineWhitelist[i].string()))
156             return true;
157     }
158     return false;
159 }
160 
setFallbackURLs(const FallbackURLVector & fallbackURLs)161 void ApplicationCache::setFallbackURLs(const FallbackURLVector& fallbackURLs)
162 {
163     ASSERT(m_fallbackURLs.isEmpty());
164     m_fallbackURLs = fallbackURLs;
165 }
166 
urlMatchesFallbackNamespace(const KURL & url,KURL * fallbackURL)167 bool ApplicationCache::urlMatchesFallbackNamespace(const KURL& url, KURL* fallbackURL)
168 {
169     size_t fallbackCount = m_fallbackURLs.size();
170     for (size_t i = 0; i < fallbackCount; ++i) {
171         if (protocolHostAndPortAreEqual(url, m_fallbackURLs[i].first) && url.string().startsWith(m_fallbackURLs[i].first.string())) {
172             if (fallbackURL)
173                 *fallbackURL = m_fallbackURLs[i].second;
174             return true;
175         }
176     }
177     return false;
178 }
179 
clearStorageID()180 void ApplicationCache::clearStorageID()
181 {
182     m_storageID = 0;
183 
184     ResourceMap::const_iterator end = m_resources.end();
185     for (ResourceMap::const_iterator it = m_resources.begin(); it != end; ++it)
186         it->second->clearStorageID();
187 }
188 
189 #ifndef NDEBUG
dump()190 void ApplicationCache::dump()
191 {
192     HashMap<String, RefPtr<ApplicationCacheResource> >::const_iterator end = m_resources.end();
193 
194     for (HashMap<String, RefPtr<ApplicationCacheResource> >::const_iterator it = m_resources.begin(); it != end; ++it) {
195         printf("%s ", it->first.ascii().data());
196         ApplicationCacheResource::dumpType(it->second->type());
197     }
198 }
199 #endif
200 
201 }
202 
203 #endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
204