Backed out changeset 177eae915693 (bug 1206581) for bustage
[gecko.git] / image / imgRequest.h
blob520ca16f59b43a772f67130ad74a2330f2e49222
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"
16 #include "nsCOMPtr.h"
17 #include "nsProxyRelease.h"
18 #include "nsStringGlue.h"
19 #include "nsError.h"
20 #include "nsIAsyncVerifyRedirectCallback.h"
21 #include "mozilla/Mutex.h"
22 #include "mozilla/net/ReferrerPolicy.h"
23 #include "ImageCacheKey.h"
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;
35 namespace mozilla {
36 namespace image {
37 class Image;
38 class ImageURL;
39 class ProgressTracker;
40 } // namespace image
41 } // namespace mozilla
43 struct NewPartResult;
45 class imgRequest final : public nsIStreamListener,
46 public nsIThreadRetargetableStreamListener,
47 public nsIChannelEventSink,
48 public nsIInterfaceRequestor,
49 public nsIAsyncVerifyRedirectCallback
51 typedef mozilla::image::Image Image;
52 typedef mozilla::image::ImageCacheKey ImageCacheKey;
53 typedef mozilla::image::ImageURL ImageURL;
54 typedef mozilla::image::ProgressTracker ProgressTracker;
55 typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
57 public:
58 imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey);
60 NS_DECL_THREADSAFE_ISUPPORTS
61 NS_DECL_NSISTREAMLISTENER
62 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
63 NS_DECL_NSIREQUESTOBSERVER
64 NS_DECL_NSICHANNELEVENTSINK
65 NS_DECL_NSIINTERFACEREQUESTOR
66 NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
68 nsresult Init(nsIURI* aURI,
69 nsIURI* aCurrentURI,
70 bool aHadInsecureRedirect,
71 nsIRequest* aRequest,
72 nsIChannel* aChannel,
73 imgCacheEntry* aCacheEntry,
74 nsISupports* aCX,
75 nsIPrincipal* aLoadingPrincipal,
76 int32_t aCORSMode,
77 ReferrerPolicy aReferrerPolicy);
79 void ClearLoader();
81 // Callers must call imgRequestProxy::Notify later.
82 void AddProxy(imgRequestProxy* proxy);
84 nsresult RemoveProxy(imgRequestProxy* proxy, nsresult aStatus);
86 // Cancel, but also ensure that all work done in Init() is undone. Call this
87 // only when the channel has failed to open, and so calling Cancel() on it
88 // won't be sufficient.
89 void CancelAndAbort(nsresult aStatus);
91 // Called or dispatched by cancel for main thread only execution.
92 void ContinueCancel(nsresult aStatus);
94 // Called or dispatched by EvictFromCache for main thread only execution.
95 void ContinueEvict();
97 // Request that we start decoding the image as soon as data becomes available.
98 void StartDecoding();
100 inline uint64_t InnerWindowID() const {
101 return mInnerWindowId;
104 // Set the cache validation information (expiry time, whether we must
105 // validate, etc) on the cache entry based on the request information.
106 // If this function is called multiple times, the information set earliest
107 // wins.
108 static void SetCacheValidation(imgCacheEntry* aEntry, nsIRequest* aRequest);
110 // Check if application cache of the original load is different from
111 // application cache of the new load. Also lack of application cache
112 // on one of the loads is considered a change of a loading cache since
113 // HTTP cache may contain a different data then app cache.
114 bool CacheChanged(nsIRequest* aNewRequest);
116 bool GetMultipart() const;
118 // Returns whether we went through an insecure (non-HTTPS) redirect at some
119 // point during loading. This does not consider the current URI.
120 bool HadInsecureRedirect() const;
122 // The CORS mode for which we loaded this image.
123 int32_t GetCORSMode() const { return mCORSMode; }
125 // The Referrer Policy in effect when loading this image.
126 ReferrerPolicy GetReferrerPolicy() const { return mReferrerPolicy; }
128 // The principal for the document that loaded this image. Used when trying to
129 // validate a CORS image load.
130 already_AddRefed<nsIPrincipal> GetLoadingPrincipal() const
132 nsCOMPtr<nsIPrincipal> principal = mLoadingPrincipal;
133 return principal.forget();
136 // Return the ProgressTracker associated with this imgRequest. It may live
137 // in |mProgressTracker| or in |mImage.mProgressTracker|, depending on whether
138 // mImage has been instantiated yet.
139 already_AddRefed<ProgressTracker> GetProgressTracker() const;
141 /// Returns the Image associated with this imgRequest, if it's ready.
142 already_AddRefed<Image> GetImage() const;
144 // Get the current principal of the image. No AddRefing.
145 inline nsIPrincipal* GetPrincipal() const { return mPrincipal.get(); }
147 /// Get the ImageCacheKey associated with this request.
148 const ImageCacheKey& CacheKey() const { return mCacheKey; }
150 // Resize the cache entry to 0 if it exists
151 void ResetCacheEntry();
153 // OK to use on any thread.
154 nsresult GetURI(ImageURL** aURI);
155 nsresult GetCurrentURI(nsIURI** aURI);
156 bool IsChrome() const;
158 nsresult GetImageErrorCode(void);
160 /// Returns true if we've received any data.
161 bool HasTransferredData() const;
163 /// Returns a non-owning pointer to this imgRequest's MIME type.
164 const char* GetMimeType() const { return mContentType.get(); }
166 /// @return the priority of the underlying network request, or
167 /// PRIORITY_NORMAL if it doesn't support nsISupportsPriority.
168 int32_t Priority() const;
170 /// Adjust the priority of the underlying network request by @aDelta on behalf
171 /// of @aProxy.
172 void AdjustPriority(imgRequestProxy* aProxy, int32_t aDelta);
174 /// Returns a weak pointer to the underlying request.
175 nsIRequest* GetRequest() const { return mRequest; }
177 nsITimedChannel* GetTimedChannel() const { return mTimedChannel; }
179 nsresult GetSecurityInfo(nsISupports** aSecurityInfoOut);
181 imgCacheValidator* GetValidator() const { return mValidator; }
182 void SetValidator(imgCacheValidator* aValidator) { mValidator = aValidator; }
184 void* LoadId() const { return mLoadId; }
185 void SetLoadId(void* aLoadId) { mLoadId = aLoadId; }
187 /// Reset the cache entry after we've dropped our reference to it. Used by
188 /// imgLoader when our cache entry is re-requested after we've dropped our
189 /// reference to it.
190 void SetCacheEntry(imgCacheEntry* aEntry);
192 /// Returns whether we've got a reference to the cache entry.
193 bool HasCacheEntry() const;
195 /// Set whether this request is stored in the cache. If it isn't, regardless
196 /// of whether this request has a non-null mCacheEntry, this imgRequest won't
197 /// try to update or modify the image cache.
198 void SetIsInCache(bool aCacheable);
200 void EvictFromCache();
201 void RemoveFromCache();
203 // Sets properties for this image; will dispatch to main thread if needed.
204 void SetProperties(const nsACString& aContentType,
205 const nsACString& aContentDisposition);
207 nsIProperties* Properties() const { return mProperties; }
209 bool HasConsumers() const;
211 private:
212 friend class FinishPreparingForNewPartRunnable;
214 virtual ~imgRequest();
216 void FinishPreparingForNewPart(const NewPartResult& aResult);
218 void Cancel(nsresult aStatus);
220 // Update the cache entry size based on the image container.
221 void UpdateCacheEntrySize();
223 /// Returns true if StartDecoding() was called.
224 bool IsDecodeRequested() const;
226 // Weak reference to parent loader; this request cannot outlive its owner.
227 imgLoader* mLoader;
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 RefPtr<ImageURL> mURI;
233 // The URI of the resource we ended up loading after all redirects, etc.
234 nsCOMPtr<nsIURI> mCurrentURI;
235 // The principal of the document which loaded this image. Used when
236 // validating for CORS.
237 nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
238 // The principal of this image.
239 nsCOMPtr<nsIPrincipal> mPrincipal;
240 nsCOMPtr<nsIProperties> mProperties;
241 nsCOMPtr<nsISupports> mSecurityInfo;
242 nsCOMPtr<nsIChannel> mChannel;
243 nsCOMPtr<nsIInterfaceRequestor> mPrevChannelSink;
244 nsCOMPtr<nsIApplicationCache> mApplicationCache;
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;
256 void* mLoadId;
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.
260 void* mFirstProxy;
262 imgCacheValidator* mValidator;
263 nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
264 nsCOMPtr<nsIChannel> mNewRedirectChannel;
266 // The ID of the inner window origin, used for error reporting.
267 uint64_t mInnerWindowId;
269 // The CORS mode (defined in imgIRequest) this image was loaded with. By
270 // default, imgIRequest::CORS_NONE.
271 int32_t mCORSMode;
273 // The Referrer Policy (defined in ReferrerPolicy.h) used for this image.
274 ReferrerPolicy mReferrerPolicy;
276 nsresult mImageErrorCode;
278 mutable mozilla::Mutex mMutex;
280 // Member variables protected by mMutex. Note that *all* flags in our bitfield
281 // are protected by mMutex; if you're adding a new flag that isn'protected, it
282 // must not be a part of this bitfield.
283 RefPtr<ProgressTracker> mProgressTracker;
284 RefPtr<Image> mImage;
285 bool mIsMultiPartChannel : 1;
286 bool mGotData : 1;
287 bool mIsInCache : 1;
288 bool mDecodeRequested : 1;
289 bool mNewPartPending : 1;
290 bool mHadInsecureRedirect : 1;
293 #endif // mozilla_image_imgRequest_h