Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include "CacheLog.h"
6 : #include "CacheStorage.h"
7 : #include "CacheStorageService.h"
8 : #include "CacheEntry.h"
9 : #include "CacheObserver.h"
10 :
11 : #include "OldWrappers.h"
12 :
13 : #include "nsICacheEntryDoomCallback.h"
14 :
15 : #include "nsIApplicationCache.h"
16 : #include "nsIApplicationCacheService.h"
17 : #include "nsIURI.h"
18 : #include "nsNetCID.h"
19 : #include "nsServiceManagerUtils.h"
20 :
21 : namespace mozilla {
22 : namespace net {
23 :
24 80 : NS_IMPL_ISUPPORTS(CacheStorage, nsICacheStorage)
25 :
26 10 : CacheStorage::CacheStorage(nsILoadContextInfo* aInfo,
27 : bool aAllowDisk,
28 : bool aLookupAppCache,
29 : bool aSkipSizeCheck,
30 10 : bool aPinning)
31 : : mLoadContextInfo(GetLoadContextInfo(aInfo))
32 : , mWriteToDisk(aAllowDisk)
33 : , mLookupAppCache(aLookupAppCache)
34 : , mSkipSizeCheck(aSkipSizeCheck)
35 10 : , mPinning(aPinning)
36 : {
37 10 : }
38 :
39 20 : CacheStorage::~CacheStorage()
40 : {
41 30 : }
42 :
43 13 : NS_IMETHODIMP CacheStorage::AsyncOpenURI(nsIURI *aURI,
44 : const nsACString & aIdExtension,
45 : uint32_t aFlags,
46 : nsICacheEntryOpenCallback *aCallback)
47 : {
48 13 : if (!CacheStorageService::Self())
49 0 : return NS_ERROR_NOT_INITIALIZED;
50 :
51 13 : if (MOZ_UNLIKELY(!CacheObserver::UseDiskCache()) && mWriteToDisk &&
52 0 : !(aFlags & OPEN_INTERCEPTED)) {
53 0 : aCallback->OnCacheEntryAvailable(nullptr, false, nullptr, NS_ERROR_NOT_AVAILABLE);
54 0 : return NS_OK;
55 : }
56 :
57 13 : if (MOZ_UNLIKELY(!CacheObserver::UseMemoryCache()) && !mWriteToDisk &&
58 0 : !(aFlags & OPEN_INTERCEPTED)) {
59 0 : aCallback->OnCacheEntryAvailable(nullptr, false, nullptr, NS_ERROR_NOT_AVAILABLE);
60 0 : return NS_OK;
61 : }
62 :
63 13 : NS_ENSURE_ARG(aURI);
64 13 : NS_ENSURE_ARG(aCallback);
65 :
66 : nsresult rv;
67 :
68 13 : bool truncate = aFlags & nsICacheStorage::OPEN_TRUNCATE;
69 :
70 26 : nsCOMPtr<nsIURI> noRefURI;
71 13 : rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
72 13 : NS_ENSURE_SUCCESS(rv, rv);
73 :
74 26 : nsAutoCString asciiSpec;
75 13 : rv = noRefURI->GetAsciiSpec(asciiSpec);
76 13 : NS_ENSURE_SUCCESS(rv, rv);
77 :
78 26 : nsCOMPtr<nsIApplicationCache> appCache;
79 13 : if (LookupAppCache()) {
80 0 : rv = ChooseApplicationCache(noRefURI, getter_AddRefs(appCache));
81 0 : NS_ENSURE_SUCCESS(rv, rv);
82 :
83 0 : if (appCache) {
84 : // From a chosen appcache open only as readonly
85 0 : aFlags &= ~nsICacheStorage::OPEN_TRUNCATE;
86 : }
87 : }
88 :
89 13 : if (appCache) {
90 0 : nsAutoCString scheme;
91 0 : rv = noRefURI->GetScheme(scheme);
92 0 : NS_ENSURE_SUCCESS(rv, rv);
93 :
94 : RefPtr<_OldCacheLoad> appCacheLoad =
95 : new _OldCacheLoad(scheme, asciiSpec, aCallback, appCache,
96 0 : LoadInfo(), WriteToDisk(), aFlags);
97 0 : rv = appCacheLoad->Start();
98 0 : NS_ENSURE_SUCCESS(rv, rv);
99 :
100 0 : LOG(("CacheStorage::AsyncOpenURI loading from appcache"));
101 0 : return NS_OK;
102 : }
103 :
104 26 : RefPtr<CacheEntryHandle> entry;
105 13 : rv = CacheStorageService::Self()->AddStorageEntry(
106 : this, asciiSpec, aIdExtension,
107 : truncate, // replace any existing one?
108 26 : getter_AddRefs(entry));
109 13 : NS_ENSURE_SUCCESS(rv, rv);
110 :
111 : // May invoke the callback synchronously
112 13 : entry->Entry()->AsyncOpen(aCallback, aFlags);
113 :
114 13 : return NS_OK;
115 : }
116 :
117 :
118 0 : NS_IMETHODIMP CacheStorage::OpenTruncate(nsIURI *aURI, const nsACString & aIdExtension,
119 : nsICacheEntry **aCacheEntry)
120 : {
121 0 : if (!CacheStorageService::Self())
122 0 : return NS_ERROR_NOT_INITIALIZED;
123 :
124 : nsresult rv;
125 :
126 0 : nsCOMPtr<nsIURI> noRefURI;
127 0 : rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
128 0 : NS_ENSURE_SUCCESS(rv, rv);
129 :
130 0 : nsAutoCString asciiSpec;
131 0 : rv = noRefURI->GetAsciiSpec(asciiSpec);
132 0 : NS_ENSURE_SUCCESS(rv, rv);
133 :
134 0 : RefPtr<CacheEntryHandle> handle;
135 0 : rv = CacheStorageService::Self()->AddStorageEntry(
136 : this, asciiSpec, aIdExtension,
137 : true, // replace any existing one
138 0 : getter_AddRefs(handle));
139 0 : NS_ENSURE_SUCCESS(rv, rv);
140 :
141 : // Just open w/o callback, similar to nsICacheEntry.recreate().
142 0 : handle->Entry()->AsyncOpen(nullptr, OPEN_TRUNCATE);
143 :
144 : // Return a write handler, consumer is supposed to fill in the entry.
145 0 : RefPtr<CacheEntryHandle> writeHandle = handle->Entry()->NewWriteHandle();
146 0 : writeHandle.forget(aCacheEntry);
147 :
148 0 : return NS_OK;
149 : }
150 :
151 0 : NS_IMETHODIMP CacheStorage::Exists(nsIURI *aURI, const nsACString & aIdExtension,
152 : bool *aResult)
153 : {
154 0 : NS_ENSURE_ARG(aURI);
155 0 : NS_ENSURE_ARG(aResult);
156 :
157 0 : if (!CacheStorageService::Self())
158 0 : return NS_ERROR_NOT_INITIALIZED;
159 :
160 : nsresult rv;
161 :
162 0 : nsCOMPtr<nsIURI> noRefURI;
163 0 : rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
164 0 : NS_ENSURE_SUCCESS(rv, rv);
165 :
166 0 : nsAutoCString asciiSpec;
167 0 : rv = noRefURI->GetAsciiSpec(asciiSpec);
168 0 : NS_ENSURE_SUCCESS(rv, rv);
169 :
170 0 : return CacheStorageService::Self()->CheckStorageEntry(
171 0 : this, asciiSpec, aIdExtension, aResult);
172 : }
173 :
174 : NS_IMETHODIMP
175 5 : CacheStorage::GetCacheIndexEntryAttrs(nsIURI *aURI,
176 : const nsACString &aIdExtension,
177 : bool *aHasAltData,
178 : uint32_t *aSizeInKB)
179 : {
180 5 : NS_ENSURE_ARG(aURI);
181 5 : NS_ENSURE_ARG(aHasAltData);
182 5 : NS_ENSURE_ARG(aSizeInKB);
183 5 : if (!CacheStorageService::Self()) {
184 0 : return NS_ERROR_NOT_INITIALIZED;
185 : }
186 :
187 : nsresult rv;
188 :
189 10 : nsCOMPtr<nsIURI> noRefURI;
190 5 : rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
191 5 : NS_ENSURE_SUCCESS(rv, rv);
192 :
193 10 : nsAutoCString asciiSpec;
194 5 : rv = noRefURI->GetAsciiSpec(asciiSpec);
195 5 : NS_ENSURE_SUCCESS(rv, rv);
196 :
197 5 : return CacheStorageService::Self()->GetCacheIndexEntryAttrs(
198 5 : this, asciiSpec, aIdExtension, aHasAltData, aSizeInKB);
199 : }
200 :
201 1 : NS_IMETHODIMP CacheStorage::AsyncDoomURI(nsIURI *aURI, const nsACString & aIdExtension,
202 : nsICacheEntryDoomCallback* aCallback)
203 : {
204 1 : if (!CacheStorageService::Self())
205 0 : return NS_ERROR_NOT_INITIALIZED;
206 :
207 : nsresult rv;
208 :
209 2 : nsCOMPtr<nsIURI> noRefURI;
210 1 : rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
211 1 : NS_ENSURE_SUCCESS(rv, rv);
212 :
213 2 : nsAutoCString asciiSpec;
214 1 : rv = noRefURI->GetAsciiSpec(asciiSpec);
215 1 : NS_ENSURE_SUCCESS(rv, rv);
216 :
217 1 : rv = CacheStorageService::Self()->DoomStorageEntry(
218 1 : this, asciiSpec, aIdExtension, aCallback);
219 1 : NS_ENSURE_SUCCESS(rv, rv);
220 :
221 1 : return NS_OK;
222 : }
223 :
224 0 : NS_IMETHODIMP CacheStorage::AsyncEvictStorage(nsICacheEntryDoomCallback* aCallback)
225 : {
226 0 : if (!CacheStorageService::Self())
227 0 : return NS_ERROR_NOT_INITIALIZED;
228 :
229 0 : nsresult rv = CacheStorageService::Self()->DoomStorageEntries(
230 0 : this, aCallback);
231 0 : NS_ENSURE_SUCCESS(rv, rv);
232 :
233 0 : return NS_OK;
234 : }
235 :
236 0 : NS_IMETHODIMP CacheStorage::AsyncVisitStorage(nsICacheStorageVisitor* aVisitor,
237 : bool aVisitEntries)
238 : {
239 0 : LOG(("CacheStorage::AsyncVisitStorage [this=%p, cb=%p, disk=%d]", this, aVisitor, (bool)mWriteToDisk));
240 0 : if (!CacheStorageService::Self())
241 0 : return NS_ERROR_NOT_INITIALIZED;
242 :
243 0 : nsresult rv = CacheStorageService::Self()->WalkStorageEntries(
244 0 : this, aVisitEntries, aVisitor);
245 0 : NS_ENSURE_SUCCESS(rv, rv);
246 :
247 0 : return NS_OK;
248 : }
249 :
250 : // Internal
251 :
252 0 : nsresult CacheStorage::ChooseApplicationCache(nsIURI* aURI,
253 : nsIApplicationCache** aCache)
254 : {
255 : nsresult rv;
256 :
257 : nsCOMPtr<nsIApplicationCacheService> appCacheService =
258 0 : do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
259 0 : NS_ENSURE_SUCCESS(rv, rv);
260 :
261 0 : nsAutoCString cacheKey;
262 0 : rv = aURI->GetAsciiSpec(cacheKey);
263 0 : NS_ENSURE_SUCCESS(rv, rv);
264 :
265 0 : rv = appCacheService->ChooseApplicationCache(cacheKey, LoadInfo(), aCache);
266 0 : NS_ENSURE_SUCCESS(rv, rv);
267 :
268 0 : return NS_OK;
269 : }
270 :
271 : } // namespace net
272 : } // namespace mozilla
|