/src/mozilla-central/image/imgLoader.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
2 | | * |
3 | | * This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef mozilla_image_imgLoader_h |
8 | | #define mozilla_image_imgLoader_h |
9 | | |
10 | | #include "mozilla/Attributes.h" |
11 | | #include "mozilla/Mutex.h" |
12 | | #include "mozilla/UniquePtr.h" |
13 | | |
14 | | #include "imgILoader.h" |
15 | | #include "imgICache.h" |
16 | | #include "nsWeakReference.h" |
17 | | #include "nsIContentSniffer.h" |
18 | | #include "nsRefPtrHashtable.h" |
19 | | #include "nsExpirationTracker.h" |
20 | | #include "ImageCacheKey.h" |
21 | | #include "imgRequest.h" |
22 | | #include "nsIProgressEventSink.h" |
23 | | #include "nsIChannel.h" |
24 | | #include "nsIThreadRetargetableStreamListener.h" |
25 | | #include "imgIRequest.h" |
26 | | #include "mozilla/net/ReferrerPolicy.h" |
27 | | |
28 | | class imgLoader; |
29 | | class imgRequestProxy; |
30 | | class imgINotificationObserver; |
31 | | class nsILoadGroup; |
32 | | class imgCacheExpirationTracker; |
33 | | class imgMemoryReporter; |
34 | | |
35 | | namespace mozilla { |
36 | | namespace image { |
37 | | } // namespace image |
38 | | } // namespace mozilla |
39 | | |
40 | | class imgCacheEntry |
41 | | { |
42 | | public: |
43 | | static uint32_t SecondsFromPRTime(PRTime prTime); |
44 | | |
45 | | imgCacheEntry(imgLoader* loader, imgRequest* request, |
46 | | bool aForcePrincipalCheck); |
47 | | ~imgCacheEntry(); |
48 | | |
49 | | nsrefcnt AddRef() |
50 | 0 | { |
51 | 0 | MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); |
52 | 0 | NS_ASSERT_OWNINGTHREAD(imgCacheEntry); |
53 | 0 | ++mRefCnt; |
54 | 0 | NS_LOG_ADDREF(this, mRefCnt, "imgCacheEntry", sizeof(*this)); |
55 | 0 | return mRefCnt; |
56 | 0 | } |
57 | | |
58 | | nsrefcnt Release() |
59 | 0 | { |
60 | 0 | MOZ_ASSERT(0 != mRefCnt, "dup release"); |
61 | 0 | NS_ASSERT_OWNINGTHREAD(imgCacheEntry); |
62 | 0 | --mRefCnt; |
63 | 0 | NS_LOG_RELEASE(this, mRefCnt, "imgCacheEntry"); |
64 | 0 | if (mRefCnt == 0) { |
65 | 0 | mRefCnt = 1; /* stabilize */ |
66 | 0 | delete this; |
67 | 0 | return 0; |
68 | 0 | } |
69 | 0 | return mRefCnt; |
70 | 0 | } |
71 | | |
72 | | uint32_t GetDataSize() const |
73 | 0 | { |
74 | 0 | return mDataSize; |
75 | 0 | } |
76 | | void SetDataSize(uint32_t aDataSize) |
77 | 0 | { |
78 | 0 | int32_t oldsize = mDataSize; |
79 | 0 | mDataSize = aDataSize; |
80 | 0 | UpdateCache(mDataSize - oldsize); |
81 | 0 | } |
82 | | |
83 | | int32_t GetTouchedTime() const |
84 | 0 | { |
85 | 0 | return mTouchedTime; |
86 | 0 | } |
87 | | void SetTouchedTime(int32_t time) |
88 | 0 | { |
89 | 0 | mTouchedTime = time; |
90 | 0 | Touch(/* updateTime = */ false); |
91 | 0 | } |
92 | | |
93 | | uint32_t GetLoadTime() const |
94 | 0 | { |
95 | 0 | return mLoadTime; |
96 | 0 | } |
97 | | |
98 | | void UpdateLoadTime(); |
99 | | |
100 | | int32_t GetExpiryTime() const |
101 | 0 | { |
102 | 0 | return mExpiryTime; |
103 | 0 | } |
104 | | void SetExpiryTime(int32_t aExpiryTime) |
105 | 0 | { |
106 | 0 | mExpiryTime = aExpiryTime; |
107 | 0 | Touch(); |
108 | 0 | } |
109 | | |
110 | | bool GetMustValidate() const |
111 | 0 | { |
112 | 0 | return mMustValidate; |
113 | 0 | } |
114 | | void SetMustValidate(bool aValidate) |
115 | 0 | { |
116 | 0 | mMustValidate = aValidate; |
117 | 0 | Touch(); |
118 | 0 | } |
119 | | |
120 | | already_AddRefed<imgRequest> GetRequest() const |
121 | 0 | { |
122 | 0 | RefPtr<imgRequest> req = mRequest; |
123 | 0 | return req.forget(); |
124 | 0 | } |
125 | | |
126 | | bool Evicted() const |
127 | 0 | { |
128 | 0 | return mEvicted; |
129 | 0 | } |
130 | | |
131 | | nsExpirationState* GetExpirationState() |
132 | 0 | { |
133 | 0 | return &mExpirationState; |
134 | 0 | } |
135 | | |
136 | | bool HasNoProxies() const |
137 | 0 | { |
138 | 0 | return mHasNoProxies; |
139 | 0 | } |
140 | | |
141 | | bool ForcePrincipalCheck() const |
142 | 0 | { |
143 | 0 | return mForcePrincipalCheck; |
144 | 0 | } |
145 | | |
146 | | imgLoader* Loader() const |
147 | 0 | { |
148 | 0 | return mLoader; |
149 | 0 | } |
150 | | |
151 | | private: // methods |
152 | | friend class imgLoader; |
153 | | friend class imgCacheQueue; |
154 | | void Touch(bool updateTime = true); |
155 | | void UpdateCache(int32_t diff = 0); |
156 | | void SetEvicted(bool evict) |
157 | 0 | { |
158 | 0 | mEvicted = evict; |
159 | 0 | } |
160 | | void SetHasNoProxies(bool hasNoProxies); |
161 | | |
162 | | // Private, unimplemented copy constructor. |
163 | | imgCacheEntry(const imgCacheEntry&); |
164 | | |
165 | | private: // data |
166 | | nsAutoRefCnt mRefCnt; |
167 | | NS_DECL_OWNINGTHREAD |
168 | | |
169 | | imgLoader* mLoader; |
170 | | RefPtr<imgRequest> mRequest; |
171 | | uint32_t mDataSize; |
172 | | int32_t mTouchedTime; |
173 | | uint32_t mLoadTime; |
174 | | int32_t mExpiryTime; |
175 | | nsExpirationState mExpirationState; |
176 | | bool mMustValidate : 1; |
177 | | bool mEvicted : 1; |
178 | | bool mHasNoProxies : 1; |
179 | | bool mForcePrincipalCheck : 1; |
180 | | }; |
181 | | |
182 | | #include <vector> |
183 | | |
184 | | #define NS_IMGLOADER_CID \ |
185 | | { /* c1354898-e3fe-4602-88a7-c4520c21cb4e */ \ |
186 | | 0xc1354898, \ |
187 | | 0xe3fe, \ |
188 | | 0x4602, \ |
189 | | {0x88, 0xa7, 0xc4, 0x52, 0x0c, 0x21, 0xcb, 0x4e} \ |
190 | | } |
191 | | |
192 | | class imgCacheQueue |
193 | | { |
194 | | public: |
195 | | imgCacheQueue(); |
196 | | void Remove(imgCacheEntry*); |
197 | | void Push(imgCacheEntry*); |
198 | | void MarkDirty(); |
199 | | bool IsDirty(); |
200 | | already_AddRefed<imgCacheEntry> Pop(); |
201 | | void Refresh(); |
202 | | uint32_t GetSize() const; |
203 | | void UpdateSize(int32_t diff); |
204 | | uint32_t GetNumElements() const; |
205 | | bool Contains(imgCacheEntry* aEntry) const; |
206 | | typedef nsTArray<RefPtr<imgCacheEntry> > queueContainer; |
207 | | typedef queueContainer::iterator iterator; |
208 | | typedef queueContainer::const_iterator const_iterator; |
209 | | |
210 | | iterator begin(); |
211 | | const_iterator begin() const; |
212 | | iterator end(); |
213 | | const_iterator end() const; |
214 | | |
215 | | private: |
216 | | queueContainer mQueue; |
217 | | bool mDirty; |
218 | | uint32_t mSize; |
219 | | }; |
220 | | |
221 | | enum class AcceptedMimeTypes : uint8_t { |
222 | | IMAGES, |
223 | | IMAGES_AND_DOCUMENTS, |
224 | | }; |
225 | | |
226 | | class imgLoader final : public imgILoader, |
227 | | public nsIContentSniffer, |
228 | | public imgICache, |
229 | | public nsSupportsWeakReference, |
230 | | public nsIObserver |
231 | | { |
232 | | virtual ~imgLoader(); |
233 | | |
234 | | public: |
235 | | typedef mozilla::image::ImageCacheKey ImageCacheKey; |
236 | | typedef nsRefPtrHashtable<nsGenericHashKey<ImageCacheKey>, |
237 | | imgCacheEntry> imgCacheTable; |
238 | | typedef nsTHashtable<nsPtrHashKey<imgRequest>> imgSet; |
239 | | typedef mozilla::net::ReferrerPolicy ReferrerPolicy; |
240 | | typedef mozilla::Mutex Mutex; |
241 | | |
242 | | NS_DECL_ISUPPORTS |
243 | | NS_DECL_IMGILOADER |
244 | | NS_DECL_NSICONTENTSNIFFER |
245 | | NS_DECL_IMGICACHE |
246 | | NS_DECL_NSIOBSERVER |
247 | | |
248 | | /** |
249 | | * Get the normal image loader instance that is used by gecko code, creating |
250 | | * it if necessary. |
251 | | */ |
252 | | static imgLoader* NormalLoader(); |
253 | | |
254 | | /** |
255 | | * Get the Private Browsing image loader instance that is used by gecko code, |
256 | | * creating it if necessary. |
257 | | */ |
258 | | static imgLoader* PrivateBrowsingLoader(); |
259 | | |
260 | | /** |
261 | | * Gecko code should use NormalLoader() or PrivateBrowsingLoader() to get the |
262 | | * appropriate image loader. |
263 | | * |
264 | | * This constructor is public because the XPCOM module code that creates |
265 | | * instances of "@mozilla.org/image/loader;1" / "@mozilla.org/image/cache;1" |
266 | | * for nsIComponentManager.createInstance()/nsIServiceManager.getService() |
267 | | * calls (now only made by add-ons) needs access to it. |
268 | | * |
269 | | * XXX We would like to get rid of the nsIServiceManager.getService (and |
270 | | * nsIComponentManager.createInstance) method of creating imgLoader objects, |
271 | | * but there are add-ons that are still using it. These add-ons don't |
272 | | * actually do anything useful with the loaders that they create since nobody |
273 | | * who creates an imgLoader using this method actually QIs to imgILoader and |
274 | | * loads images. They all just QI to imgICache and either call clearCache() |
275 | | * or findEntryProperties(). Since they're doing this on an imgLoader that |
276 | | * has never loaded images, these calls are useless. It seems likely that |
277 | | * the code that is doing this is just legacy code left over from a time when |
278 | | * there was only one imgLoader instance for the entire process. (Nowadays |
279 | | * the correct method to get an imgILoader/imgICache is to call |
280 | | * imgITools::getImgCacheForDocument/imgITools::getImgLoaderForDocument.) |
281 | | * All the same, even though what these add-ons are doing is a no-op, |
282 | | * removing the nsIServiceManager.getService method of creating/getting an |
283 | | * imgLoader objects would cause an exception in these add-ons that could |
284 | | * break things. |
285 | | */ |
286 | | imgLoader(); |
287 | | nsresult Init(); |
288 | | |
289 | | MOZ_MUST_USE nsresult LoadImage(nsIURI* aURI, |
290 | | nsIURI* aInitialDocumentURI, |
291 | | nsIURI* aReferrerURI, |
292 | | ReferrerPolicy aReferrerPolicy, |
293 | | nsIPrincipal* aLoadingPrincipal, |
294 | | uint64_t aRequestContextID, |
295 | | nsILoadGroup* aLoadGroup, |
296 | | imgINotificationObserver* aObserver, |
297 | | nsINode* aContext, |
298 | | nsIDocument* aLoadingDocument, |
299 | | nsLoadFlags aLoadFlags, |
300 | | nsISupports* aCacheKey, |
301 | | nsContentPolicyType aContentPolicyType, |
302 | | const nsAString& initiatorType, |
303 | | bool aUseUrgentStartForChannel, |
304 | | imgRequestProxy** _retval); |
305 | | |
306 | | MOZ_MUST_USE nsresult |
307 | | LoadImageWithChannel(nsIChannel* channel, |
308 | | imgINotificationObserver* aObserver, |
309 | | nsISupports* aCX, |
310 | | nsIStreamListener** listener, |
311 | | imgRequestProxy** _retval); |
312 | | |
313 | | static nsresult GetMimeTypeFromContent(const char* aContents, |
314 | | uint32_t aLength, |
315 | | nsACString& aContentType); |
316 | | |
317 | | /** |
318 | | * Returns true if the given mime type may be interpreted as an image. |
319 | | * |
320 | | * Some MIME types may be interpreted as both images and documents. (At the |
321 | | * moment only "image/svg+xml" falls into this category, but there may be more |
322 | | * in the future.) Callers which want this function to return true for such |
323 | | * MIME types should pass AcceptedMimeTypes::IMAGES_AND_DOCUMENTS for |
324 | | * @aAccept. |
325 | | * |
326 | | * @param aMimeType The MIME type to evaluate. |
327 | | * @param aAcceptedMimeTypes Which kinds of MIME types to treat as images. |
328 | | */ |
329 | | static bool |
330 | | SupportImageWithMimeType(const char* aMimeType, |
331 | | AcceptedMimeTypes aAccept = |
332 | | AcceptedMimeTypes::IMAGES); |
333 | | |
334 | | static void GlobalInit(); // for use by the factory |
335 | | static void Shutdown(); // for use by the factory |
336 | | static void ShutdownMemoryReporter(); |
337 | | |
338 | | nsresult ClearChromeImageCache(); |
339 | | nsresult ClearImageCache(); |
340 | | void MinimizeCaches(); |
341 | | |
342 | | nsresult InitCache(); |
343 | | |
344 | | bool RemoveFromCache(const ImageCacheKey& aKey); |
345 | | |
346 | | // Enumeration describing if a given entry is in the cache queue or not. |
347 | | // There are some cases we know the entry is definitely not in the queue. |
348 | | enum class QueueState { |
349 | | MaybeExists, |
350 | | AlreadyRemoved |
351 | | }; |
352 | | |
353 | | bool RemoveFromCache(imgCacheEntry* entry, |
354 | | QueueState aQueueState = QueueState::MaybeExists); |
355 | | |
356 | | bool PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* aEntry); |
357 | | |
358 | | void AddToUncachedImages(imgRequest* aRequest); |
359 | | void RemoveFromUncachedImages(imgRequest* aRequest); |
360 | | |
361 | | // Returns true if we should prefer evicting cache entry |two| over cache |
362 | | // entry |one|. |
363 | | // This mixes units in the worst way, but provides reasonable results. |
364 | | inline static bool CompareCacheEntries(const RefPtr<imgCacheEntry>& one, |
365 | | const RefPtr<imgCacheEntry>& two) |
366 | 0 | { |
367 | 0 | if (!one) { |
368 | 0 | return false; |
369 | 0 | } |
370 | 0 | if (!two) { |
371 | 0 | return true; |
372 | 0 | } |
373 | 0 | |
374 | 0 | const double sizeweight = 1.0 - sCacheTimeWeight; |
375 | 0 |
|
376 | 0 | // We want large, old images to be evicted first (depending on their |
377 | 0 | // relative weights). Since a larger time is actually newer, we subtract |
378 | 0 | // time's weight, so an older image has a larger weight. |
379 | 0 | double oneweight = double(one->GetDataSize()) * sizeweight - |
380 | 0 | double(one->GetTouchedTime()) * sCacheTimeWeight; |
381 | 0 | double twoweight = double(two->GetDataSize()) * sizeweight - |
382 | 0 | double(two->GetTouchedTime()) * sCacheTimeWeight; |
383 | 0 |
|
384 | 0 | return oneweight < twoweight; |
385 | 0 | } |
386 | | |
387 | | void VerifyCacheSizes(); |
388 | | |
389 | | // The image loader maintains a hash table of all imgCacheEntries. However, |
390 | | // only some of them will be evicted from the cache: those who have no |
391 | | // imgRequestProxies watching their imgRequests. |
392 | | // |
393 | | // Once an imgRequest has no imgRequestProxies, it should notify us by |
394 | | // calling HasNoObservers(), and null out its cache entry pointer. |
395 | | // |
396 | | // Upon having a proxy start observing again, it should notify us by calling |
397 | | // HasObservers(). The request's cache entry will be re-set before this |
398 | | // happens, by calling imgRequest::SetCacheEntry() when an entry with no |
399 | | // observers is re-requested. |
400 | | bool SetHasNoProxies(imgRequest* aRequest, imgCacheEntry* aEntry); |
401 | | bool SetHasProxies(imgRequest* aRequest); |
402 | | |
403 | | private: // methods |
404 | | |
405 | | static already_AddRefed<imgLoader> CreateImageLoader(); |
406 | | |
407 | | bool ValidateEntry(imgCacheEntry* aEntry, nsIURI* aKey, |
408 | | nsIURI* aInitialDocumentURI, nsIURI* aReferrerURI, |
409 | | ReferrerPolicy aReferrerPolicy, |
410 | | nsILoadGroup* aLoadGroup, |
411 | | imgINotificationObserver* aObserver, nsISupports* aCX, |
412 | | nsIDocument* aLoadingDocument, |
413 | | nsLoadFlags aLoadFlags, |
414 | | nsContentPolicyType aContentPolicyType, |
415 | | bool aCanMakeNewChannel, |
416 | | bool* aNewChannelCreated, |
417 | | imgRequestProxy** aProxyRequest, |
418 | | nsIPrincipal* aLoadingPrincipal, |
419 | | int32_t aCORSMode); |
420 | | |
421 | | bool ValidateRequestWithNewChannel(imgRequest* request, nsIURI* aURI, |
422 | | nsIURI* aInitialDocumentURI, |
423 | | nsIURI* aReferrerURI, |
424 | | ReferrerPolicy aReferrerPolicy, |
425 | | nsILoadGroup* aLoadGroup, |
426 | | imgINotificationObserver* aObserver, |
427 | | nsISupports* aCX, |
428 | | nsIDocument* aLoadingDocument, |
429 | | nsLoadFlags aLoadFlags, |
430 | | nsContentPolicyType aContentPolicyType, |
431 | | imgRequestProxy** aProxyRequest, |
432 | | nsIPrincipal* aLoadingPrincipal, |
433 | | int32_t aCORSMode, |
434 | | bool* aNewChannelCreated); |
435 | | |
436 | | nsresult CreateNewProxyForRequest(imgRequest* aRequest, |
437 | | nsILoadGroup* aLoadGroup, |
438 | | nsIDocument* aLoadingDocument, |
439 | | imgINotificationObserver* aObserver, |
440 | | nsLoadFlags aLoadFlags, |
441 | | imgRequestProxy** _retval); |
442 | | |
443 | | void ReadAcceptHeaderPref(); |
444 | | |
445 | | nsresult EvictEntries(imgCacheTable& aCacheToClear); |
446 | | nsresult EvictEntries(imgCacheQueue& aQueueToClear); |
447 | | |
448 | | imgCacheTable& GetCache(bool aForChrome); |
449 | | imgCacheTable& GetCache(const ImageCacheKey& aKey); |
450 | | imgCacheQueue& GetCacheQueue(bool aForChrome); |
451 | | imgCacheQueue& GetCacheQueue(const ImageCacheKey& aKey); |
452 | | void CacheEntriesChanged(bool aForChrome, int32_t aSizeDiff = 0); |
453 | | void CheckCacheLimits(imgCacheTable& cache, imgCacheQueue& queue); |
454 | | |
455 | | private: // data |
456 | | friend class imgCacheEntry; |
457 | | friend class imgMemoryReporter; |
458 | | |
459 | | imgCacheTable mCache; |
460 | | imgCacheQueue mCacheQueue; |
461 | | |
462 | | imgCacheTable mChromeCache; |
463 | | imgCacheQueue mChromeCacheQueue; |
464 | | |
465 | | // Hash set of every imgRequest for this loader that isn't in mCache or |
466 | | // mChromeCache. The union over all imgLoader's of mCache, mChromeCache, and |
467 | | // mUncachedImages should be every imgRequest that is alive. These are weak |
468 | | // pointers so we rely on the imgRequest destructor to remove itself. |
469 | | imgSet mUncachedImages; |
470 | | // The imgRequest can have refs to them held on non-main thread, so we need |
471 | | // a mutex because we modify the uncached images set from the imgRequest |
472 | | // destructor. |
473 | | Mutex mUncachedImagesMutex; |
474 | | |
475 | | static double sCacheTimeWeight; |
476 | | static uint32_t sCacheMaxSize; |
477 | | static imgMemoryReporter* sMemReporter; |
478 | | |
479 | | nsCString mAcceptHeader; |
480 | | |
481 | | mozilla::UniquePtr<imgCacheExpirationTracker> mCacheTracker; |
482 | | bool mRespectPrivacy; |
483 | | }; |
484 | | |
485 | | |
486 | | |
487 | | /** |
488 | | * proxy stream listener class used to handle multipart/x-mixed-replace |
489 | | */ |
490 | | |
491 | | #include "nsCOMPtr.h" |
492 | | #include "nsIStreamListener.h" |
493 | | #include "nsIThreadRetargetableStreamListener.h" |
494 | | |
495 | | class ProxyListener : public nsIStreamListener |
496 | | , public nsIThreadRetargetableStreamListener |
497 | | { |
498 | | public: |
499 | | explicit ProxyListener(nsIStreamListener* dest); |
500 | | |
501 | | /* additional members */ |
502 | | NS_DECL_THREADSAFE_ISUPPORTS |
503 | | NS_DECL_NSISTREAMLISTENER |
504 | | NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER |
505 | | NS_DECL_NSIREQUESTOBSERVER |
506 | | |
507 | | private: |
508 | | virtual ~ProxyListener(); |
509 | | |
510 | | nsCOMPtr<nsIStreamListener> mDestListener; |
511 | | }; |
512 | | |
513 | | /** |
514 | | * A class that implements nsIProgressEventSink and forwards all calls to it to |
515 | | * the original notification callbacks of the channel. Also implements |
516 | | * nsIInterfaceRequestor and gives out itself for nsIProgressEventSink calls, |
517 | | * and forwards everything else to the channel's notification callbacks. |
518 | | */ |
519 | | class nsProgressNotificationProxy final |
520 | | : public nsIProgressEventSink |
521 | | , public nsIChannelEventSink |
522 | | , public nsIInterfaceRequestor |
523 | | { |
524 | | public: |
525 | | nsProgressNotificationProxy(nsIChannel* channel, |
526 | | imgIRequest* proxy) |
527 | 0 | : mImageRequest(proxy) { |
528 | 0 | channel->GetNotificationCallbacks(getter_AddRefs(mOriginalCallbacks)); |
529 | 0 | } |
530 | | |
531 | | NS_DECL_ISUPPORTS |
532 | | NS_DECL_NSIPROGRESSEVENTSINK |
533 | | NS_DECL_NSICHANNELEVENTSINK |
534 | | NS_DECL_NSIINTERFACEREQUESTOR |
535 | | private: |
536 | 0 | ~nsProgressNotificationProxy() { } |
537 | | |
538 | | nsCOMPtr<nsIInterfaceRequestor> mOriginalCallbacks; |
539 | | nsCOMPtr<nsIRequest> mImageRequest; |
540 | | }; |
541 | | |
542 | | /** |
543 | | * validate checker |
544 | | */ |
545 | | |
546 | | #include "nsCOMArray.h" |
547 | | |
548 | | class imgCacheValidator : public nsIStreamListener, |
549 | | public nsIThreadRetargetableStreamListener, |
550 | | public nsIChannelEventSink, |
551 | | public nsIInterfaceRequestor, |
552 | | public nsIAsyncVerifyRedirectCallback |
553 | | { |
554 | | public: |
555 | | imgCacheValidator(nsProgressNotificationProxy* progress, imgLoader* loader, |
556 | | imgRequest* aRequest, nsISupports* aContext, |
557 | | bool forcePrincipalCheckForCacheEntry); |
558 | | |
559 | | void AddProxy(imgRequestProxy* aProxy); |
560 | | void RemoveProxy(imgRequestProxy* aProxy); |
561 | | |
562 | | NS_DECL_THREADSAFE_ISUPPORTS |
563 | | NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER |
564 | | NS_DECL_NSISTREAMLISTENER |
565 | | NS_DECL_NSIREQUESTOBSERVER |
566 | | NS_DECL_NSICHANNELEVENTSINK |
567 | | NS_DECL_NSIINTERFACEREQUESTOR |
568 | | NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK |
569 | | |
570 | | private: |
571 | | void UpdateProxies(bool aCancelRequest, bool aSyncNotify); |
572 | | virtual ~imgCacheValidator(); |
573 | | |
574 | | nsCOMPtr<nsIStreamListener> mDestListener; |
575 | | RefPtr<nsProgressNotificationProxy> mProgressProxy; |
576 | | nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback; |
577 | | nsCOMPtr<nsIChannel> mRedirectChannel; |
578 | | |
579 | | RefPtr<imgRequest> mRequest; |
580 | | AutoTArray<RefPtr<imgRequestProxy>, 4> mProxies; |
581 | | |
582 | | RefPtr<imgRequest> mNewRequest; |
583 | | RefPtr<imgCacheEntry> mNewEntry; |
584 | | |
585 | | nsCOMPtr<nsISupports> mContext; |
586 | | |
587 | | imgLoader* mImgLoader; |
588 | | |
589 | | bool mHadInsecureRedirect; |
590 | | }; |
591 | | |
592 | | #endif // mozilla_image_imgLoader_h |