/src/mozilla-central/netwerk/cache2/OldWrappers.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Stuff to link the old imp to the new api - will go away! |
2 | | |
3 | | #include "CacheLog.h" |
4 | | #include "OldWrappers.h" |
5 | | #include "CacheStorage.h" |
6 | | #include "CacheStorageService.h" |
7 | | #include "LoadContextInfo.h" |
8 | | #include "nsCacheService.h" |
9 | | |
10 | | #include "nsIURI.h" |
11 | | #include "nsICacheSession.h" |
12 | | #include "nsIApplicationCache.h" |
13 | | #include "nsIApplicationCacheService.h" |
14 | | #include "nsIStreamTransportService.h" |
15 | | #include "nsIFile.h" |
16 | | #include "nsICacheEntryDoomCallback.h" |
17 | | #include "nsICacheListener.h" |
18 | | #include "nsICacheStorageVisitor.h" |
19 | | |
20 | | #include "nsServiceManagerUtils.h" |
21 | | #include "nsNetCID.h" |
22 | | #include "nsNetUtil.h" |
23 | | #include "nsProxyRelease.h" |
24 | | #include "mozilla/IntegerPrintfMacros.h" |
25 | | #include "mozilla/Telemetry.h" |
26 | | |
27 | | static NS_DEFINE_CID(kStreamTransportServiceCID, |
28 | | NS_STREAMTRANSPORTSERVICE_CID); |
29 | | |
30 | | static uint32_t const CHECK_MULTITHREADED = nsICacheStorage::CHECK_MULTITHREADED; |
31 | | |
32 | | namespace mozilla { |
33 | | namespace net { |
34 | | |
35 | | namespace { |
36 | | |
37 | | // Fires the doom callback back on the main thread |
38 | | // after the cache I/O thread is looped. |
39 | | |
40 | | class DoomCallbackSynchronizer : public Runnable |
41 | | { |
42 | | public: |
43 | | explicit DoomCallbackSynchronizer(nsICacheEntryDoomCallback* cb) |
44 | | : Runnable("net::DoomCallbackSynchronizer") |
45 | | , mCB(cb) |
46 | 0 | { |
47 | 0 | } |
48 | | nsresult Dispatch(); |
49 | | |
50 | | private: |
51 | 0 | virtual ~DoomCallbackSynchronizer() = default; |
52 | | |
53 | | NS_DECL_NSIRUNNABLE |
54 | | nsCOMPtr<nsICacheEntryDoomCallback> mCB; |
55 | | }; |
56 | | |
57 | | nsresult DoomCallbackSynchronizer::Dispatch() |
58 | 0 | { |
59 | 0 | nsresult rv; |
60 | 0 |
|
61 | 0 | nsCOMPtr<nsICacheService> serv = |
62 | 0 | do_GetService(NS_CACHESERVICE_CONTRACTID, &rv); |
63 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
64 | 0 |
|
65 | 0 | nsCOMPtr<nsIEventTarget> eventTarget; |
66 | 0 | rv = serv->GetCacheIOTarget(getter_AddRefs(eventTarget)); |
67 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
68 | 0 |
|
69 | 0 | rv = eventTarget->Dispatch(this, NS_DISPATCH_NORMAL); |
70 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
71 | 0 |
|
72 | 0 | return NS_OK; |
73 | 0 | } |
74 | | |
75 | | NS_IMETHODIMP DoomCallbackSynchronizer::Run() |
76 | 0 | { |
77 | 0 | if (!NS_IsMainThread()) { |
78 | 0 | NS_DispatchToMainThread(this); |
79 | 0 | } |
80 | 0 | else { |
81 | 0 | if (mCB) |
82 | 0 | mCB->OnCacheEntryDoomed(NS_OK); |
83 | 0 | } |
84 | 0 | return NS_OK; |
85 | 0 | } |
86 | | |
87 | | // Receives doom callback from the old API and forwards to the new API |
88 | | |
89 | | class DoomCallbackWrapper : public nsICacheListener |
90 | | { |
91 | | NS_DECL_THREADSAFE_ISUPPORTS |
92 | | NS_DECL_NSICACHELISTENER |
93 | | |
94 | | explicit DoomCallbackWrapper(nsICacheEntryDoomCallback* cb) : mCB(cb) |
95 | 0 | { |
96 | 0 | } |
97 | | |
98 | | private: |
99 | 0 | virtual ~DoomCallbackWrapper() = default; |
100 | | |
101 | | nsCOMPtr<nsICacheEntryDoomCallback> mCB; |
102 | | }; |
103 | | |
104 | | NS_IMPL_ISUPPORTS(DoomCallbackWrapper, nsICacheListener); |
105 | | |
106 | | NS_IMETHODIMP DoomCallbackWrapper::OnCacheEntryAvailable(nsICacheEntryDescriptor *descriptor, |
107 | | nsCacheAccessMode accessGranted, |
108 | | nsresult status) |
109 | 0 | { |
110 | 0 | return NS_OK; |
111 | 0 | } |
112 | | |
113 | | NS_IMETHODIMP DoomCallbackWrapper::OnCacheEntryDoomed(nsresult status) |
114 | 0 | { |
115 | 0 | if (!mCB) |
116 | 0 | return NS_ERROR_NULL_POINTER; |
117 | 0 | |
118 | 0 | mCB->OnCacheEntryDoomed(status); |
119 | 0 | mCB = nullptr; |
120 | 0 | return NS_OK; |
121 | 0 | } |
122 | | |
123 | | } // namespace |
124 | | |
125 | | // _OldVisitCallbackWrapper |
126 | | // Receives visit callbacks from the old API and forwards it to the new API |
127 | | |
128 | | NS_IMPL_ISUPPORTS(_OldVisitCallbackWrapper, nsICacheVisitor) |
129 | | |
130 | | _OldVisitCallbackWrapper::~_OldVisitCallbackWrapper() |
131 | 0 | { |
132 | 0 | if (!mHit) { |
133 | 0 | // The device has not been found, to not break the chain, simulate |
134 | 0 | // storage info callback. |
135 | 0 | mCB->OnCacheStorageInfo(0, 0, 0, nullptr); |
136 | 0 | } |
137 | 0 |
|
138 | 0 | if (mVisitEntries) { |
139 | 0 | mCB->OnCacheEntryVisitCompleted(); |
140 | 0 | } |
141 | 0 | } |
142 | | |
143 | | NS_IMETHODIMP _OldVisitCallbackWrapper::VisitDevice(const char * deviceID, |
144 | | nsICacheDeviceInfo *deviceInfo, |
145 | | bool *_retval) |
146 | 0 | { |
147 | 0 | if (!mCB) |
148 | 0 | return NS_ERROR_NULL_POINTER; |
149 | 0 | |
150 | 0 | *_retval = false; |
151 | 0 | if (strcmp(deviceID, mDeviceID)) { |
152 | 0 | // Not the device we want to visit |
153 | 0 | return NS_OK; |
154 | 0 | } |
155 | 0 | |
156 | 0 | mHit = true; |
157 | 0 |
|
158 | 0 | nsresult rv; |
159 | 0 |
|
160 | 0 | uint32_t capacity; |
161 | 0 | rv = deviceInfo->GetMaximumSize(&capacity); |
162 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
163 | 0 |
|
164 | 0 | nsCOMPtr<nsIFile> dir; |
165 | 0 | if (!strcmp(mDeviceID, "disk")) { |
166 | 0 | nsCacheService::GetDiskCacheDirectory(getter_AddRefs(dir)); |
167 | 0 | } else if (!strcmp(mDeviceID, "offline")) { |
168 | 0 | nsCacheService::GetAppCacheDirectory(getter_AddRefs(dir)); |
169 | 0 | } |
170 | 0 |
|
171 | 0 | if (mLoadInfo->IsAnonymous()) { |
172 | 0 | // Anonymous visiting reports 0, 0 since we cannot count that |
173 | 0 | // early the number of anon entries. |
174 | 0 | mCB->OnCacheStorageInfo(0, 0, capacity, dir); |
175 | 0 | } else { |
176 | 0 | // Non-anon visitor counts all non-anon + ALL ANON entries, |
177 | 0 | // there is no way to determine the number of entries when |
178 | 0 | // using the old cache APIs - there is no concept of anonymous |
179 | 0 | // storage. |
180 | 0 | uint32_t entryCount; |
181 | 0 | rv = deviceInfo->GetEntryCount(&entryCount); |
182 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
183 | 0 |
|
184 | 0 | uint32_t totalSize; |
185 | 0 | rv = deviceInfo->GetTotalSize(&totalSize); |
186 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
187 | 0 |
|
188 | 0 | mCB->OnCacheStorageInfo(entryCount, totalSize, capacity, dir); |
189 | 0 | } |
190 | 0 |
|
191 | 0 | *_retval = mVisitEntries; |
192 | 0 | return NS_OK; |
193 | 0 | } |
194 | | |
195 | | NS_IMETHODIMP _OldVisitCallbackWrapper::VisitEntry(const char * deviceID, |
196 | | nsICacheEntryInfo *entryInfo, |
197 | | bool *_retval) |
198 | 0 | { |
199 | 0 | MOZ_ASSERT(!strcmp(deviceID, mDeviceID)); |
200 | 0 |
|
201 | 0 | nsresult rv; |
202 | 0 |
|
203 | 0 | *_retval = true; |
204 | 0 |
|
205 | 0 | // Read all informative properties from the entry. |
206 | 0 | nsAutoCString clientId; |
207 | 0 | rv = entryInfo->GetClientID(clientId); |
208 | 0 | if (NS_FAILED(rv)) |
209 | 0 | return NS_OK; |
210 | 0 | |
211 | 0 | if (mLoadInfo->IsPrivate() != |
212 | 0 | StringBeginsWith(clientId, NS_LITERAL_CSTRING("HTTP-memory-only-PB"))) { |
213 | 0 | return NS_OK; |
214 | 0 | } |
215 | 0 | |
216 | 0 | nsAutoCString cacheKey, enhanceId; |
217 | 0 | rv = entryInfo->GetKey(cacheKey); |
218 | 0 | if (NS_FAILED(rv)) |
219 | 0 | return NS_OK; |
220 | 0 | |
221 | 0 | if (StringBeginsWith(cacheKey, NS_LITERAL_CSTRING("anon&"))) { |
222 | 0 | if (!mLoadInfo->IsAnonymous()) |
223 | 0 | return NS_OK; |
224 | 0 | |
225 | 0 | cacheKey = Substring(cacheKey, 5, cacheKey.Length()); |
226 | 0 | } else if (mLoadInfo->IsAnonymous()) { |
227 | 0 | return NS_OK; |
228 | 0 | } |
229 | 0 | |
230 | 0 | if (StringBeginsWith(cacheKey, NS_LITERAL_CSTRING("id="))) { |
231 | 0 | int32_t uriSpecEnd = cacheKey.Find("&uri="); |
232 | 0 | if (uriSpecEnd == kNotFound) // Corrupted, ignore |
233 | 0 | return NS_OK; |
234 | 0 | |
235 | 0 | enhanceId = Substring(cacheKey, 3, uriSpecEnd - 3); |
236 | 0 | cacheKey = Substring(cacheKey, uriSpecEnd + 1, cacheKey.Length()); |
237 | 0 | } |
238 | 0 |
|
239 | 0 | if (StringBeginsWith(cacheKey, NS_LITERAL_CSTRING("uri="))) { |
240 | 0 | cacheKey = Substring(cacheKey, 4, cacheKey.Length()); |
241 | 0 | } |
242 | 0 |
|
243 | 0 | nsCOMPtr<nsIURI> uri; |
244 | 0 | // cacheKey is strip of any prefixes |
245 | 0 | rv = NS_NewURI(getter_AddRefs(uri), cacheKey); |
246 | 0 | if (NS_FAILED(rv)) |
247 | 0 | return NS_OK; |
248 | 0 | |
249 | 0 | uint32_t dataSize; |
250 | 0 | if (NS_FAILED(entryInfo->GetDataSize(&dataSize))) |
251 | 0 | dataSize = 0; |
252 | 0 | int32_t fetchCount; |
253 | 0 | if (NS_FAILED(entryInfo->GetFetchCount(&fetchCount))) |
254 | 0 | fetchCount = 0; |
255 | 0 | uint32_t expirationTime; |
256 | 0 | if (NS_FAILED(entryInfo->GetExpirationTime(&expirationTime))) |
257 | 0 | expirationTime = 0; |
258 | 0 | uint32_t lastModified; |
259 | 0 | if (NS_FAILED(entryInfo->GetLastModified(&lastModified))) |
260 | 0 | lastModified = 0; |
261 | 0 |
|
262 | 0 | // Send them to the consumer. |
263 | 0 | rv = mCB->OnCacheEntryInfo( |
264 | 0 | uri, enhanceId, (int64_t)dataSize, fetchCount, lastModified, |
265 | 0 | expirationTime, false, mLoadInfo); |
266 | 0 |
|
267 | 0 | *_retval = NS_SUCCEEDED(rv); |
268 | 0 | return NS_OK; |
269 | 0 | } |
270 | | |
271 | | // _OldGetDiskConsumption |
272 | | |
273 | | //static |
274 | | nsresult _OldGetDiskConsumption::Get(nsICacheStorageConsumptionObserver* aCallback) |
275 | 0 | { |
276 | 0 | nsresult rv; |
277 | 0 |
|
278 | 0 | nsCOMPtr<nsICacheService> serv = |
279 | 0 | do_GetService(NS_CACHESERVICE_CONTRACTID, &rv); |
280 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
281 | 0 |
|
282 | 0 | RefPtr<_OldGetDiskConsumption> cb = new _OldGetDiskConsumption(aCallback); |
283 | 0 |
|
284 | 0 | // _OldGetDiskConsumption stores the found size value, but until dispatched |
285 | 0 | // to the main thread it doesn't call on the consupmtion observer. See bellow. |
286 | 0 | rv = serv->VisitEntries(cb); |
287 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
288 | 0 |
|
289 | 0 | // We are called from CacheStorageService::AsyncGetDiskConsumption whose IDL |
290 | 0 | // documentation claims the callback is always delievered asynchronously |
291 | 0 | // back to the main thread. Despite we know the result synchronosusly when |
292 | 0 | // querying the old cache, we need to stand the word and dispatch the result |
293 | 0 | // to the main thread asynchronously. Hence the dispatch here. |
294 | 0 | return NS_DispatchToMainThread(cb); |
295 | 0 | } |
296 | | |
297 | | NS_IMPL_ISUPPORTS_INHERITED(_OldGetDiskConsumption, |
298 | | Runnable, |
299 | | nsICacheVisitor) |
300 | | |
301 | | _OldGetDiskConsumption::_OldGetDiskConsumption( |
302 | | nsICacheStorageConsumptionObserver* aCallback) |
303 | | : Runnable("net::_OldGetDiskConsumption") |
304 | | , mCallback(aCallback) |
305 | | , mSize(0) |
306 | 0 | { |
307 | 0 | } |
308 | | |
309 | | NS_IMETHODIMP |
310 | | _OldGetDiskConsumption::Run() |
311 | 0 | { |
312 | 0 | mCallback->OnNetworkCacheDiskConsumption(mSize); |
313 | 0 | return NS_OK; |
314 | 0 | } |
315 | | |
316 | | NS_IMETHODIMP |
317 | | _OldGetDiskConsumption::VisitDevice(const char * deviceID, |
318 | | nsICacheDeviceInfo *deviceInfo, |
319 | | bool *_retval) |
320 | 0 | { |
321 | 0 | if (!strcmp(deviceID, "disk")) { |
322 | 0 | uint32_t size; |
323 | 0 | nsresult rv = deviceInfo->GetTotalSize(&size); |
324 | 0 | if (NS_SUCCEEDED(rv)) |
325 | 0 | mSize = (int64_t)size; |
326 | 0 | } |
327 | 0 |
|
328 | 0 | *_retval = false; |
329 | 0 | return NS_OK; |
330 | 0 | } |
331 | | |
332 | | NS_IMETHODIMP |
333 | | _OldGetDiskConsumption::VisitEntry(const char * deviceID, |
334 | | nsICacheEntryInfo *entryInfo, |
335 | | bool *_retval) |
336 | 0 | { |
337 | 0 | MOZ_CRASH("Unexpected"); |
338 | 0 | return NS_OK; |
339 | 0 | } |
340 | | |
341 | | |
342 | | // _OldCacheEntryWrapper |
343 | | |
344 | | _OldCacheEntryWrapper::_OldCacheEntryWrapper(nsICacheEntryDescriptor* desc) |
345 | | : mOldDesc(desc), mOldInfo(desc), mCacheEntryId(CacheEntry::GetNextId()) |
346 | 0 | { |
347 | 0 | LOG(("Creating _OldCacheEntryWrapper %p for descriptor %p", this, desc)); |
348 | 0 | } |
349 | | |
350 | | _OldCacheEntryWrapper::_OldCacheEntryWrapper(nsICacheEntryInfo* info) |
351 | | : mOldDesc(nullptr), mOldInfo(info), mCacheEntryId(CacheEntry::GetNextId()) |
352 | 0 | { |
353 | 0 | LOG(("Creating _OldCacheEntryWrapper %p for info %p", this, info)); |
354 | 0 | } |
355 | | |
356 | | _OldCacheEntryWrapper::~_OldCacheEntryWrapper() |
357 | 0 | { |
358 | 0 | LOG(("Destroying _OldCacheEntryWrapper %p for descriptor %p", this, mOldInfo.get())); |
359 | 0 | } |
360 | | |
361 | | NS_IMETHODIMP _OldCacheEntryWrapper::GetIsForcedValid(bool *aIsForcedValid) |
362 | 0 | { |
363 | 0 | // Unused stub |
364 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
365 | 0 | } |
366 | | |
367 | | NS_IMETHODIMP _OldCacheEntryWrapper::ForceValidFor(uint32_t aSecondsToTheFuture) |
368 | 0 | { |
369 | 0 | // Unused stub |
370 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
371 | 0 | } |
372 | | |
373 | | NS_IMPL_ISUPPORTS(_OldCacheEntryWrapper, nsICacheEntry) |
374 | | |
375 | | NS_IMETHODIMP _OldCacheEntryWrapper::AsyncDoom(nsICacheEntryDoomCallback* listener) |
376 | 0 | { |
377 | 0 | RefPtr<DoomCallbackWrapper> cb = listener |
378 | 0 | ? new DoomCallbackWrapper(listener) |
379 | 0 | : nullptr; |
380 | 0 | return AsyncDoom(cb); |
381 | 0 | } |
382 | | |
383 | | NS_IMETHODIMP _OldCacheEntryWrapper::GetDataSize(int64_t *aSize) |
384 | 0 | { |
385 | 0 | uint32_t size; |
386 | 0 | nsresult rv = GetDataSize(&size); |
387 | 0 | if (NS_FAILED(rv)) |
388 | 0 | return rv; |
389 | 0 | |
390 | 0 | *aSize = size; |
391 | 0 | return NS_OK; |
392 | 0 | } |
393 | | |
394 | | NS_IMETHODIMP _OldCacheEntryWrapper::GetAltDataSize(int64_t *aSize) |
395 | 0 | { |
396 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
397 | 0 | } |
398 | | |
399 | | NS_IMETHODIMP _OldCacheEntryWrapper::GetPersistent(bool *aPersistToDisk) |
400 | 0 | { |
401 | 0 | if (!mOldDesc) { |
402 | 0 | return NS_ERROR_NULL_POINTER; |
403 | 0 | } |
404 | 0 | |
405 | 0 | nsresult rv; |
406 | 0 |
|
407 | 0 | nsCacheStoragePolicy policy; |
408 | 0 | rv = mOldDesc->GetStoragePolicy(&policy); |
409 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
410 | 0 |
|
411 | 0 | *aPersistToDisk = policy != nsICache::STORE_IN_MEMORY; |
412 | 0 |
|
413 | 0 | return NS_OK; |
414 | 0 | } |
415 | | |
416 | | NS_IMETHODIMP _OldCacheEntryWrapper::Recreate(bool aMemoryOnly, |
417 | | nsICacheEntry** aResult) |
418 | 0 | { |
419 | 0 | NS_ENSURE_TRUE(mOldDesc, NS_ERROR_NOT_AVAILABLE); |
420 | 0 |
|
421 | 0 | nsCacheAccessMode mode; |
422 | 0 | nsresult rv = mOldDesc->GetAccessGranted(&mode); |
423 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
424 | 0 |
|
425 | 0 | if (!(mode & nsICache::ACCESS_WRITE)) |
426 | 0 | return NS_ERROR_NOT_AVAILABLE; |
427 | 0 | |
428 | 0 | LOG(("_OldCacheEntryWrapper::Recreate [this=%p]", this)); |
429 | 0 |
|
430 | 0 | if (aMemoryOnly) |
431 | 0 | mOldDesc->SetStoragePolicy(nsICache::STORE_IN_MEMORY); |
432 | 0 |
|
433 | 0 | nsCOMPtr<nsICacheEntry> self(this); |
434 | 0 | self.forget(aResult); |
435 | 0 | return NS_OK; |
436 | 0 | } |
437 | | |
438 | | NS_IMETHODIMP _OldCacheEntryWrapper::OpenInputStream(int64_t offset, |
439 | | nsIInputStream * *_retval) |
440 | 0 | { |
441 | 0 | if (offset > PR_UINT32_MAX) |
442 | 0 | return NS_ERROR_INVALID_ARG; |
443 | 0 | |
444 | 0 | return OpenInputStream(uint32_t(offset), _retval); |
445 | 0 | } |
446 | | NS_IMETHODIMP _OldCacheEntryWrapper::OpenOutputStream(int64_t offset, |
447 | | int64_t predictedSize, |
448 | | nsIOutputStream * *_retval) |
449 | 0 | { |
450 | 0 | if (offset > PR_UINT32_MAX) |
451 | 0 | return NS_ERROR_INVALID_ARG; |
452 | 0 | |
453 | 0 | return OpenOutputStream(uint32_t(offset), _retval); |
454 | 0 | } |
455 | | |
456 | | NS_IMETHODIMP _OldCacheEntryWrapper::MaybeMarkValid() |
457 | 0 | { |
458 | 0 | LOG(("_OldCacheEntryWrapper::MaybeMarkValid [this=%p]", this)); |
459 | 0 |
|
460 | 0 | NS_ENSURE_TRUE(mOldDesc, NS_ERROR_NULL_POINTER); |
461 | 0 |
|
462 | 0 | nsCacheAccessMode mode; |
463 | 0 | nsresult rv = mOldDesc->GetAccessGranted(&mode); |
464 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
465 | 0 |
|
466 | 0 | if (mode & nsICache::ACCESS_WRITE) { |
467 | 0 | LOG(("Marking cache entry valid [entry=%p, descr=%p]", this, mOldDesc)); |
468 | 0 | return mOldDesc->MarkValid(); |
469 | 0 | } |
470 | 0 |
|
471 | 0 | LOG(("Not marking read-only cache entry valid [entry=%p, descr=%p]", this, mOldDesc)); |
472 | 0 | return NS_OK; |
473 | 0 | } |
474 | | |
475 | | NS_IMETHODIMP _OldCacheEntryWrapper::HasWriteAccess(bool aWriteAllowed_unused, bool *aWriteAccess) |
476 | 0 | { |
477 | 0 | NS_ENSURE_TRUE(mOldDesc, NS_ERROR_NULL_POINTER); |
478 | 0 | NS_ENSURE_ARG(aWriteAccess); |
479 | 0 |
|
480 | 0 | nsCacheAccessMode mode; |
481 | 0 | nsresult rv = mOldDesc->GetAccessGranted(&mode); |
482 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
483 | 0 |
|
484 | 0 | *aWriteAccess = !!(mode & nsICache::ACCESS_WRITE); |
485 | 0 |
|
486 | 0 | LOG(("_OldCacheEntryWrapper::HasWriteAccess [this=%p, write-access=%d]", this, *aWriteAccess)); |
487 | 0 |
|
488 | 0 | return NS_OK; |
489 | 0 | } |
490 | | |
491 | | namespace { |
492 | | |
493 | | class MetaDataVisitorWrapper : public nsICacheMetaDataVisitor |
494 | | { |
495 | 0 | virtual ~MetaDataVisitorWrapper() = default; |
496 | | |
497 | | NS_DECL_ISUPPORTS |
498 | | NS_DECL_NSICACHEMETADATAVISITOR |
499 | 0 | explicit MetaDataVisitorWrapper(nsICacheEntryMetaDataVisitor* cb) : mCB(cb) {} |
500 | | nsCOMPtr<nsICacheEntryMetaDataVisitor> mCB; |
501 | | }; |
502 | | |
503 | | NS_IMPL_ISUPPORTS(MetaDataVisitorWrapper, nsICacheMetaDataVisitor) |
504 | | |
505 | | NS_IMETHODIMP |
506 | | MetaDataVisitorWrapper::VisitMetaDataElement(char const * key, |
507 | | char const * value, |
508 | | bool *goon) |
509 | 0 | { |
510 | 0 | *goon = true; |
511 | 0 | return mCB->OnMetaDataElement(key, value); |
512 | 0 | } |
513 | | |
514 | | } // namespace |
515 | | |
516 | | NS_IMETHODIMP _OldCacheEntryWrapper::VisitMetaData(nsICacheEntryMetaDataVisitor* cb) |
517 | 0 | { |
518 | 0 | RefPtr<MetaDataVisitorWrapper> w = new MetaDataVisitorWrapper(cb); |
519 | 0 | return mOldDesc->VisitMetaData(w); |
520 | 0 | } |
521 | | |
522 | | namespace { |
523 | | |
524 | | nsresult |
525 | | GetCacheSessionNameForStoragePolicy( |
526 | | const nsACString& scheme, |
527 | | nsCacheStoragePolicy storagePolicy, |
528 | | bool isPrivate, |
529 | | OriginAttributes const *originAttribs, |
530 | | nsACString& sessionName) |
531 | 0 | { |
532 | 0 | MOZ_ASSERT(!isPrivate || storagePolicy == nsICache::STORE_IN_MEMORY); |
533 | 0 |
|
534 | 0 | // HTTP |
535 | 0 | if (scheme.EqualsLiteral("http") || |
536 | 0 | scheme.EqualsLiteral("https")) { |
537 | 0 | switch (storagePolicy) { |
538 | 0 | case nsICache::STORE_IN_MEMORY: |
539 | 0 | if (isPrivate) |
540 | 0 | sessionName.AssignLiteral("HTTP-memory-only-PB"); |
541 | 0 | else |
542 | 0 | sessionName.AssignLiteral("HTTP-memory-only"); |
543 | 0 | break; |
544 | 0 | case nsICache::STORE_OFFLINE: |
545 | 0 | // XXX This is actually never used, only added to prevent |
546 | 0 | // any compatibility damage. |
547 | 0 | sessionName.AssignLiteral("HTTP-offline"); |
548 | 0 | break; |
549 | 0 | default: |
550 | 0 | sessionName.AssignLiteral("HTTP"); |
551 | 0 | break; |
552 | 0 | } |
553 | 0 | } |
554 | 0 | // WYCIWYG |
555 | 0 | else if (scheme.EqualsLiteral("wyciwyg")) { |
556 | 0 | if (isPrivate) |
557 | 0 | sessionName.AssignLiteral("wyciwyg-private"); |
558 | 0 | else |
559 | 0 | sessionName.AssignLiteral("wyciwyg"); |
560 | 0 | } |
561 | 0 | // FTP |
562 | 0 | else if (scheme.EqualsLiteral("ftp")) { |
563 | 0 | if (isPrivate) |
564 | 0 | sessionName.AssignLiteral("FTP-private"); |
565 | 0 | else |
566 | 0 | sessionName.AssignLiteral("FTP"); |
567 | 0 | } |
568 | 0 | // all remaining URL scheme |
569 | 0 | else { |
570 | 0 | // Since with the new API a consumer cannot specify its own session name |
571 | 0 | // and partitioning of the cache is handled stricly only by the cache |
572 | 0 | // back-end internally, we will use a separate session name to pretend |
573 | 0 | // functionality of the new API wrapping the Darin's cache for all other |
574 | 0 | // URL schemes. |
575 | 0 | // Deliberately omitting |anonymous| since other session types don't |
576 | 0 | // recognize it too. |
577 | 0 | sessionName.AssignLiteral("other"); |
578 | 0 | if (isPrivate) |
579 | 0 | sessionName.AppendLiteral("-private"); |
580 | 0 | } |
581 | 0 |
|
582 | 0 | nsAutoCString suffix; |
583 | 0 | originAttribs->CreateSuffix(suffix); |
584 | 0 | sessionName.Append(suffix); |
585 | 0 |
|
586 | 0 | return NS_OK; |
587 | 0 | } |
588 | | |
589 | | nsresult |
590 | | GetCacheSession(const nsACString& aScheme, |
591 | | bool aWriteToDisk, |
592 | | nsILoadContextInfo* aLoadInfo, |
593 | | nsIApplicationCache* aAppCache, |
594 | | nsICacheSession** _result) |
595 | 0 | { |
596 | 0 | nsresult rv; |
597 | 0 |
|
598 | 0 | nsCacheStoragePolicy storagePolicy; |
599 | 0 | if (aAppCache) |
600 | 0 | storagePolicy = nsICache::STORE_OFFLINE; |
601 | 0 | else if (!aWriteToDisk || aLoadInfo->IsPrivate()) |
602 | 0 | storagePolicy = nsICache::STORE_IN_MEMORY; |
603 | 0 | else |
604 | 0 | storagePolicy = nsICache::STORE_ANYWHERE; |
605 | 0 |
|
606 | 0 | nsAutoCString clientId; |
607 | 0 | if (aAppCache) { |
608 | 0 | aAppCache->GetClientID(clientId); |
609 | 0 | } |
610 | 0 | else { |
611 | 0 | rv = GetCacheSessionNameForStoragePolicy( |
612 | 0 | aScheme, |
613 | 0 | storagePolicy, |
614 | 0 | aLoadInfo->IsPrivate(), |
615 | 0 | aLoadInfo->OriginAttributesPtr(), |
616 | 0 | clientId); |
617 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
618 | 0 | } |
619 | 0 |
|
620 | 0 | LOG((" GetCacheSession for client=%s, policy=%d", clientId.get(), storagePolicy)); |
621 | 0 |
|
622 | 0 | nsCOMPtr<nsICacheService> serv = |
623 | 0 | do_GetService(NS_CACHESERVICE_CONTRACTID, &rv); |
624 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
625 | 0 |
|
626 | 0 | nsCOMPtr<nsICacheSession> session; |
627 | 0 | rv = nsCacheService::GlobalInstance()->CreateSessionInternal(clientId.get(), |
628 | 0 | storagePolicy, |
629 | 0 | nsICache::STREAM_BASED, |
630 | 0 | getter_AddRefs(session)); |
631 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
632 | 0 |
|
633 | 0 | rv = session->SetIsPrivate(aLoadInfo->IsPrivate()); |
634 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
635 | 0 |
|
636 | 0 | rv = session->SetDoomEntriesIfExpired(false); |
637 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
638 | 0 |
|
639 | 0 | if (aAppCache) { |
640 | 0 | nsCOMPtr<nsIFile> profileDirectory; |
641 | 0 | aAppCache->GetProfileDirectory(getter_AddRefs(profileDirectory)); |
642 | 0 | if (profileDirectory) |
643 | 0 | rv = session->SetProfileDirectory(profileDirectory); |
644 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
645 | 0 | } |
646 | 0 |
|
647 | 0 | session.forget(_result); |
648 | 0 | return NS_OK; |
649 | 0 | } |
650 | | |
651 | | } // namespace |
652 | | |
653 | | |
654 | | NS_IMPL_ISUPPORTS_INHERITED(_OldCacheLoad, Runnable, nsICacheListener) |
655 | | |
656 | | _OldCacheLoad::_OldCacheLoad(const nsACString& aScheme, |
657 | | const nsACString& aCacheKey, |
658 | | nsICacheEntryOpenCallback* aCallback, |
659 | | nsIApplicationCache* aAppCache, |
660 | | nsILoadContextInfo* aLoadInfo, |
661 | | bool aWriteToDisk, |
662 | | uint32_t aFlags) |
663 | | : Runnable("net::_OldCacheLoad") |
664 | | , mScheme(aScheme) |
665 | | , mCacheKey(aCacheKey) |
666 | | , mCallback(aCallback) |
667 | | , mLoadInfo(GetLoadContextInfo(aLoadInfo)) |
668 | | , mFlags(aFlags) |
669 | | , mWriteToDisk(aWriteToDisk) |
670 | | , mNew(true) |
671 | | , mOpening(true) |
672 | | , mSync(false) |
673 | | , mStatus(NS_ERROR_UNEXPECTED) |
674 | | , mRunCount(0) |
675 | | , mAppCache(aAppCache) |
676 | 0 | { |
677 | 0 | } |
678 | | |
679 | | _OldCacheLoad::~_OldCacheLoad() |
680 | 0 | { |
681 | 0 | ProxyReleaseMainThread( |
682 | 0 | "_OldCacheLoad::mAppCache", mAppCache); |
683 | 0 | } |
684 | | |
685 | | nsresult _OldCacheLoad::Start() |
686 | 0 | { |
687 | 0 | LOG(("_OldCacheLoad::Start [this=%p, key=%s]", this, mCacheKey.get())); |
688 | 0 |
|
689 | 0 | mLoadStart = mozilla::TimeStamp::Now(); |
690 | 0 |
|
691 | 0 | nsresult rv; |
692 | 0 |
|
693 | 0 | // Consumers that can invoke this code as first and off the main thread |
694 | 0 | // are responsible for initiating these two services on the main thread. |
695 | 0 | // Currently this is only nsWyciwygChannel. |
696 | 0 |
|
697 | 0 | // XXX: Start the cache service; otherwise DispatchToCacheIOThread will |
698 | 0 | // fail. |
699 | 0 | nsCOMPtr<nsICacheService> service = |
700 | 0 | do_GetService(NS_CACHESERVICE_CONTRACTID, &rv); |
701 | 0 |
|
702 | 0 | // Ensure the stream transport service gets initialized on the main thread |
703 | 0 | if (NS_SUCCEEDED(rv) && NS_IsMainThread()) { |
704 | 0 | nsCOMPtr<nsIStreamTransportService> sts = |
705 | 0 | do_GetService(kStreamTransportServiceCID, &rv); |
706 | 0 | } |
707 | 0 |
|
708 | 0 | if (NS_SUCCEEDED(rv)) { |
709 | 0 | rv = service->GetCacheIOTarget(getter_AddRefs(mCacheThread)); |
710 | 0 | } |
711 | 0 |
|
712 | 0 | if (NS_SUCCEEDED(rv)) { |
713 | 0 | bool onCacheTarget; |
714 | 0 | rv = mCacheThread->IsOnCurrentThread(&onCacheTarget); |
715 | 0 | if (NS_SUCCEEDED(rv) && onCacheTarget) { |
716 | 0 | mSync = true; |
717 | 0 | } |
718 | 0 | } |
719 | 0 |
|
720 | 0 | if (NS_SUCCEEDED(rv)) { |
721 | 0 | if (mSync) { |
722 | 0 | rv = Run(); |
723 | 0 | } |
724 | 0 | else { |
725 | 0 | rv = mCacheThread->Dispatch(this, NS_DISPATCH_NORMAL); |
726 | 0 | } |
727 | 0 | } |
728 | 0 |
|
729 | 0 | return rv; |
730 | 0 | } |
731 | | |
732 | | NS_IMETHODIMP |
733 | | _OldCacheLoad::Run() |
734 | 0 | { |
735 | 0 | LOG(("_OldCacheLoad::Run [this=%p, key=%s, cb=%p]", this, mCacheKey.get(), mCallback.get())); |
736 | 0 |
|
737 | 0 | nsresult rv; |
738 | 0 |
|
739 | 0 | if (mOpening) { |
740 | 0 | mOpening = false; |
741 | 0 | nsCOMPtr<nsICacheSession> session; |
742 | 0 | rv = GetCacheSession(mScheme, mWriteToDisk, mLoadInfo, mAppCache, |
743 | 0 | getter_AddRefs(session)); |
744 | 0 | if (NS_SUCCEEDED(rv)) { |
745 | 0 | // AsyncOpenCacheEntry isn't really async when its called on the |
746 | 0 | // cache service thread. |
747 | 0 |
|
748 | 0 | nsCacheAccessMode cacheAccess; |
749 | 0 | if (mFlags & nsICacheStorage::OPEN_TRUNCATE) |
750 | 0 | cacheAccess = nsICache::ACCESS_WRITE; |
751 | 0 | else if ((mFlags & nsICacheStorage::OPEN_READONLY) || mAppCache) |
752 | 0 | cacheAccess = nsICache::ACCESS_READ; |
753 | 0 | else |
754 | 0 | cacheAccess = nsICache::ACCESS_READ_WRITE; |
755 | 0 |
|
756 | 0 | LOG((" session->AsyncOpenCacheEntry with access=%d", cacheAccess)); |
757 | 0 |
|
758 | 0 | bool bypassBusy = mFlags & nsICacheStorage::OPEN_BYPASS_IF_BUSY; |
759 | 0 |
|
760 | 0 | if (mSync && cacheAccess == nsICache::ACCESS_WRITE) { |
761 | 0 | nsCOMPtr<nsICacheEntryDescriptor> entry; |
762 | 0 | rv = session->OpenCacheEntry(mCacheKey, cacheAccess, bypassBusy, |
763 | 0 | getter_AddRefs(entry)); |
764 | 0 |
|
765 | 0 | nsCacheAccessMode grantedAccess = 0; |
766 | 0 | if (NS_SUCCEEDED(rv)) { |
767 | 0 | entry->GetAccessGranted(&grantedAccess); |
768 | 0 | } |
769 | 0 |
|
770 | 0 | return OnCacheEntryAvailable(entry, grantedAccess, rv); |
771 | 0 | } |
772 | 0 |
|
773 | 0 | rv = session->AsyncOpenCacheEntry(mCacheKey, cacheAccess, this, bypassBusy); |
774 | 0 | if (NS_SUCCEEDED(rv)) |
775 | 0 | return NS_OK; |
776 | 0 | } |
777 | 0 | |
778 | 0 | // Opening failed, propagate the error to the consumer |
779 | 0 | LOG((" Opening cache entry failed with rv=0x%08" PRIx32, static_cast<uint32_t>(rv))); |
780 | 0 | mStatus = rv; |
781 | 0 | mNew = false; |
782 | 0 | NS_DispatchToMainThread(this); |
783 | 0 | } else { |
784 | 0 | if (!mCallback) { |
785 | 0 | LOG((" duplicate call, bypassed")); |
786 | 0 | return NS_OK; |
787 | 0 | } |
788 | 0 |
|
789 | 0 | if (NS_SUCCEEDED(mStatus)) { |
790 | 0 | if (mFlags & nsICacheStorage::OPEN_TRUNCATE) { |
791 | 0 | mozilla::Telemetry::AccumulateTimeDelta( |
792 | 0 | mozilla::Telemetry::NETWORK_CACHE_V1_TRUNCATE_TIME_MS, |
793 | 0 | mLoadStart); |
794 | 0 | } |
795 | 0 | else if (mNew) { |
796 | 0 | mozilla::Telemetry::AccumulateTimeDelta( |
797 | 0 | mozilla::Telemetry::NETWORK_CACHE_V1_MISS_TIME_MS, |
798 | 0 | mLoadStart); |
799 | 0 | } |
800 | 0 | else { |
801 | 0 | mozilla::Telemetry::AccumulateTimeDelta( |
802 | 0 | mozilla::Telemetry::NETWORK_CACHE_V1_HIT_TIME_MS, |
803 | 0 | mLoadStart); |
804 | 0 | } |
805 | 0 | } |
806 | 0 |
|
807 | 0 | if (!(mFlags & CHECK_MULTITHREADED)) |
808 | 0 | Check(); |
809 | 0 |
|
810 | 0 | // break cycles |
811 | 0 | nsCOMPtr<nsICacheEntryOpenCallback> cb = mCallback.forget(); |
812 | 0 | mCacheThread = nullptr; |
813 | 0 | nsCOMPtr<nsICacheEntry> entry = mCacheEntry.forget(); |
814 | 0 |
|
815 | 0 | rv = cb->OnCacheEntryAvailable(entry, mNew, mAppCache, mStatus); |
816 | 0 |
|
817 | 0 | if (NS_FAILED(rv) && entry) { |
818 | 0 | LOG((" cb->OnCacheEntryAvailable failed with rv=0x%08" PRIx32, |
819 | 0 | static_cast<uint32_t>(rv))); |
820 | 0 | if (mNew) |
821 | 0 | entry->AsyncDoom(nullptr); |
822 | 0 | else |
823 | 0 | entry->Close(); |
824 | 0 | } |
825 | 0 | } |
826 | 0 |
|
827 | 0 | return rv; |
828 | 0 | } |
829 | | |
830 | | NS_IMETHODIMP |
831 | | _OldCacheLoad::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry, |
832 | | nsCacheAccessMode access, |
833 | | nsresult status) |
834 | 0 | { |
835 | 0 | LOG(("_OldCacheLoad::OnCacheEntryAvailable [this=%p, ent=%p, cb=%p, appcache=%p, access=%x]", |
836 | 0 | this, entry, mCallback.get(), mAppCache.get(), access)); |
837 | 0 |
|
838 | 0 | // XXX Bug 759805: Sometimes we will call this method directly from |
839 | 0 | // HttpCacheQuery::Run when AsyncOpenCacheEntry fails, but |
840 | 0 | // AsyncOpenCacheEntry will also call this method. As a workaround, we just |
841 | 0 | // ensure we only execute this code once. |
842 | 0 | NS_ENSURE_TRUE(mRunCount == 0, NS_ERROR_UNEXPECTED); |
843 | 0 | ++mRunCount; |
844 | 0 |
|
845 | 0 | mCacheEntry = entry ? new _OldCacheEntryWrapper(entry) : nullptr; |
846 | 0 | mStatus = status; |
847 | 0 | mNew = access == nsICache::ACCESS_WRITE; |
848 | 0 |
|
849 | 0 | if (mFlags & CHECK_MULTITHREADED) |
850 | 0 | Check(); |
851 | 0 |
|
852 | 0 | if (mSync) |
853 | 0 | return Run(); |
854 | 0 | |
855 | 0 | return NS_DispatchToMainThread(this); |
856 | 0 | } |
857 | | |
858 | | void |
859 | | _OldCacheLoad::Check() |
860 | 0 | { |
861 | 0 | if (!mCacheEntry) |
862 | 0 | return; |
863 | 0 | |
864 | 0 | if (mNew) |
865 | 0 | return; |
866 | 0 | |
867 | 0 | uint32_t result; |
868 | 0 | nsresult rv = mCallback->OnCacheEntryCheck(mCacheEntry, mAppCache, &result); |
869 | 0 | LOG((" OnCacheEntryCheck result ent=%p, cb=%p, appcache=%p, rv=0x%08" |
870 | 0 | PRIx32 ", result=%d", |
871 | 0 | mCacheEntry.get(), mCallback.get(), mAppCache.get(), static_cast<uint32_t>(rv), |
872 | 0 | result)); |
873 | 0 |
|
874 | 0 | if (NS_FAILED(rv)) { |
875 | 0 | NS_WARNING("cache check failed"); |
876 | 0 | } |
877 | 0 |
|
878 | 0 | if (NS_FAILED(rv) || result == nsICacheEntryOpenCallback::ENTRY_NOT_WANTED) { |
879 | 0 | mCacheEntry->Close(); |
880 | 0 | mCacheEntry = nullptr; |
881 | 0 | mStatus = NS_ERROR_CACHE_KEY_NOT_FOUND; |
882 | 0 | } |
883 | 0 | } |
884 | | |
885 | | NS_IMETHODIMP |
886 | | _OldCacheLoad::OnCacheEntryDoomed(nsresult) |
887 | 0 | { |
888 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
889 | 0 | } |
890 | | |
891 | | // nsICacheStorage old cache wrapper |
892 | | |
893 | | NS_IMPL_ISUPPORTS(_OldStorage, nsICacheStorage) |
894 | | |
895 | | _OldStorage::_OldStorage(nsILoadContextInfo* aInfo, |
896 | | bool aAllowDisk, |
897 | | bool aLookupAppCache, |
898 | | bool aOfflineStorage, |
899 | | nsIApplicationCache* aAppCache) |
900 | | : mLoadInfo(GetLoadContextInfo(aInfo)) |
901 | | , mAppCache(aAppCache) |
902 | | , mWriteToDisk(aAllowDisk) |
903 | | , mLookupAppCache(aLookupAppCache) |
904 | | , mOfflineStorage(aOfflineStorage) |
905 | 0 | { |
906 | 0 | } |
907 | | |
908 | 0 | _OldStorage::~_OldStorage() = default; |
909 | | |
910 | | NS_IMETHODIMP _OldStorage::AsyncOpenURI(nsIURI *aURI, |
911 | | const nsACString & aIdExtension, |
912 | | uint32_t aFlags, |
913 | | nsICacheEntryOpenCallback *aCallback) |
914 | 0 | { |
915 | 0 | NS_ENSURE_ARG(aURI); |
916 | 0 | NS_ENSURE_ARG(aCallback); |
917 | 0 |
|
918 | 0 | #ifdef MOZ_LOGGING |
919 | 0 | nsAutoCString uriSpec; |
920 | 0 | aURI->GetAsciiSpec(uriSpec); |
921 | 0 | LOG(("_OldStorage::AsyncOpenURI [this=%p, uri=%s, ide=%s, flags=%x]", |
922 | 0 | this, uriSpec.get(), aIdExtension.BeginReading(), aFlags)); |
923 | 0 | #endif |
924 | 0 |
|
925 | 0 | nsresult rv; |
926 | 0 |
|
927 | 0 | nsAutoCString cacheKey, scheme; |
928 | 0 | rv = AssembleCacheKey(aURI, aIdExtension, cacheKey, scheme); |
929 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
930 | 0 |
|
931 | 0 | if (!mAppCache && (mLookupAppCache || mOfflineStorage)) { |
932 | 0 | rv = ChooseApplicationCache(cacheKey, getter_AddRefs(mAppCache)); |
933 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
934 | 0 |
|
935 | 0 | if (mAppCache) { |
936 | 0 | // From a chosen appcache open only as readonly |
937 | 0 | aFlags &= ~nsICacheStorage::OPEN_TRUNCATE; |
938 | 0 | } |
939 | 0 | } |
940 | 0 |
|
941 | 0 | RefPtr<_OldCacheLoad> cacheLoad = |
942 | 0 | new _OldCacheLoad(scheme, cacheKey, aCallback, mAppCache, |
943 | 0 | mLoadInfo, mWriteToDisk, aFlags); |
944 | 0 |
|
945 | 0 | rv = cacheLoad->Start(); |
946 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
947 | 0 |
|
948 | 0 | return NS_OK; |
949 | 0 | } |
950 | | |
951 | | NS_IMETHODIMP _OldStorage::OpenTruncate(nsIURI *aURI, const nsACString & aIdExtension, |
952 | | nsICacheEntry **aCacheEntry) |
953 | 0 | { |
954 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
955 | 0 | } |
956 | | |
957 | | NS_IMETHODIMP _OldStorage::Exists(nsIURI *aURI, const nsACString & aIdExtension, |
958 | | bool *aResult) |
959 | 0 | { |
960 | 0 | return NS_ERROR_NOT_AVAILABLE; |
961 | 0 | } |
962 | | |
963 | | NS_IMETHODIMP _OldStorage::AsyncDoomURI(nsIURI *aURI, const nsACString & aIdExtension, |
964 | | nsICacheEntryDoomCallback* aCallback) |
965 | 0 | { |
966 | 0 | LOG(("_OldStorage::AsyncDoomURI")); |
967 | 0 |
|
968 | 0 | nsresult rv; |
969 | 0 |
|
970 | 0 | nsAutoCString cacheKey, scheme; |
971 | 0 | rv = AssembleCacheKey(aURI, aIdExtension, cacheKey, scheme); |
972 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
973 | 0 |
|
974 | 0 | nsCOMPtr<nsICacheSession> session; |
975 | 0 | rv = GetCacheSession(scheme, mWriteToDisk, mLoadInfo, mAppCache, |
976 | 0 | getter_AddRefs(session)); |
977 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
978 | 0 |
|
979 | 0 | RefPtr<DoomCallbackWrapper> cb = aCallback |
980 | 0 | ? new DoomCallbackWrapper(aCallback) |
981 | 0 | : nullptr; |
982 | 0 | rv = session->DoomEntry(cacheKey, cb); |
983 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
984 | 0 |
|
985 | 0 | return NS_OK; |
986 | 0 | } |
987 | | |
988 | | NS_IMETHODIMP _OldStorage::AsyncEvictStorage(nsICacheEntryDoomCallback* aCallback) |
989 | 0 | { |
990 | 0 | LOG(("_OldStorage::AsyncEvictStorage")); |
991 | 0 |
|
992 | 0 | nsresult rv; |
993 | 0 |
|
994 | 0 | if (!mAppCache && mOfflineStorage) { |
995 | 0 | nsCOMPtr<nsIApplicationCacheService> appCacheService = |
996 | 0 | do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv); |
997 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
998 | 0 |
|
999 | 0 | rv = appCacheService->Evict(mLoadInfo); |
1000 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1001 | 0 | } else if (mAppCache) { |
1002 | 0 | nsCOMPtr<nsICacheSession> session; |
1003 | 0 | rv = GetCacheSession(EmptyCString(), |
1004 | 0 | mWriteToDisk, mLoadInfo, mAppCache, |
1005 | 0 | getter_AddRefs(session)); |
1006 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1007 | 0 |
|
1008 | 0 | rv = session->EvictEntries(); |
1009 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1010 | 0 | } else { |
1011 | 0 | // Oh, I'll be so happy when session names are gone... |
1012 | 0 | nsCOMPtr<nsICacheSession> session; |
1013 | 0 | rv = GetCacheSession(NS_LITERAL_CSTRING("http"), |
1014 | 0 | mWriteToDisk, mLoadInfo, mAppCache, |
1015 | 0 | getter_AddRefs(session)); |
1016 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1017 | 0 |
|
1018 | 0 | rv = session->EvictEntries(); |
1019 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1020 | 0 |
|
1021 | 0 | rv = GetCacheSession(NS_LITERAL_CSTRING("wyciwyg"), |
1022 | 0 | mWriteToDisk, mLoadInfo, mAppCache, |
1023 | 0 | getter_AddRefs(session)); |
1024 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1025 | 0 |
|
1026 | 0 | rv = session->EvictEntries(); |
1027 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1028 | 0 |
|
1029 | 0 | // This clears any data from scheme other then http, wyciwyg or ftp |
1030 | 0 | rv = GetCacheSession(EmptyCString(), |
1031 | 0 | mWriteToDisk, mLoadInfo, mAppCache, |
1032 | 0 | getter_AddRefs(session)); |
1033 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1034 | 0 |
|
1035 | 0 | rv = session->EvictEntries(); |
1036 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1037 | 0 | } |
1038 | 0 |
|
1039 | 0 | if (aCallback) { |
1040 | 0 | RefPtr<DoomCallbackSynchronizer> sync = |
1041 | 0 | new DoomCallbackSynchronizer(aCallback); |
1042 | 0 | rv = sync->Dispatch(); |
1043 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1044 | 0 | } |
1045 | 0 |
|
1046 | 0 | return NS_OK; |
1047 | 0 | } |
1048 | | |
1049 | | NS_IMETHODIMP _OldStorage::AsyncVisitStorage(nsICacheStorageVisitor* aVisitor, |
1050 | | bool aVisitEntries) |
1051 | 0 | { |
1052 | 0 | LOG(("_OldStorage::AsyncVisitStorage")); |
1053 | 0 |
|
1054 | 0 | NS_ENSURE_ARG(aVisitor); |
1055 | 0 |
|
1056 | 0 | nsresult rv; |
1057 | 0 |
|
1058 | 0 | nsCOMPtr<nsICacheService> serv = |
1059 | 0 | do_GetService(NS_CACHESERVICE_CONTRACTID, &rv); |
1060 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1061 | 0 |
|
1062 | 0 | char* deviceID; |
1063 | 0 | if (mAppCache || mOfflineStorage) { |
1064 | 0 | deviceID = const_cast<char*>("offline"); |
1065 | 0 | } else if (!mWriteToDisk || mLoadInfo->IsPrivate()) { |
1066 | 0 | deviceID = const_cast<char*>("memory"); |
1067 | 0 | } else { |
1068 | 0 | deviceID = const_cast<char*>("disk"); |
1069 | 0 | } |
1070 | 0 |
|
1071 | 0 | RefPtr<_OldVisitCallbackWrapper> cb = new _OldVisitCallbackWrapper( |
1072 | 0 | deviceID, aVisitor, aVisitEntries, mLoadInfo); |
1073 | 0 | rv = nsCacheService::GlobalInstance()->VisitEntriesInternal(cb); |
1074 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1075 | 0 |
|
1076 | 0 | return NS_OK; |
1077 | 0 | } |
1078 | | |
1079 | | NS_IMETHODIMP _OldStorage::GetCacheIndexEntryAttrs(nsIURI *aURI, |
1080 | | const nsACString &aIdExtension, |
1081 | | bool *aHasAltData, |
1082 | | uint32_t *aSizeInKB) |
1083 | 0 | { |
1084 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
1085 | 0 | } |
1086 | | |
1087 | | // Internal |
1088 | | |
1089 | | nsresult _OldStorage::AssembleCacheKey(nsIURI *aURI, |
1090 | | nsACString const & aIdExtension, |
1091 | | nsACString & aCacheKey, |
1092 | | nsACString & aScheme) |
1093 | 0 | { |
1094 | 0 | // Copied from nsHttpChannel::AssembleCacheKey |
1095 | 0 |
|
1096 | 0 | aCacheKey.Truncate(); |
1097 | 0 |
|
1098 | 0 | nsresult rv; |
1099 | 0 |
|
1100 | 0 | rv = aURI->GetScheme(aScheme); |
1101 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1102 | 0 |
|
1103 | 0 | nsAutoCString uriSpec; |
1104 | 0 | if (aScheme.EqualsLiteral("http") || |
1105 | 0 | aScheme.EqualsLiteral("https")) { |
1106 | 0 | if (mLoadInfo->IsAnonymous()) { |
1107 | 0 | aCacheKey.AssignLiteral("anon&"); |
1108 | 0 | } |
1109 | 0 |
|
1110 | 0 | if (!aIdExtension.IsEmpty()) { |
1111 | 0 | aCacheKey.AppendPrintf("id=%s&", aIdExtension.BeginReading()); |
1112 | 0 | } |
1113 | 0 |
|
1114 | 0 | nsCOMPtr<nsIURI> noRefURI; |
1115 | 0 | rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(noRefURI)); |
1116 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1117 | 0 |
|
1118 | 0 | rv = noRefURI->GetAsciiSpec(uriSpec); |
1119 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1120 | 0 |
|
1121 | 0 | if (!aCacheKey.IsEmpty()) { |
1122 | 0 | aCacheKey.AppendLiteral("uri="); |
1123 | 0 | } |
1124 | 0 | } |
1125 | 0 | else if (aScheme.EqualsLiteral("wyciwyg")) { |
1126 | 0 | rv = aURI->GetSpec(uriSpec); |
1127 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1128 | 0 | } |
1129 | 0 | else { |
1130 | 0 | rv = aURI->GetAsciiSpec(uriSpec); |
1131 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1132 | 0 | } |
1133 | 0 |
|
1134 | 0 | aCacheKey.Append(uriSpec); |
1135 | 0 |
|
1136 | 0 | return NS_OK; |
1137 | 0 | } |
1138 | | |
1139 | | nsresult _OldStorage::ChooseApplicationCache(const nsACString& cacheKey, |
1140 | | nsIApplicationCache** aCache) |
1141 | 0 | { |
1142 | 0 | nsresult rv; |
1143 | 0 |
|
1144 | 0 | nsCOMPtr<nsIApplicationCacheService> appCacheService = |
1145 | 0 | do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv); |
1146 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1147 | 0 |
|
1148 | 0 | rv = appCacheService->ChooseApplicationCache(cacheKey, mLoadInfo, aCache); |
1149 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1150 | 0 |
|
1151 | 0 | return NS_OK; |
1152 | 0 | } |
1153 | | |
1154 | | } // namespace net |
1155 | | } // namespace mozilla |