1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
7 #ifndef mozilla_image_imgRequest_h
8 #define mozilla_image_imgRequest_h
10 #include "nsIChannelEventSink.h"
11 #include "nsIInterfaceRequestor.h"
12 #include "nsIStreamListener.h"
13 #include "nsIThreadRetargetableStreamListener.h"
14 #include "nsIPrincipal.h"
17 #include "nsProxyRelease.h"
20 #include "nsIAsyncVerifyRedirectCallback.h"
21 #include "mozilla/Mutex.h"
22 #include "ImageCacheKey.h"
24 class imgCacheValidator
;
26 class imgRequestProxy
;
30 class nsITimedChannel
;
32 class nsIReferrerInfo
;
35 enum CORSMode
: uint8_t;
38 class ProgressTracker
;
40 } // namespace mozilla
44 class imgRequest final
: public nsIStreamListener
,
45 public nsIThreadRetargetableStreamListener
,
46 public nsIChannelEventSink
,
47 public nsIInterfaceRequestor
,
48 public nsIAsyncVerifyRedirectCallback
{
49 typedef mozilla::image::Image Image
;
50 typedef mozilla::image::ImageCacheKey ImageCacheKey
;
51 typedef mozilla::image::ProgressTracker ProgressTracker
;
52 typedef mozilla::dom::ReferrerPolicy ReferrerPolicy
;
55 imgRequest(imgLoader
* aLoader
, const ImageCacheKey
& aCacheKey
);
57 NS_DECL_THREADSAFE_ISUPPORTS
58 NS_DECL_NSISTREAMLISTENER
59 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
60 NS_DECL_NSIREQUESTOBSERVER
61 NS_DECL_NSICHANNELEVENTSINK
62 NS_DECL_NSIINTERFACEREQUESTOR
63 NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
65 [[nodiscard
]] nsresult
Init(nsIURI
* aURI
, nsIURI
* aFinalURI
,
66 bool aHadInsecureRedirect
, nsIRequest
* aRequest
,
67 nsIChannel
* aChannel
, imgCacheEntry
* aCacheEntry
,
68 mozilla::dom::Document
* aLoadingDocument
,
69 nsIPrincipal
* aTriggeringPrincipal
,
70 mozilla::CORSMode aCORSMode
,
71 nsIReferrerInfo
* aReferrerInfo
);
75 // Callers must call imgRequestProxy::Notify later.
76 void AddProxy(imgRequestProxy
* proxy
);
78 // Whether a given document is allowed to reuse this request without any
80 bool CanReuseWithoutValidation(mozilla::dom::Document
*) const;
82 nsresult
RemoveProxy(imgRequestProxy
* proxy
, nsresult aStatus
);
84 // Cancel, but also ensure that all work done in Init() is undone. Call this
85 // only when the channel has failed to open, and so calling Cancel() on it
86 // won't be sufficient.
87 void CancelAndAbort(nsresult aStatus
);
89 // Called or dispatched by cancel for main thread only execution.
90 void ContinueCancel(nsresult aStatus
);
92 // Called or dispatched by EvictFromCache for main thread only execution.
95 // Request that we start decoding the image as soon as data becomes available.
98 uint64_t InnerWindowID() const;
99 void SetInnerWindowID(uint64_t aInnerWindowId
);
101 // Set the cache validation information (expiry time, whether we must
102 // validate, etc) on the cache entry based on the request information.
103 // If this function is called multiple times, the information set earliest
105 static void SetCacheValidation(imgCacheEntry
* aEntry
, nsIRequest
* aRequest
);
107 bool GetMultipart() const;
109 // Returns whether we went through an insecure (non-HTTPS) redirect at some
110 // point during loading. This does not consider the final URI.
111 bool HadInsecureRedirect() const;
113 // The CORS mode for which we loaded this image.
114 mozilla::CORSMode
GetCORSMode() const { return mCORSMode
; }
116 // The ReferrerInfo in effect when loading this image.
117 nsIReferrerInfo
* GetReferrerInfo() const { return mReferrerInfo
; }
119 // The principal for the document that loaded this image. Used when trying to
120 // validate a CORS image load.
121 already_AddRefed
<nsIPrincipal
> GetTriggeringPrincipal() const {
122 nsCOMPtr
<nsIPrincipal
> principal
= mTriggeringPrincipal
;
123 return principal
.forget();
126 // Return the ProgressTracker associated with this imgRequest. It may live
127 // in |mProgressTracker| or in |mImage.mProgressTracker|, depending on whether
128 // mImage has been instantiated yet.
129 already_AddRefed
<ProgressTracker
> GetProgressTracker() const;
131 /// Returns the Image associated with this imgRequest, if it's ready.
132 already_AddRefed
<Image
> GetImage() const;
134 // Get the current principal of the image. No AddRefing.
135 inline nsIPrincipal
* GetPrincipal() const { return mPrincipal
.get(); }
137 /// Get the ImageCacheKey associated with this request.
138 const ImageCacheKey
& CacheKey() const { return mCacheKey
; }
140 // Resize the cache entry to 0 if it exists
141 void ResetCacheEntry();
143 // OK to use on any thread.
144 nsresult
GetURI(nsIURI
** aURI
);
145 nsresult
GetFinalURI(nsIURI
** aURI
);
146 bool IsChrome() const;
149 nsresult
GetImageErrorCode(void);
151 /// Returns a non-owning pointer to this imgRequest's MIME type.
152 const char* GetMimeType() const { return mContentType
.get(); }
154 void GetFileName(nsACString
& aFileName
);
156 /// @return the priority of the underlying network request, or
157 /// PRIORITY_NORMAL if it doesn't support nsISupportsPriority.
158 int32_t Priority() const;
160 /// Adjust the priority of the underlying network request by @aDelta on behalf
162 void AdjustPriority(imgRequestProxy
* aProxy
, int32_t aDelta
);
164 void BoostPriority(uint32_t aCategory
);
166 /// Returns a weak pointer to the underlying request.
167 nsIRequest
* GetRequest() const { return mRequest
; }
169 nsITimedChannel
* GetTimedChannel() const { return mTimedChannel
; }
171 imgCacheValidator
* GetValidator() const { return mValidator
; }
172 void SetValidator(imgCacheValidator
* aValidator
) { mValidator
= aValidator
; }
174 void* LoadId() const { return mLoadId
; }
175 void SetLoadId(void* aLoadId
) { mLoadId
= aLoadId
; }
177 /// Reset the cache entry after we've dropped our reference to it. Used by
178 /// imgLoader when our cache entry is re-requested after we've dropped our
180 void SetCacheEntry(imgCacheEntry
* aEntry
);
182 /// Returns whether we've got a reference to the cache entry.
183 bool HasCacheEntry() const;
185 /// Set whether this request is stored in the cache. If it isn't, regardless
186 /// of whether this request has a non-null mCacheEntry, this imgRequest won't
187 /// try to update or modify the image cache.
188 void SetIsInCache(bool aCacheable
);
190 void EvictFromCache();
191 void RemoveFromCache();
193 // Sets properties for this image; will dispatch to main thread if needed.
194 void SetProperties(const nsACString
& aContentType
,
195 const nsACString
& aContentDisposition
);
197 nsIProperties
* Properties() const { return mProperties
; }
199 bool HasConsumers() const;
201 bool ImageAvailable() const;
203 bool IsDeniedCrossSiteCORSRequest() const {
204 return mIsDeniedCrossSiteCORSRequest
;
207 bool IsCrossSiteNoCORSRequest() const { return mIsCrossSiteNoCORSRequest
; }
210 friend class FinishPreparingForNewPartRunnable
;
212 virtual ~imgRequest();
214 void FinishPreparingForNewPart(const NewPartResult
& aResult
);
216 void Cancel(nsresult aStatus
);
218 // Update the cache entry size based on the image container.
219 void UpdateCacheEntrySize();
221 /// Returns true if StartDecoding() was called.
222 bool IsDecodeRequested() const;
224 void AdjustPriorityInternal(int32_t aDelta
);
226 // Weak reference to parent loader; this request cannot outlive its owner.
228 nsCOMPtr
<nsIRequest
> mRequest
;
229 // The original URI we were loaded with. This is the same as the URI we are
230 // keyed on in the cache. We store a string here to avoid off main thread
231 // refcounting issues with nsStandardURL.
232 nsCOMPtr
<nsIURI
> mURI
;
233 // The URI of the resource we ended up loading after all redirects, etc.
234 nsCOMPtr
<nsIURI
> mFinalURI
;
235 // The principal which triggered the load of this image. Generally either
236 // the principal of the document the image is being loaded into, or of the
237 // stylesheet which specified the image to load. Used when validating for
239 nsCOMPtr
<nsIPrincipal
> mTriggeringPrincipal
;
240 // The principal of this image.
241 nsCOMPtr
<nsIPrincipal
> mPrincipal
;
242 nsCOMPtr
<nsIProperties
> mProperties
;
243 nsCOMPtr
<nsIChannel
> mChannel
;
244 nsCOMPtr
<nsIInterfaceRequestor
> mPrevChannelSink
;
246 nsCOMPtr
<nsITimedChannel
> mTimedChannel
;
248 nsCString mContentType
;
250 /* we hold on to this to this so long as we have observers */
251 RefPtr
<imgCacheEntry
> mCacheEntry
;
253 /// The key under which this imgRequest is stored in the image cache.
254 ImageCacheKey mCacheKey
;
258 /// Raw pointer to the first proxy that was added to this imgRequest. Use only
259 /// pointer comparisons; there's no guarantee this will remain valid.
262 imgCacheValidator
* mValidator
;
263 nsCOMPtr
<nsIAsyncVerifyRedirectCallback
> mRedirectCallback
;
264 nsCOMPtr
<nsIChannel
> mNewRedirectChannel
;
266 // The CORS mode (defined in imgIRequest) this image was loaded with. By
267 // default, CORS_NONE.
268 mozilla::CORSMode mCORSMode
;
270 // The ReferrerInfo used for this image.
271 nsCOMPtr
<nsIReferrerInfo
> mReferrerInfo
;
273 nsresult mImageErrorCode
;
275 // The categories of prioritization strategy that have been requested.
276 uint32_t mBoostCategoriesRequested
= 0;
278 // If we've called OnImageAvailable.
279 bool mImageAvailable
;
280 bool mIsDeniedCrossSiteCORSRequest
;
281 bool mIsCrossSiteNoCORSRequest
;
283 mutable mozilla::Mutex mMutex
;
285 // Member variables protected by mMutex. Note that *all* flags in our bitfield
286 // are protected by mMutex; if you're adding a new flag that isn'protected, it
287 // must not be a part of this bitfield.
288 RefPtr
<ProgressTracker
> mProgressTracker
GUARDED_BY(mMutex
);
289 RefPtr
<Image
> mImage
GUARDED_BY(mMutex
);
290 bool mIsMultiPartChannel
: 1 GUARDED_BY(mMutex
);
291 bool mIsInCache
: 1 GUARDED_BY(mMutex
);
292 bool mDecodeRequested
: 1 GUARDED_BY(mMutex
);
293 bool mNewPartPending
: 1 GUARDED_BY(mMutex
);
294 bool mHadInsecureRedirect
: 1 GUARDED_BY(mMutex
);
295 // The ID of the inner window origin, used for error reporting.
296 uint64_t mInnerWindowId
GUARDED_BY(mMutex
);
299 #endif // mozilla_image_imgRequest_h