Blame image/imgLoader.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
Packit f0b94e
 *
Packit f0b94e
 * This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#ifndef mozilla_image_imgLoader_h
Packit f0b94e
#define mozilla_image_imgLoader_h
Packit f0b94e
Packit f0b94e
#include "mozilla/Attributes.h"
Packit f0b94e
#include "mozilla/Mutex.h"
Packit f0b94e
#include "mozilla/UniquePtr.h"
Packit f0b94e
Packit f0b94e
#include "imgILoader.h"
Packit f0b94e
#include "imgICache.h"
Packit f0b94e
#include "nsWeakReference.h"
Packit f0b94e
#include "nsIContentSniffer.h"
Packit f0b94e
#include "nsRefPtrHashtable.h"
Packit f0b94e
#include "nsExpirationTracker.h"
Packit f0b94e
#include "ImageCacheKey.h"
Packit f0b94e
#include "imgRequest.h"
Packit f0b94e
#include "nsIProgressEventSink.h"
Packit f0b94e
#include "nsIChannel.h"
Packit f0b94e
#include "nsIThreadRetargetableStreamListener.h"
Packit f0b94e
#include "imgIRequest.h"
Packit f0b94e
#include "mozilla/net/ReferrerPolicy.h"
Packit f0b94e
Packit f0b94e
class imgLoader;
Packit f0b94e
class imgRequestProxy;
Packit f0b94e
class imgINotificationObserver;
Packit f0b94e
class nsILoadGroup;
Packit f0b94e
class imgCacheExpirationTracker;
Packit f0b94e
class imgMemoryReporter;
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
namespace image {
Packit f0b94e
class ImageURL;
Packit f0b94e
}  // namespace image
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
class imgCacheEntry {
Packit f0b94e
 public:
Packit f0b94e
  static uint32_t SecondsFromPRTime(PRTime prTime);
Packit f0b94e
Packit f0b94e
  imgCacheEntry(imgLoader* loader, imgRequest* request,
Packit f0b94e
                bool aForcePrincipalCheck);
Packit f0b94e
  ~imgCacheEntry();
Packit f0b94e
Packit f0b94e
  nsrefcnt AddRef() {
Packit f0b94e
    NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt");
Packit f0b94e
    NS_ASSERT_OWNINGTHREAD(imgCacheEntry);
Packit f0b94e
    ++mRefCnt;
Packit f0b94e
    NS_LOG_ADDREF(this, mRefCnt, "imgCacheEntry", sizeof(*this));
Packit f0b94e
    return mRefCnt;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  nsrefcnt Release() {
Packit f0b94e
    NS_PRECONDITION(0 != mRefCnt, "dup release");
Packit f0b94e
    NS_ASSERT_OWNINGTHREAD(imgCacheEntry);
Packit f0b94e
    --mRefCnt;
Packit f0b94e
    NS_LOG_RELEASE(this, mRefCnt, "imgCacheEntry");
Packit f0b94e
    if (mRefCnt == 0) {
Packit f0b94e
      mRefCnt = 1; /* stabilize */
Packit f0b94e
      delete this;
Packit f0b94e
      return 0;
Packit f0b94e
    }
Packit f0b94e
    return mRefCnt;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  uint32_t GetDataSize() const { return mDataSize; }
Packit f0b94e
  void SetDataSize(uint32_t aDataSize) {
Packit f0b94e
    int32_t oldsize = mDataSize;
Packit f0b94e
    mDataSize = aDataSize;
Packit f0b94e
    UpdateCache(mDataSize - oldsize);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  int32_t GetTouchedTime() const { return mTouchedTime; }
Packit f0b94e
  void SetTouchedTime(int32_t time) {
Packit f0b94e
    mTouchedTime = time;
Packit f0b94e
    Touch(/* updateTime = */ false);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  uint32_t GetLoadTime() const { return mLoadTime; }
Packit f0b94e
Packit f0b94e
  void UpdateLoadTime();
Packit f0b94e
Packit f0b94e
  int32_t GetExpiryTime() const { return mExpiryTime; }
Packit f0b94e
  void SetExpiryTime(int32_t aExpiryTime) {
Packit f0b94e
    mExpiryTime = aExpiryTime;
Packit f0b94e
    Touch();
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  bool GetMustValidate() const { return mMustValidate; }
Packit f0b94e
  void SetMustValidate(bool aValidate) {
Packit f0b94e
    mMustValidate = aValidate;
Packit f0b94e
    Touch();
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  already_AddRefed<imgRequest> GetRequest() const {
Packit f0b94e
    RefPtr<imgRequest> req = mRequest;
Packit f0b94e
    return req.forget();
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  bool Evicted() const { return mEvicted; }
Packit f0b94e
Packit f0b94e
  nsExpirationState* GetExpirationState() { return &mExpirationState; }
Packit f0b94e
Packit f0b94e
  bool HasNoProxies() const { return mHasNoProxies; }
Packit f0b94e
Packit f0b94e
  bool ForcePrincipalCheck() const { return mForcePrincipalCheck; }
Packit f0b94e
Packit f0b94e
  imgLoader* Loader() const { return mLoader; }
Packit f0b94e
Packit f0b94e
 private:  // methods
Packit f0b94e
  friend class imgLoader;
Packit f0b94e
  friend class imgCacheQueue;
Packit f0b94e
  void Touch(bool updateTime = true);
Packit f0b94e
  void UpdateCache(int32_t diff = 0);
Packit f0b94e
  void SetEvicted(bool evict) { mEvicted = evict; }
Packit f0b94e
  void SetHasNoProxies(bool hasNoProxies);
Packit f0b94e
Packit f0b94e
  // Private, unimplemented copy constructor.
Packit f0b94e
  imgCacheEntry(const imgCacheEntry&);
Packit f0b94e
Packit f0b94e
 private:  // data
Packit f0b94e
  nsAutoRefCnt mRefCnt;
Packit f0b94e
  NS_DECL_OWNINGTHREAD
Packit f0b94e
Packit f0b94e
  imgLoader* mLoader;
Packit f0b94e
  RefPtr<imgRequest> mRequest;
Packit f0b94e
  uint32_t mDataSize;
Packit f0b94e
  int32_t mTouchedTime;
Packit f0b94e
  uint32_t mLoadTime;
Packit f0b94e
  int32_t mExpiryTime;
Packit f0b94e
  nsExpirationState mExpirationState;
Packit f0b94e
  bool mMustValidate : 1;
Packit f0b94e
  bool mEvicted : 1;
Packit f0b94e
  bool mHasNoProxies : 1;
Packit f0b94e
  bool mForcePrincipalCheck : 1;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
#include <vector>
Packit f0b94e
Packit f0b94e
#define NS_IMGLOADER_CID                             \
Packit f0b94e
  { /* c1354898-e3fe-4602-88a7-c4520c21cb4e */       \
Packit f0b94e
    0xc1354898, 0xe3fe, 0x4602, {                    \
Packit f0b94e
      0x88, 0xa7, 0xc4, 0x52, 0x0c, 0x21, 0xcb, 0x4e \
Packit f0b94e
    }                                                \
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
class imgCacheQueue {
Packit f0b94e
 public:
Packit f0b94e
  imgCacheQueue();
Packit f0b94e
  void Remove(imgCacheEntry*);
Packit f0b94e
  void Push(imgCacheEntry*);
Packit f0b94e
  void MarkDirty();
Packit f0b94e
  bool IsDirty();
Packit f0b94e
  already_AddRefed<imgCacheEntry> Pop();
Packit f0b94e
  void Refresh();
Packit f0b94e
  uint32_t GetSize() const;
Packit f0b94e
  void UpdateSize(int32_t diff);
Packit f0b94e
  uint32_t GetNumElements() const;
Packit f0b94e
  bool Contains(imgCacheEntry* aEntry) const;
Packit f0b94e
  typedef nsTArray<RefPtr<imgCacheEntry>> queueContainer;
Packit f0b94e
  typedef queueContainer::iterator iterator;
Packit f0b94e
  typedef queueContainer::const_iterator const_iterator;
Packit f0b94e
Packit f0b94e
  iterator begin();
Packit f0b94e
  const_iterator begin() const;
Packit f0b94e
  iterator end();
Packit f0b94e
  const_iterator end() const;
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  queueContainer mQueue;
Packit f0b94e
  bool mDirty;
Packit f0b94e
  uint32_t mSize;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
enum class AcceptedMimeTypes : uint8_t {
Packit f0b94e
  IMAGES,
Packit f0b94e
  IMAGES_AND_DOCUMENTS,
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
class imgLoader final : public imgILoader,
Packit f0b94e
                        public nsIContentSniffer,
Packit f0b94e
                        public imgICache,
Packit f0b94e
                        public nsSupportsWeakReference,
Packit f0b94e
                        public nsIObserver {
Packit f0b94e
  virtual ~imgLoader();
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  typedef mozilla::image::ImageCacheKey ImageCacheKey;
Packit f0b94e
  typedef mozilla::image::ImageURL ImageURL;
Packit f0b94e
  typedef nsRefPtrHashtable<nsGenericHashKey<ImageCacheKey>, imgCacheEntry>
Packit f0b94e
      imgCacheTable;
Packit f0b94e
  typedef nsTHashtable<nsPtrHashKey<imgRequest>> imgSet;
Packit f0b94e
  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
Packit f0b94e
  typedef mozilla::Mutex Mutex;
Packit f0b94e
Packit f0b94e
  NS_DECL_ISUPPORTS
Packit f0b94e
  NS_DECL_IMGILOADER
Packit f0b94e
  NS_DECL_NSICONTENTSNIFFER
Packit f0b94e
  NS_DECL_IMGICACHE
Packit f0b94e
  NS_DECL_NSIOBSERVER
Packit f0b94e
Packit f0b94e
  /**
Packit f0b94e
   * Get the normal image loader instance that is used by gecko code, creating
Packit f0b94e
   * it if necessary.
Packit f0b94e
   */
Packit f0b94e
  static imgLoader* NormalLoader();
Packit f0b94e
Packit f0b94e
  /**
Packit f0b94e
   * Get the Private Browsing image loader instance that is used by gecko code,
Packit f0b94e
   * creating it if necessary.
Packit f0b94e
   */
Packit f0b94e
  static imgLoader* PrivateBrowsingLoader();
Packit f0b94e
Packit f0b94e
  /**
Packit f0b94e
   * Gecko code should use NormalLoader() or PrivateBrowsingLoader() to get the
Packit f0b94e
   * appropriate image loader.
Packit f0b94e
   *
Packit f0b94e
   * This constructor is public because the XPCOM module code that creates
Packit f0b94e
   * instances of "@mozilla.org/image/loader;1" / "@mozilla.org/image/cache;1"
Packit f0b94e
   * for nsIComponentManager.createInstance()/nsIServiceManager.getService()
Packit f0b94e
   * calls (now only made by add-ons) needs access to it.
Packit f0b94e
   *
Packit f0b94e
   * XXX We would like to get rid of the nsIServiceManager.getService (and
Packit f0b94e
   * nsIComponentManager.createInstance) method of creating imgLoader objects,
Packit f0b94e
   * but there are add-ons that are still using it.  These add-ons don't
Packit f0b94e
   * actually do anything useful with the loaders that they create since nobody
Packit f0b94e
   * who creates an imgLoader using this method actually QIs to imgILoader and
Packit f0b94e
   * loads images.  They all just QI to imgICache and either call clearCache()
Packit f0b94e
   * or findEntryProperties().  Since they're doing this on an imgLoader that
Packit f0b94e
   * has never loaded images, these calls are useless.  It seems likely that
Packit f0b94e
   * the code that is doing this is just legacy code left over from a time when
Packit f0b94e
   * there was only one imgLoader instance for the entire process.  (Nowadays
Packit f0b94e
   * the correct method to get an imgILoader/imgICache is to call
Packit f0b94e
   * imgITools::getImgCacheForDocument/imgITools::getImgLoaderForDocument.)
Packit f0b94e
   * All the same, even though what these add-ons are doing is a no-op,
Packit f0b94e
   * removing the nsIServiceManager.getService method of creating/getting an
Packit f0b94e
   * imgLoader objects would cause an exception in these add-ons that could
Packit f0b94e
   * break things.
Packit f0b94e
   */
Packit f0b94e
  imgLoader();
Packit f0b94e
  nsresult Init();
Packit f0b94e
Packit f0b94e
  MOZ_MUST_USE nsresult
Packit f0b94e
  LoadImage(nsIURI* aURI, nsIURI* aInitialDocumentURI, nsIURI* aReferrerURI,
Packit f0b94e
            ReferrerPolicy aReferrerPolicy, nsIPrincipal* aLoadingPrincipal,
Packit f0b94e
            uint64_t aRequestContextID, nsILoadGroup* aLoadGroup,
Packit f0b94e
            imgINotificationObserver* aObserver, nsINode* aContext,
Packit f0b94e
            nsIDocument* aLoadingDocument, nsLoadFlags aLoadFlags,
Packit f0b94e
            nsISupports* aCacheKey, nsContentPolicyType aContentPolicyType,
Packit f0b94e
            const nsAString& initiatorType, bool aUseUrgentStartForChannel,
Packit f0b94e
            imgRequestProxy** _retval);
Packit f0b94e
Packit f0b94e
  MOZ_MUST_USE nsresult
Packit f0b94e
  LoadImageWithChannel(nsIChannel* channel, imgINotificationObserver* aObserver,
Packit f0b94e
                       nsISupports* aCX, nsIStreamListener** listener,
Packit f0b94e
                       imgRequestProxy** _retval);
Packit f0b94e
Packit f0b94e
  static nsresult GetMimeTypeFromContent(const char* aContents,
Packit f0b94e
                                         uint32_t aLength,
Packit f0b94e
                                         nsACString& aContentType);
Packit f0b94e
Packit f0b94e
  /**
Packit f0b94e
   * Returns true if the given mime type may be interpreted as an image.
Packit f0b94e
   *
Packit f0b94e
   * Some MIME types may be interpreted as both images and documents. (At the
Packit f0b94e
   * moment only "image/svg+xml" falls into this category, but there may be more
Packit f0b94e
   * in the future.) Callers which want this function to return true for such
Packit f0b94e
   * MIME types should pass AcceptedMimeTypes::IMAGES_AND_DOCUMENTS for
Packit f0b94e
   * @aAccept.
Packit f0b94e
   *
Packit f0b94e
   * @param aMimeType The MIME type to evaluate.
Packit f0b94e
   * @param aAcceptedMimeTypes Which kinds of MIME types to treat as images.
Packit f0b94e
   */
Packit f0b94e
  static bool SupportImageWithMimeType(
Packit f0b94e
      const char* aMimeType,
Packit f0b94e
      AcceptedMimeTypes aAccept = AcceptedMimeTypes::IMAGES);
Packit f0b94e
Packit f0b94e
  static void GlobalInit();  // for use by the factory
Packit f0b94e
  static void Shutdown();    // for use by the factory
Packit f0b94e
  static void ShutdownMemoryReporter();
Packit f0b94e
Packit f0b94e
  nsresult ClearChromeImageCache();
Packit f0b94e
  nsresult ClearImageCache();
Packit f0b94e
  void MinimizeCaches();
Packit f0b94e
Packit f0b94e
  nsresult InitCache();
Packit f0b94e
Packit f0b94e
  bool RemoveFromCache(const ImageCacheKey& aKey);
Packit f0b94e
Packit f0b94e
  // Enumeration describing if a given entry is in the cache queue or not.
Packit f0b94e
  // There are some cases we know the entry is definitely not in the queue.
Packit f0b94e
  enum class QueueState { MaybeExists, AlreadyRemoved };
Packit f0b94e
Packit f0b94e
  bool RemoveFromCache(imgCacheEntry* entry,
Packit f0b94e
                       QueueState aQueueState = QueueState::MaybeExists);
Packit f0b94e
Packit f0b94e
  bool PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* aEntry);
Packit f0b94e
Packit f0b94e
  void AddToUncachedImages(imgRequest* aRequest);
Packit f0b94e
  void RemoveFromUncachedImages(imgRequest* aRequest);
Packit f0b94e
Packit f0b94e
  // Returns true if we should prefer evicting cache entry |two| over cache
Packit f0b94e
  // entry |one|.
Packit f0b94e
  // This mixes units in the worst way, but provides reasonable results.
Packit f0b94e
  inline static bool CompareCacheEntries(const RefPtr<imgCacheEntry>& one,
Packit f0b94e
                                         const RefPtr<imgCacheEntry>& two) {
Packit f0b94e
    if (!one) {
Packit f0b94e
      return false;
Packit f0b94e
    }
Packit f0b94e
    if (!two) {
Packit f0b94e
      return true;
Packit f0b94e
    }
Packit f0b94e
Packit f0b94e
    const double sizeweight = 1.0 - sCacheTimeWeight;
Packit f0b94e
Packit f0b94e
    // We want large, old images to be evicted first (depending on their
Packit f0b94e
    // relative weights). Since a larger time is actually newer, we subtract
Packit f0b94e
    // time's weight, so an older image has a larger weight.
Packit f0b94e
    double oneweight = double(one->GetDataSize()) * sizeweight -
Packit f0b94e
                       double(one->GetTouchedTime()) * sCacheTimeWeight;
Packit f0b94e
    double twoweight = double(two->GetDataSize()) * sizeweight -
Packit f0b94e
                       double(two->GetTouchedTime()) * sCacheTimeWeight;
Packit f0b94e
Packit f0b94e
    return oneweight < twoweight;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  void VerifyCacheSizes();
Packit f0b94e
Packit f0b94e
  // The image loader maintains a hash table of all imgCacheEntries. However,
Packit f0b94e
  // only some of them will be evicted from the cache: those who have no
Packit f0b94e
  // imgRequestProxies watching their imgRequests.
Packit f0b94e
  //
Packit f0b94e
  // Once an imgRequest has no imgRequestProxies, it should notify us by
Packit f0b94e
  // calling HasNoObservers(), and null out its cache entry pointer.
Packit f0b94e
  //
Packit f0b94e
  // Upon having a proxy start observing again, it should notify us by calling
Packit f0b94e
  // HasObservers(). The request's cache entry will be re-set before this
Packit f0b94e
  // happens, by calling imgRequest::SetCacheEntry() when an entry with no
Packit f0b94e
  // observers is re-requested.
Packit f0b94e
  bool SetHasNoProxies(imgRequest* aRequest, imgCacheEntry* aEntry);
Packit f0b94e
  bool SetHasProxies(imgRequest* aRequest);
Packit f0b94e
Packit f0b94e
 private:  // methods
Packit f0b94e
  static already_AddRefed<imgLoader> CreateImageLoader();
Packit f0b94e
Packit f0b94e
  bool ValidateEntry(imgCacheEntry* aEntry, nsIURI* aKey,
Packit f0b94e
                     nsIURI* aInitialDocumentURI, nsIURI* aReferrerURI,
Packit f0b94e
                     ReferrerPolicy aReferrerPolicy, nsILoadGroup* aLoadGroup,
Packit f0b94e
                     imgINotificationObserver* aObserver, nsISupports* aCX,
Packit f0b94e
                     nsIDocument* aLoadingDocument, nsLoadFlags aLoadFlags,
Packit f0b94e
                     nsContentPolicyType aContentPolicyType,
Packit f0b94e
                     bool aCanMakeNewChannel, imgRequestProxy** aProxyRequest,
Packit f0b94e
                     nsIPrincipal* aLoadingPrincipal, int32_t aCORSMode);
Packit f0b94e
Packit f0b94e
  bool ValidateRequestWithNewChannel(
Packit f0b94e
      imgRequest* request, nsIURI* aURI, nsIURI* aInitialDocumentURI,
Packit f0b94e
      nsIURI* aReferrerURI, ReferrerPolicy aReferrerPolicy,
Packit f0b94e
      nsILoadGroup* aLoadGroup, imgINotificationObserver* aObserver,
Packit f0b94e
      nsISupports* aCX, nsIDocument* aLoadingDocument, nsLoadFlags aLoadFlags,
Packit f0b94e
      nsContentPolicyType aContentPolicyType, imgRequestProxy** aProxyRequest,
Packit f0b94e
      nsIPrincipal* aLoadingPrincipal, int32_t aCORSMode);
Packit f0b94e
Packit f0b94e
  nsresult CreateNewProxyForRequest(imgRequest* aRequest,
Packit f0b94e
                                    nsILoadGroup* aLoadGroup,
Packit f0b94e
                                    nsIDocument* aLoadingDocument,
Packit f0b94e
                                    imgINotificationObserver* aObserver,
Packit f0b94e
                                    nsLoadFlags aLoadFlags,
Packit f0b94e
                                    imgRequestProxy** _retval);
Packit f0b94e
Packit f0b94e
  void ReadAcceptHeaderPref();
Packit f0b94e
Packit f0b94e
  nsresult EvictEntries(imgCacheTable& aCacheToClear);
Packit f0b94e
  nsresult EvictEntries(imgCacheQueue& aQueueToClear);
Packit f0b94e
Packit f0b94e
  imgCacheTable& GetCache(bool aForChrome);
Packit f0b94e
  imgCacheTable& GetCache(const ImageCacheKey& aKey);
Packit f0b94e
  imgCacheQueue& GetCacheQueue(bool aForChrome);
Packit f0b94e
  imgCacheQueue& GetCacheQueue(const ImageCacheKey& aKey);
Packit f0b94e
  void CacheEntriesChanged(bool aForChrome, int32_t aSizeDiff = 0);
Packit f0b94e
  void CheckCacheLimits(imgCacheTable& cache, imgCacheQueue& queue);
Packit f0b94e
Packit f0b94e
 private:  // data
Packit f0b94e
  friend class imgCacheEntry;
Packit f0b94e
  friend class imgMemoryReporter;
Packit f0b94e
Packit f0b94e
  imgCacheTable mCache;
Packit f0b94e
  imgCacheQueue mCacheQueue;
Packit f0b94e
Packit f0b94e
  imgCacheTable mChromeCache;
Packit f0b94e
  imgCacheQueue mChromeCacheQueue;
Packit f0b94e
Packit f0b94e
  // Hash set of every imgRequest for this loader that isn't in mCache or
Packit f0b94e
  // mChromeCache. The union over all imgLoader's of mCache, mChromeCache, and
Packit f0b94e
  // mUncachedImages should be every imgRequest that is alive. These are weak
Packit f0b94e
  // pointers so we rely on the imgRequest destructor to remove itself.
Packit f0b94e
  imgSet mUncachedImages;
Packit f0b94e
  // The imgRequest can have refs to them held on non-main thread, so we need
Packit f0b94e
  // a mutex because we modify the uncached images set from the imgRequest
Packit f0b94e
  // destructor.
Packit f0b94e
  Mutex mUncachedImagesMutex;
Packit f0b94e
Packit f0b94e
  static double sCacheTimeWeight;
Packit f0b94e
  static uint32_t sCacheMaxSize;
Packit f0b94e
  static imgMemoryReporter* sMemReporter;
Packit f0b94e
Packit f0b94e
  nsCString mAcceptHeader;
Packit f0b94e
Packit f0b94e
  mozilla::UniquePtr<imgCacheExpirationTracker> mCacheTracker;
Packit f0b94e
  bool mRespectPrivacy;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
/**
Packit f0b94e
 * proxy stream listener class used to handle multipart/x-mixed-replace
Packit f0b94e
 */
Packit f0b94e
Packit f0b94e
#include "nsCOMPtr.h"
Packit f0b94e
#include "nsIStreamListener.h"
Packit f0b94e
#include "nsIThreadRetargetableStreamListener.h"
Packit f0b94e
Packit f0b94e
class ProxyListener : public nsIStreamListener,
Packit f0b94e
                      public nsIThreadRetargetableStreamListener {
Packit f0b94e
 public:
Packit f0b94e
  explicit ProxyListener(nsIStreamListener* dest);
Packit f0b94e
Packit f0b94e
  /* additional members */
Packit f0b94e
  NS_DECL_THREADSAFE_ISUPPORTS
Packit f0b94e
  NS_DECL_NSISTREAMLISTENER
Packit f0b94e
  NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
Packit f0b94e
  NS_DECL_NSIREQUESTOBSERVER
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  virtual ~ProxyListener();
Packit f0b94e
Packit f0b94e
  nsCOMPtr<nsIStreamListener> mDestListener;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
/**
Packit f0b94e
 * A class that implements nsIProgressEventSink and forwards all calls to it to
Packit f0b94e
 * the original notification callbacks of the channel. Also implements
Packit f0b94e
 * nsIInterfaceRequestor and gives out itself for nsIProgressEventSink calls,
Packit f0b94e
 * and forwards everything else to the channel's notification callbacks.
Packit f0b94e
 */
Packit f0b94e
class nsProgressNotificationProxy final : public nsIProgressEventSink,
Packit f0b94e
                                          public nsIChannelEventSink,
Packit f0b94e
                                          public nsIInterfaceRequestor {
Packit f0b94e
 public:
Packit f0b94e
  nsProgressNotificationProxy(nsIChannel* channel, imgIRequest* proxy)
Packit f0b94e
      : mImageRequest(proxy) {
Packit f0b94e
    channel->GetNotificationCallbacks(getter_AddRefs(mOriginalCallbacks));
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  NS_DECL_ISUPPORTS
Packit f0b94e
  NS_DECL_NSIPROGRESSEVENTSINK
Packit f0b94e
  NS_DECL_NSICHANNELEVENTSINK
Packit f0b94e
  NS_DECL_NSIINTERFACEREQUESTOR
Packit f0b94e
 private:
Packit f0b94e
  ~nsProgressNotificationProxy() {}
Packit f0b94e
Packit f0b94e
  nsCOMPtr<nsIInterfaceRequestor> mOriginalCallbacks;
Packit f0b94e
  nsCOMPtr<nsIRequest> mImageRequest;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
/**
Packit f0b94e
 * validate checker
Packit f0b94e
 */
Packit f0b94e
Packit f0b94e
#include "nsCOMArray.h"
Packit f0b94e
Packit f0b94e
class imgCacheValidator : public nsIStreamListener,
Packit f0b94e
                          public nsIThreadRetargetableStreamListener,
Packit f0b94e
                          public nsIChannelEventSink,
Packit f0b94e
                          public nsIInterfaceRequestor,
Packit f0b94e
                          public nsIAsyncVerifyRedirectCallback {
Packit f0b94e
 public:
Packit f0b94e
  imgCacheValidator(nsProgressNotificationProxy* progress, imgLoader* loader,
Packit f0b94e
                    imgRequest* aRequest, nsISupports* aContext,
Packit f0b94e
                    bool forcePrincipalCheckForCacheEntry);
Packit f0b94e
Packit f0b94e
  void AddProxy(imgRequestProxy* aProxy);
Packit f0b94e
  void RemoveProxy(imgRequestProxy* aProxy);
Packit f0b94e
Packit f0b94e
  NS_DECL_THREADSAFE_ISUPPORTS
Packit f0b94e
  NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
Packit f0b94e
  NS_DECL_NSISTREAMLISTENER
Packit f0b94e
  NS_DECL_NSIREQUESTOBSERVER
Packit f0b94e
  NS_DECL_NSICHANNELEVENTSINK
Packit f0b94e
  NS_DECL_NSIINTERFACEREQUESTOR
Packit f0b94e
  NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  void UpdateProxies(bool aCancelRequest, bool aSyncNotify);
Packit f0b94e
  virtual ~imgCacheValidator();
Packit f0b94e
Packit f0b94e
  nsCOMPtr<nsIStreamListener> mDestListener;
Packit f0b94e
  RefPtr<nsProgressNotificationProxy> mProgressProxy;
Packit f0b94e
  nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
Packit f0b94e
  nsCOMPtr<nsIChannel> mRedirectChannel;
Packit f0b94e
Packit f0b94e
  RefPtr<imgRequest> mRequest;
Packit f0b94e
  AutoTArray<RefPtr<imgRequestProxy>, 4> mProxies;
Packit f0b94e
Packit f0b94e
  RefPtr<imgRequest> mNewRequest;
Packit f0b94e
  RefPtr<imgCacheEntry> mNewEntry;
Packit f0b94e
Packit f0b94e
  nsCOMPtr<nsISupports> mContext;
Packit f0b94e
Packit f0b94e
  imgLoader* mImgLoader;
Packit f0b94e
Packit f0b94e
  bool mHadInsecureRedirect;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
#endif  // mozilla_image_imgLoader_h