Remove ApplicationCacheGroup::m_isCopy
[WebKit-https.git] / Source / WebCore / loader / appcache / ApplicationCache.cpp
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 #include "ApplicationCacheGroup.h"
30 #include "ApplicationCacheResource.h"
31 #include "ApplicationCacheStorage.h"
32 #include "ResourceRequest.h"
33 #include "SecurityOrigin.h"
34 #include <algorithm>
35 #include <stdio.h>
36 #include <wtf/text/CString.h>
37
38 namespace WebCore {
39  
40 static inline bool fallbackURLLongerThan(const std::pair<URL, URL>& lhs, const std::pair<URL, URL>& rhs)
41 {
42     return lhs.first.string().length() > rhs.first.string().length();
43 }
44
45 ApplicationCache::ApplicationCache()
46     : m_group(0)
47     , m_manifest(0)
48     , m_estimatedSizeInStorage(0)
49     , m_storageID(0)
50 {
51 }
52
53 ApplicationCache::~ApplicationCache()
54 {
55     if (m_group)
56         m_group->cacheDestroyed(this);
57 }
58     
59 void ApplicationCache::setGroup(ApplicationCacheGroup* group)
60 {
61     ASSERT(!m_group || group == m_group);
62     m_group = group;
63 }
64
65 bool ApplicationCache::isComplete()
66 {
67     return m_group && m_group->cacheIsComplete(this);
68 }
69
70 void ApplicationCache::setManifestResource(PassRefPtr<ApplicationCacheResource> manifest)
71 {
72     ASSERT(manifest);
73     ASSERT(!m_manifest);
74     ASSERT(manifest->type() & ApplicationCacheResource::Manifest);
75     
76     m_manifest = manifest.get();
77     
78     addResource(manifest);
79 }
80     
81 void ApplicationCache::addResource(PassRefPtr<ApplicationCacheResource> resource)
82 {
83     ASSERT(resource);
84     
85     const String& url = resource->url();
86     
87     ASSERT(!m_resources.contains(url));
88     
89     if (m_storageID) {
90         ASSERT(!resource->storageID());
91         ASSERT(resource->type() & ApplicationCacheResource::Master);
92         
93         // Add the resource to the storage.
94         ApplicationCacheStorage::singleton().store(resource.get(), this);
95     }
96
97     m_estimatedSizeInStorage += resource->estimatedSizeInStorage();
98
99     m_resources.set(url, resource);
100 }
101
102 unsigned ApplicationCache::removeResource(const String& url)
103 {
104     HashMap<String, RefPtr<ApplicationCacheResource>>::iterator it = m_resources.find(url);
105     if (it == m_resources.end())
106         return 0;
107
108     // The resource exists, get its type so we can return it.
109     unsigned type = it->value->type();
110
111     m_estimatedSizeInStorage -= it->value->estimatedSizeInStorage();
112
113     m_resources.remove(it);
114
115     return type;
116 }    
117     
118 ApplicationCacheResource* ApplicationCache::resourceForURL(const String& url)
119 {
120     ASSERT(!URL(ParsedURLString, url).hasFragmentIdentifier());
121     return m_resources.get(url);
122 }    
123
124 bool ApplicationCache::requestIsHTTPOrHTTPSGet(const ResourceRequest& request)
125 {
126     if (!request.url().protocolIsInHTTPFamily())
127         return false;
128     
129     if (!equalIgnoringCase(request.httpMethod(), "GET"))
130         return false;
131
132     return true;
133 }    
134
135 ApplicationCacheResource* ApplicationCache::resourceForRequest(const ResourceRequest& request)
136 {
137     // We only care about HTTP/HTTPS GET requests.
138     if (!requestIsHTTPOrHTTPSGet(request))
139         return 0;
140
141     URL url(request.url());
142     if (url.hasFragmentIdentifier())
143         url.removeFragmentIdentifier();
144
145     return resourceForURL(url);
146 }
147
148 void ApplicationCache::setOnlineWhitelist(const Vector<URL>& onlineWhitelist)
149 {
150     ASSERT(m_onlineWhitelist.isEmpty());
151     m_onlineWhitelist = onlineWhitelist; 
152 }
153
154 bool ApplicationCache::isURLInOnlineWhitelist(const URL& url)
155 {
156     size_t whitelistSize = m_onlineWhitelist.size();
157     for (size_t i = 0; i < whitelistSize; ++i) {
158         if (protocolHostAndPortAreEqual(url, m_onlineWhitelist[i]) && url.string().startsWith(m_onlineWhitelist[i].string()))
159             return true;
160     }
161     return false;
162 }
163
164 void ApplicationCache::setFallbackURLs(const FallbackURLVector& fallbackURLs)
165 {
166     ASSERT(m_fallbackURLs.isEmpty());
167     m_fallbackURLs = fallbackURLs;
168     // FIXME: What's the right behavior if we have 2 or more identical namespace URLs?
169     std::stable_sort(m_fallbackURLs.begin(), m_fallbackURLs.end(), fallbackURLLongerThan);
170 }
171
172 bool ApplicationCache::urlMatchesFallbackNamespace(const URL& url, URL* fallbackURL)
173 {
174     size_t fallbackCount = m_fallbackURLs.size();
175     for (size_t i = 0; i < fallbackCount; ++i) {
176         if (protocolHostAndPortAreEqual(url, m_fallbackURLs[i].first) && url.string().startsWith(m_fallbackURLs[i].first.string())) {
177             if (fallbackURL)
178                 *fallbackURL = m_fallbackURLs[i].second;
179             return true;
180         }
181     }
182     return false;
183 }
184
185 void ApplicationCache::clearStorageID()
186 {
187     m_storageID = 0;
188     
189     for (const auto& resource : m_resources.values())
190         resource->clearStorageID();
191 }
192     
193 #ifndef NDEBUG
194 void ApplicationCache::dump()
195 {
196     for (const auto& urlAndResource : m_resources) {
197         printf("%s ", urlAndResource.key.utf8().data());
198         ApplicationCacheResource::dumpType(urlAndResource.value->type());
199     }
200 }
201 #endif
202
203 }