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