/* -*- Mode: C++; tab-width: 4; 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 nsWebBrowserPersist_h__ #define nsWebBrowserPersist_h__ #include "nsCOMPtr.h" #include "nsWeakReference.h" #include "nsIInterfaceRequestor.h" #include "nsIMIMEService.h" #include "nsIStreamListener.h" #include "nsIOutputStream.h" #include "nsIInputStream.h" #include "nsIChannel.h" #include "nsIProgressEventSink.h" #include "nsIFile.h" #include "nsIThreadRetargetableStreamListener.h" #include "nsIWebProgressListener2.h" #include "nsIWebBrowserPersist.h" #include "nsIWebBrowserPersistDocument.h" #include "mozilla/MozPromise.h" #include "mozilla/Mutex.h" #include "mozilla/UniquePtr.h" #include "nsClassHashtable.h" #include "nsHashKeys.h" #include "nsTArray.h" class nsIStorageStream; class nsIWebBrowserPersistDocument; using ClosePromise = mozilla::MozPromise; class nsWebBrowserPersist final : public nsIInterfaceRequestor, public nsIWebBrowserPersist, public nsIStreamListener, public nsIThreadRetargetableStreamListener, public nsIProgressEventSink, public nsSupportsWeakReference { friend class nsEncoderNodeFixup; // Public members public: nsWebBrowserPersist(); NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSICANCELABLE NS_DECL_NSIWEBBROWSERPERSIST NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER NS_DECL_NSIPROGRESSEVENTSINK // Private members private: virtual ~nsWebBrowserPersist(); nsresult SaveURIInternal(nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal, nsContentPolicyType aContentPolicyType, uint32_t aCacheKey, nsIReferrerInfo* aReferrerInfo, nsICookieJarSettings* aCookieJarSettings, nsIInputStream* aPostData, const char* aExtraHeaders, nsIURI* aFile, bool aCalcFileExt, bool aIsPrivate); nsresult SaveChannelInternal(nsIChannel* aChannel, nsIURI* aFile, bool aCalcFileExt); nsresult SaveDocumentInternal(nsIWebBrowserPersistDocument* aDocument, nsIURI* aFile, nsIURI* aDataPath); nsresult SaveDocuments(); void FinishSaveDocumentInternal(nsIURI* aFile, nsIFile* aDataPath); nsresult GetExtensionForContentType(const char16_t* aContentType, char16_t** aExt); struct CleanupData; struct DocData; struct OutputData; struct UploadData; struct URIData; struct WalkData; class OnWalk; class OnRemoteWalk; class OnWrite; class FlatURIMap; friend class OnWalk; friend class OnWrite; nsresult SaveDocumentDeferred(mozilla::UniquePtr&& aData); void Cleanup(); void CleanupLocalFiles(); nsresult GetValidURIFromObject(nsISupports* aObject, nsIURI** aURI) const; static nsresult GetLocalFileFromURI(nsIURI* aURI, nsIFile** aLocalFile); static nsresult AppendPathToURI(nsIURI* aURI, const nsAString& aPath, nsCOMPtr& aOutURI); nsresult MakeAndStoreLocalFilenameInURIMap( nsIURI* aURI, nsIWebBrowserPersistDocument* aDoc, nsContentPolicyType aContentPolicyType, bool aNeedsPersisting, URIData** aData); nsresult MakeOutputStream(nsIURI* aFile, nsIOutputStream** aOutputStream); nsresult MakeOutputStreamFromFile(nsIFile* aFile, nsIOutputStream** aOutputStream); nsresult MakeOutputStreamFromURI(nsIURI* aURI, nsIOutputStream** aOutStream); nsresult CreateChannelFromURI(nsIURI* aURI, nsIChannel** aChannel); nsresult StartUpload(nsIStorageStream* aOutStream, nsIURI* aDestinationURI, const nsACString& aContentType); nsresult StartUpload(nsIInputStream* aInputStream, nsIURI* aDestinationURI, const nsACString& aContentType); nsresult CalculateAndAppendFileExt(nsIURI* aURI, nsIChannel* aChannel, nsIURI* aOriginalURIWithExtension, nsCOMPtr& aOutURI); nsresult CalculateUniqueFilename(nsIURI* aURI, nsCOMPtr& aOutURI); nsresult MakeFilenameFromURI(nsIURI* aURI, nsString& aFilename); nsresult StoreURI(const nsACString& aURI, nsIWebBrowserPersistDocument* aDoc, nsContentPolicyType aContentPolicyType, bool aNeedsPersisting = true, URIData** aData = nullptr); nsresult StoreURI(nsIURI* aURI, nsIWebBrowserPersistDocument* aDoc, nsContentPolicyType aContentPolicyType, bool aNeedsPersisting = true, URIData** aData = nullptr); bool DocumentEncoderExists(const char* aContentType); nsresult SaveSubframeContent(nsIWebBrowserPersistDocument* aFrameContent, nsIWebBrowserPersistDocument* aParentDocument, const nsCString& aURISpec, URIData* aData); nsresult SendErrorStatusChange(bool aIsReadError, nsresult aResult, nsIRequest* aRequest, nsIURI* aURI); nsresult FixRedirectedChannelEntry(nsIChannel* aNewChannel); void FinishDownload(); void EndDownload(nsresult aResult); void EndDownloadInternal(nsresult aResult); void SerializeNextFile(); void CalcTotalProgress(); void SetApplyConversionIfNeeded(nsIChannel* aChannel); nsCOMPtr mCurrentDataPath; bool mCurrentDataPathIsRelative; nsCString mCurrentRelativePathToData; nsCOMPtr mCurrentBaseURI; nsCString mCurrentCharset; nsCOMPtr mTargetBaseURI; uint32_t mCurrentThingsToPersist; nsCOMPtr mMIMEService; nsCOMPtr mURI; nsCOMPtr mProgressListener; /** * Progress listener for 64-bit values; this is the same object as * mProgressListener, but is a member to avoid having to qi it for each * progress notification. */ nsCOMPtr mProgressListener2; nsCOMPtr mEventSink; mozilla::Mutex mOutputMapMutex MOZ_UNANNOTATED; nsClassHashtable mOutputMap; nsClassHashtable mUploadList; nsCOMPtr mBackgroundQueue; nsTArray> mFileClosePromises; nsClassHashtable mURIMap; nsCOMPtr mFlatURIMap; nsTArray> mWalkStack; nsTArray mDocList; nsTArray mCleanupList; nsTArray mFilenameList; bool mFirstAndOnlyUse; bool mSavingDocument; // mCancel is used from both the main thread, and (inside OnDataAvailable) // from a background thread. mozilla::Atomic mCancel; bool mEndCalled; bool mCompleted; bool mStartSaving; bool mReplaceExisting; bool mSerializingOutput; bool mIsPrivate; // mPersistFlags can be modified on the main thread, and can be read from // a background thread when OnDataAvailable calls MakeOutputStreamFromFile. mozilla::Atomic mPersistFlags; nsresult mPersistResult; int64_t mTotalCurrentProgress; int64_t mTotalMaxProgress; int16_t mWrapColumn; uint32_t mEncodingFlags; nsString mContentType; }; #endif