diff options
Diffstat (limited to 'image/imgRequest.h')
-rw-r--r-- | image/imgRequest.h | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/image/imgRequest.h b/image/imgRequest.h new file mode 100644 index 000000000..c05e6a4a9 --- /dev/null +++ b/image/imgRequest.h @@ -0,0 +1,293 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_image_imgRequest_h +#define mozilla_image_imgRequest_h + +#include "nsIChannelEventSink.h" +#include "nsIInterfaceRequestor.h" +#include "nsIStreamListener.h" +#include "nsIThreadRetargetableStreamListener.h" +#include "nsIPrincipal.h" + +#include "nsCOMPtr.h" +#include "nsProxyRelease.h" +#include "nsStringGlue.h" +#include "nsError.h" +#include "nsIAsyncVerifyRedirectCallback.h" +#include "mozilla/Mutex.h" +#include "mozilla/net/ReferrerPolicy.h" +#include "ImageCacheKey.h" + +class imgCacheValidator; +class imgLoader; +class imgRequestProxy; +class imgCacheEntry; +class nsIApplicationCache; +class nsIProperties; +class nsIRequest; +class nsITimedChannel; +class nsIURI; + +namespace mozilla { +namespace image { +class Image; +class ImageURL; +class ProgressTracker; +} // namespace image +} // namespace mozilla + +struct NewPartResult; + +class imgRequest final : public nsIStreamListener, + public nsIThreadRetargetableStreamListener, + public nsIChannelEventSink, + public nsIInterfaceRequestor, + public nsIAsyncVerifyRedirectCallback +{ + typedef mozilla::image::Image Image; + typedef mozilla::image::ImageCacheKey ImageCacheKey; + typedef mozilla::image::ImageURL ImageURL; + typedef mozilla::image::ProgressTracker ProgressTracker; + typedef mozilla::net::ReferrerPolicy ReferrerPolicy; + +public: + imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey); + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSICHANNELEVENTSINK + NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK + + MOZ_MUST_USE nsresult Init(nsIURI* aURI, + nsIURI* aCurrentURI, + bool aHadInsecureRedirect, + nsIRequest* aRequest, + nsIChannel* aChannel, + imgCacheEntry* aCacheEntry, + nsISupports* aCX, + nsIPrincipal* aLoadingPrincipal, + int32_t aCORSMode, + ReferrerPolicy aReferrerPolicy); + + void ClearLoader(); + + // Callers must call imgRequestProxy::Notify later. + void AddProxy(imgRequestProxy* proxy); + + nsresult RemoveProxy(imgRequestProxy* proxy, nsresult aStatus); + + // Cancel, but also ensure that all work done in Init() is undone. Call this + // only when the channel has failed to open, and so calling Cancel() on it + // won't be sufficient. + void CancelAndAbort(nsresult aStatus); + + // Called or dispatched by cancel for main thread only execution. + void ContinueCancel(nsresult aStatus); + + // Called or dispatched by EvictFromCache for main thread only execution. + void ContinueEvict(); + + // Request that we start decoding the image as soon as data becomes available. + void StartDecoding(); + + inline uint64_t InnerWindowID() const { + return mInnerWindowId; + } + + // Set the cache validation information (expiry time, whether we must + // validate, etc) on the cache entry based on the request information. + // If this function is called multiple times, the information set earliest + // wins. + static void SetCacheValidation(imgCacheEntry* aEntry, nsIRequest* aRequest); + + // Check if application cache of the original load is different from + // application cache of the new load. Also lack of application cache + // on one of the loads is considered a change of a loading cache since + // HTTP cache may contain a different data then app cache. + bool CacheChanged(nsIRequest* aNewRequest); + + bool GetMultipart() const; + + // Returns whether we went through an insecure (non-HTTPS) redirect at some + // point during loading. This does not consider the current URI. + bool HadInsecureRedirect() const; + + // The CORS mode for which we loaded this image. + int32_t GetCORSMode() const { return mCORSMode; } + + // The Referrer Policy in effect when loading this image. + ReferrerPolicy GetReferrerPolicy() const { return mReferrerPolicy; } + + // The principal for the document that loaded this image. Used when trying to + // validate a CORS image load. + already_AddRefed<nsIPrincipal> GetLoadingPrincipal() const + { + nsCOMPtr<nsIPrincipal> principal = mLoadingPrincipal; + return principal.forget(); + } + + // Return the ProgressTracker associated with this imgRequest. It may live + // in |mProgressTracker| or in |mImage.mProgressTracker|, depending on whether + // mImage has been instantiated yet. + already_AddRefed<ProgressTracker> GetProgressTracker() const; + + /// Returns the Image associated with this imgRequest, if it's ready. + already_AddRefed<Image> GetImage() const; + + // Get the current principal of the image. No AddRefing. + inline nsIPrincipal* GetPrincipal() const { return mPrincipal.get(); } + + /// Get the ImageCacheKey associated with this request. + const ImageCacheKey& CacheKey() const { return mCacheKey; } + + // Resize the cache entry to 0 if it exists + void ResetCacheEntry(); + + // OK to use on any thread. + nsresult GetURI(ImageURL** aURI); + nsresult GetCurrentURI(nsIURI** aURI); + bool IsChrome() const; + + nsresult GetImageErrorCode(void); + + /// Returns true if we've received any data. + bool HasTransferredData() const; + + /// Returns a non-owning pointer to this imgRequest's MIME type. + const char* GetMimeType() const { return mContentType.get(); } + + /// @return the priority of the underlying network request, or + /// PRIORITY_NORMAL if it doesn't support nsISupportsPriority. + int32_t Priority() const; + + /// Adjust the priority of the underlying network request by @aDelta on behalf + /// of @aProxy. + void AdjustPriority(imgRequestProxy* aProxy, int32_t aDelta); + + /// Returns a weak pointer to the underlying request. + nsIRequest* GetRequest() const { return mRequest; } + + nsITimedChannel* GetTimedChannel() const { return mTimedChannel; } + + nsresult GetSecurityInfo(nsISupports** aSecurityInfoOut); + + imgCacheValidator* GetValidator() const { return mValidator; } + void SetValidator(imgCacheValidator* aValidator) { mValidator = aValidator; } + + void* LoadId() const { return mLoadId; } + void SetLoadId(void* aLoadId) { mLoadId = aLoadId; } + + /// Reset the cache entry after we've dropped our reference to it. Used by + /// imgLoader when our cache entry is re-requested after we've dropped our + /// reference to it. + void SetCacheEntry(imgCacheEntry* aEntry); + + /// Returns whether we've got a reference to the cache entry. + bool HasCacheEntry() const; + + /// Set whether this request is stored in the cache. If it isn't, regardless + /// of whether this request has a non-null mCacheEntry, this imgRequest won't + /// try to update or modify the image cache. + void SetIsInCache(bool aCacheable); + + void EvictFromCache(); + void RemoveFromCache(); + + // Sets properties for this image; will dispatch to main thread if needed. + void SetProperties(const nsACString& aContentType, + const nsACString& aContentDisposition); + + nsIProperties* Properties() const { return mProperties; } + + bool HasConsumers() const; + +private: + friend class FinishPreparingForNewPartRunnable; + + virtual ~imgRequest(); + + void FinishPreparingForNewPart(const NewPartResult& aResult); + + void Cancel(nsresult aStatus); + + // Update the cache entry size based on the image container. + void UpdateCacheEntrySize(); + + /// Returns true if StartDecoding() was called. + bool IsDecodeRequested() const; + + // Weak reference to parent loader; this request cannot outlive its owner. + imgLoader* mLoader; + nsCOMPtr<nsIRequest> mRequest; + // The original URI we were loaded with. This is the same as the URI we are + // keyed on in the cache. We store a string here to avoid off main thread + // refcounting issues with nsStandardURL. + RefPtr<ImageURL> mURI; + // The URI of the resource we ended up loading after all redirects, etc. + nsCOMPtr<nsIURI> mCurrentURI; + // The principal of the document which loaded this image. Used when + // validating for CORS. + nsCOMPtr<nsIPrincipal> mLoadingPrincipal; + // The principal of this image. + nsCOMPtr<nsIPrincipal> mPrincipal; + nsCOMPtr<nsIProperties> mProperties; + nsCOMPtr<nsISupports> mSecurityInfo; + nsCOMPtr<nsIChannel> mChannel; + nsCOMPtr<nsIInterfaceRequestor> mPrevChannelSink; + nsCOMPtr<nsIApplicationCache> mApplicationCache; + + nsCOMPtr<nsITimedChannel> mTimedChannel; + + nsCString mContentType; + + /* we hold on to this to this so long as we have observers */ + RefPtr<imgCacheEntry> mCacheEntry; + + /// The key under which this imgRequest is stored in the image cache. + ImageCacheKey mCacheKey; + + void* mLoadId; + + /// Raw pointer to the first proxy that was added to this imgRequest. Use only + /// pointer comparisons; there's no guarantee this will remain valid. + void* mFirstProxy; + + imgCacheValidator* mValidator; + nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback; + nsCOMPtr<nsIChannel> mNewRedirectChannel; + + // The ID of the inner window origin, used for error reporting. + uint64_t mInnerWindowId; + + // The CORS mode (defined in imgIRequest) this image was loaded with. By + // default, imgIRequest::CORS_NONE. + int32_t mCORSMode; + + // The Referrer Policy (defined in ReferrerPolicy.h) used for this image. + ReferrerPolicy mReferrerPolicy; + + nsresult mImageErrorCode; + + mutable mozilla::Mutex mMutex; + + // Member variables protected by mMutex. Note that *all* flags in our bitfield + // are protected by mMutex; if you're adding a new flag that isn'protected, it + // must not be a part of this bitfield. + RefPtr<ProgressTracker> mProgressTracker; + RefPtr<Image> mImage; + bool mIsMultiPartChannel : 1; + bool mGotData : 1; + bool mIsInCache : 1; + bool mDecodeRequested : 1; + bool mNewPartPending : 1; + bool mHadInsecureRedirect : 1; +}; + +#endif // mozilla_image_imgRequest_h |