imgRequest.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. #ifndef mozilla_image_imgRequest_h
  7. #define mozilla_image_imgRequest_h
  8. #include "nsIChannelEventSink.h"
  9. #include "nsIInterfaceRequestor.h"
  10. #include "nsIStreamListener.h"
  11. #include "nsIThreadRetargetableStreamListener.h"
  12. #include "nsIPrincipal.h"
  13. #include "nsCOMPtr.h"
  14. #include "nsProxyRelease.h"
  15. #include "nsStringGlue.h"
  16. #include "nsError.h"
  17. #include "nsIAsyncVerifyRedirectCallback.h"
  18. #include "mozilla/Mutex.h"
  19. #include "mozilla/net/ReferrerPolicy.h"
  20. #include "ImageCacheKey.h"
  21. class imgCacheValidator;
  22. class imgLoader;
  23. class imgRequestProxy;
  24. class imgCacheEntry;
  25. class nsIApplicationCache;
  26. class nsIProperties;
  27. class nsIRequest;
  28. class nsITimedChannel;
  29. class nsIURI;
  30. namespace mozilla {
  31. namespace image {
  32. class Image;
  33. class ImageURL;
  34. class ProgressTracker;
  35. } // namespace image
  36. } // namespace mozilla
  37. struct NewPartResult;
  38. class imgRequest final : public nsIStreamListener,
  39. public nsIThreadRetargetableStreamListener,
  40. public nsIChannelEventSink,
  41. public nsIInterfaceRequestor,
  42. public nsIAsyncVerifyRedirectCallback
  43. {
  44. typedef mozilla::image::Image Image;
  45. typedef mozilla::image::ImageCacheKey ImageCacheKey;
  46. typedef mozilla::image::ImageURL ImageURL;
  47. typedef mozilla::image::ProgressTracker ProgressTracker;
  48. typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
  49. public:
  50. imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey);
  51. NS_DECL_THREADSAFE_ISUPPORTS
  52. NS_DECL_NSISTREAMLISTENER
  53. NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
  54. NS_DECL_NSIREQUESTOBSERVER
  55. NS_DECL_NSICHANNELEVENTSINK
  56. NS_DECL_NSIINTERFACEREQUESTOR
  57. NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
  58. MOZ_MUST_USE nsresult Init(nsIURI* aURI,
  59. nsIURI* aCurrentURI,
  60. bool aHadInsecureRedirect,
  61. nsIRequest* aRequest,
  62. nsIChannel* aChannel,
  63. imgCacheEntry* aCacheEntry,
  64. nsISupports* aCX,
  65. nsIPrincipal* aLoadingPrincipal,
  66. int32_t aCORSMode,
  67. ReferrerPolicy aReferrerPolicy);
  68. void ClearLoader();
  69. // Callers must call imgRequestProxy::Notify later.
  70. void AddProxy(imgRequestProxy* proxy);
  71. nsresult RemoveProxy(imgRequestProxy* proxy, nsresult aStatus);
  72. // Cancel, but also ensure that all work done in Init() is undone. Call this
  73. // only when the channel has failed to open, and so calling Cancel() on it
  74. // won't be sufficient.
  75. void CancelAndAbort(nsresult aStatus);
  76. // Called or dispatched by cancel for main thread only execution.
  77. void ContinueCancel(nsresult aStatus);
  78. // Called or dispatched by EvictFromCache for main thread only execution.
  79. void ContinueEvict();
  80. // Request that we start decoding the image as soon as data becomes available.
  81. void StartDecoding();
  82. inline uint64_t InnerWindowID() const {
  83. return mInnerWindowId;
  84. }
  85. // Set the cache validation information (expiry time, whether we must
  86. // validate, etc) on the cache entry based on the request information.
  87. // If this function is called multiple times, the information set earliest
  88. // wins.
  89. static void SetCacheValidation(imgCacheEntry* aEntry, nsIRequest* aRequest);
  90. // Check if application cache of the original load is different from
  91. // application cache of the new load. Also lack of application cache
  92. // on one of the loads is considered a change of a loading cache since
  93. // HTTP cache may contain a different data then app cache.
  94. bool CacheChanged(nsIRequest* aNewRequest);
  95. bool GetMultipart() const;
  96. // Returns whether we went through an insecure (non-HTTPS) redirect at some
  97. // point during loading. This does not consider the current URI.
  98. bool HadInsecureRedirect() const;
  99. // The CORS mode for which we loaded this image.
  100. int32_t GetCORSMode() const { return mCORSMode; }
  101. // The Referrer Policy in effect when loading this image.
  102. ReferrerPolicy GetReferrerPolicy() const { return mReferrerPolicy; }
  103. // The principal for the document that loaded this image. Used when trying to
  104. // validate a CORS image load.
  105. already_AddRefed<nsIPrincipal> GetLoadingPrincipal() const
  106. {
  107. nsCOMPtr<nsIPrincipal> principal = mLoadingPrincipal;
  108. return principal.forget();
  109. }
  110. // Return the ProgressTracker associated with this imgRequest. It may live
  111. // in |mProgressTracker| or in |mImage.mProgressTracker|, depending on whether
  112. // mImage has been instantiated yet.
  113. already_AddRefed<ProgressTracker> GetProgressTracker() const;
  114. /// Returns the Image associated with this imgRequest, if it's ready.
  115. already_AddRefed<Image> GetImage() const;
  116. // Get the current principal of the image. No AddRefing.
  117. inline nsIPrincipal* GetPrincipal() const { return mPrincipal.get(); }
  118. /// Get the ImageCacheKey associated with this request.
  119. const ImageCacheKey& CacheKey() const { return mCacheKey; }
  120. // Resize the cache entry to 0 if it exists
  121. void ResetCacheEntry();
  122. // OK to use on any thread.
  123. nsresult GetURI(ImageURL** aURI);
  124. nsresult GetCurrentURI(nsIURI** aURI);
  125. bool IsChrome() const;
  126. nsresult GetImageErrorCode(void);
  127. /// Returns true if we've received any data.
  128. bool HasTransferredData() const;
  129. /// Returns a non-owning pointer to this imgRequest's MIME type.
  130. const char* GetMimeType() const { return mContentType.get(); }
  131. /// @return the priority of the underlying network request, or
  132. /// PRIORITY_NORMAL if it doesn't support nsISupportsPriority.
  133. int32_t Priority() const;
  134. /// Adjust the priority of the underlying network request by @aDelta on behalf
  135. /// of @aProxy.
  136. void AdjustPriority(imgRequestProxy* aProxy, int32_t aDelta);
  137. /// Returns a weak pointer to the underlying request.
  138. nsIRequest* GetRequest() const { return mRequest; }
  139. nsITimedChannel* GetTimedChannel() const { return mTimedChannel; }
  140. nsresult GetSecurityInfo(nsISupports** aSecurityInfoOut);
  141. imgCacheValidator* GetValidator() const { return mValidator; }
  142. void SetValidator(imgCacheValidator* aValidator) { mValidator = aValidator; }
  143. void* LoadId() const { return mLoadId; }
  144. void SetLoadId(void* aLoadId) { mLoadId = aLoadId; }
  145. /// Reset the cache entry after we've dropped our reference to it. Used by
  146. /// imgLoader when our cache entry is re-requested after we've dropped our
  147. /// reference to it.
  148. void SetCacheEntry(imgCacheEntry* aEntry);
  149. /// Returns whether we've got a reference to the cache entry.
  150. bool HasCacheEntry() const;
  151. /// Set whether this request is stored in the cache. If it isn't, regardless
  152. /// of whether this request has a non-null mCacheEntry, this imgRequest won't
  153. /// try to update or modify the image cache.
  154. void SetIsInCache(bool aCacheable);
  155. void EvictFromCache();
  156. void RemoveFromCache();
  157. // Sets properties for this image; will dispatch to main thread if needed.
  158. void SetProperties(const nsACString& aContentType,
  159. const nsACString& aContentDisposition);
  160. nsIProperties* Properties() const { return mProperties; }
  161. bool HasConsumers() const;
  162. private:
  163. friend class FinishPreparingForNewPartRunnable;
  164. virtual ~imgRequest();
  165. void FinishPreparingForNewPart(const NewPartResult& aResult);
  166. void Cancel(nsresult aStatus);
  167. // Update the cache entry size based on the image container.
  168. void UpdateCacheEntrySize();
  169. /// Returns true if StartDecoding() was called.
  170. bool IsDecodeRequested() const;
  171. // Weak reference to parent loader; this request cannot outlive its owner.
  172. imgLoader* mLoader;
  173. nsCOMPtr<nsIRequest> mRequest;
  174. // The original URI we were loaded with. This is the same as the URI we are
  175. // keyed on in the cache. We store a string here to avoid off main thread
  176. // refcounting issues with nsStandardURL.
  177. RefPtr<ImageURL> mURI;
  178. // The URI of the resource we ended up loading after all redirects, etc.
  179. nsCOMPtr<nsIURI> mCurrentURI;
  180. // The principal of the document which loaded this image. Used when
  181. // validating for CORS.
  182. nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
  183. // The principal of this image.
  184. nsCOMPtr<nsIPrincipal> mPrincipal;
  185. nsCOMPtr<nsIProperties> mProperties;
  186. nsCOMPtr<nsISupports> mSecurityInfo;
  187. nsCOMPtr<nsIChannel> mChannel;
  188. nsCOMPtr<nsIInterfaceRequestor> mPrevChannelSink;
  189. nsCOMPtr<nsIApplicationCache> mApplicationCache;
  190. nsCOMPtr<nsITimedChannel> mTimedChannel;
  191. nsCString mContentType;
  192. /* we hold on to this to this so long as we have observers */
  193. RefPtr<imgCacheEntry> mCacheEntry;
  194. /// The key under which this imgRequest is stored in the image cache.
  195. ImageCacheKey mCacheKey;
  196. void* mLoadId;
  197. /// Raw pointer to the first proxy that was added to this imgRequest. Use only
  198. /// pointer comparisons; there's no guarantee this will remain valid.
  199. void* mFirstProxy;
  200. imgCacheValidator* mValidator;
  201. nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
  202. nsCOMPtr<nsIChannel> mNewRedirectChannel;
  203. // The ID of the inner window origin, used for error reporting.
  204. uint64_t mInnerWindowId;
  205. // The CORS mode (defined in imgIRequest) this image was loaded with. By
  206. // default, imgIRequest::CORS_NONE.
  207. int32_t mCORSMode;
  208. // The Referrer Policy (defined in ReferrerPolicy.h) used for this image.
  209. ReferrerPolicy mReferrerPolicy;
  210. nsresult mImageErrorCode;
  211. mutable mozilla::Mutex mMutex;
  212. // Member variables protected by mMutex. Note that *all* flags in our bitfield
  213. // are protected by mMutex; if you're adding a new flag that isn'protected, it
  214. // must not be a part of this bitfield.
  215. RefPtr<ProgressTracker> mProgressTracker;
  216. RefPtr<Image> mImage;
  217. bool mIsMultiPartChannel : 1;
  218. bool mGotData : 1;
  219. bool mIsInCache : 1;
  220. bool mDecodeRequested : 1;
  221. bool mNewPartPending : 1;
  222. bool mHadInsecureRedirect : 1;
  223. };
  224. #endif // mozilla_image_imgRequest_h