1 /* -*- Mode: C++; tab-width: 4; 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 nsWebBrowserPersist_h__
8 #define nsWebBrowserPersist_h__
11 #include "nsWeakReference.h"
13 #include "nsIInterfaceRequestor.h"
14 #include "nsIMIMEService.h"
15 #include "nsIStreamListener.h"
16 #include "nsIOutputStream.h"
17 #include "nsIInputStream.h"
18 #include "nsIChannel.h"
19 #include "nsIProgressEventSink.h"
21 #include "nsIThreadRetargetableStreamListener.h"
22 #include "nsIWebProgressListener2.h"
23 #include "nsIWebBrowserPersist.h"
24 #include "nsIWebBrowserPersistDocument.h"
26 #include "mozilla/MozPromise.h"
27 #include "mozilla/Mutex.h"
28 #include "mozilla/UniquePtr.h"
29 #include "nsClassHashtable.h"
30 #include "nsHashKeys.h"
33 class nsIStorageStream
;
34 class nsIWebBrowserPersistDocument
;
36 using ClosePromise
= mozilla::MozPromise
<nsresult
, nsresult
, true>;
38 class nsWebBrowserPersist final
: public nsIInterfaceRequestor
,
39 public nsIWebBrowserPersist
,
40 public nsIThreadRetargetableStreamListener
,
41 public nsIProgressEventSink
,
42 public nsSupportsWeakReference
{
43 friend class nsEncoderNodeFixup
;
47 nsWebBrowserPersist();
49 NS_DECL_THREADSAFE_ISUPPORTS
50 NS_DECL_NSIINTERFACEREQUESTOR
52 NS_DECL_NSIWEBBROWSERPERSIST
53 NS_DECL_NSIREQUESTOBSERVER
54 NS_DECL_NSISTREAMLISTENER
55 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
56 NS_DECL_NSIPROGRESSEVENTSINK
60 virtual ~nsWebBrowserPersist();
61 nsresult
SaveURIInternal(nsIURI
* aURI
, nsIPrincipal
* aTriggeringPrincipal
,
62 nsContentPolicyType aContentPolicyType
,
63 uint32_t aCacheKey
, nsIReferrerInfo
* aReferrerInfo
,
64 nsICookieJarSettings
* aCookieJarSettings
,
65 nsIInputStream
* aPostData
, const char* aExtraHeaders
,
66 nsIURI
* aFile
, bool aCalcFileExt
, bool aIsPrivate
);
67 nsresult
SaveChannelInternal(nsIChannel
* aChannel
, nsIURI
* aFile
,
69 nsresult
SaveDocumentInternal(nsIWebBrowserPersistDocument
* aDocument
,
70 nsIURI
* aFile
, nsIURI
* aDataPath
);
71 nsresult
SaveDocuments();
72 void FinishSaveDocumentInternal(nsIURI
* aFile
, nsIFile
* aDataPath
);
73 nsresult
GetExtensionForContentType(const char16_t
* aContentType
,
90 nsresult
SaveDocumentDeferred(mozilla::UniquePtr
<WalkData
>&& aData
);
92 void CleanupLocalFiles();
93 nsresult
GetValidURIFromObject(nsISupports
* aObject
, nsIURI
** aURI
) const;
94 static nsresult
GetLocalFileFromURI(nsIURI
* aURI
, nsIFile
** aLocalFile
);
95 static nsresult
AppendPathToURI(nsIURI
* aURI
, const nsAString
& aPath
,
96 nsCOMPtr
<nsIURI
>& aOutURI
);
97 nsresult
MakeAndStoreLocalFilenameInURIMap(
98 nsIURI
* aURI
, nsIWebBrowserPersistDocument
* aDoc
,
99 nsContentPolicyType aContentPolicyType
, bool aNeedsPersisting
,
101 nsresult
MakeOutputStream(nsIURI
* aFile
, nsIOutputStream
** aOutputStream
);
102 nsresult
MakeOutputStreamFromFile(nsIFile
* aFile
,
103 nsIOutputStream
** aOutputStream
);
104 nsresult
MakeOutputStreamFromURI(nsIURI
* aURI
, nsIOutputStream
** aOutStream
);
105 nsresult
CreateChannelFromURI(nsIURI
* aURI
, nsIChannel
** aChannel
);
106 nsresult
StartUpload(nsIStorageStream
* aOutStream
, nsIURI
* aDestinationURI
,
107 const nsACString
& aContentType
);
108 nsresult
StartUpload(nsIInputStream
* aInputStream
, nsIURI
* aDestinationURI
,
109 const nsACString
& aContentType
);
110 nsresult
CalculateAndAppendFileExt(nsIURI
* aURI
, nsIChannel
* aChannel
,
111 nsIURI
* aOriginalURIWithExtension
,
112 nsCOMPtr
<nsIURI
>& aOutURI
);
113 nsresult
CalculateUniqueFilename(nsIURI
* aURI
, nsCOMPtr
<nsIURI
>& aOutURI
);
114 nsresult
MakeFilenameFromURI(nsIURI
* aURI
, nsString
& aFilename
);
115 nsresult
StoreURI(const nsACString
& aURI
, nsIWebBrowserPersistDocument
* aDoc
,
116 nsContentPolicyType aContentPolicyType
,
117 bool aNeedsPersisting
= true, URIData
** aData
= nullptr);
118 nsresult
StoreURI(nsIURI
* aURI
, nsIWebBrowserPersistDocument
* aDoc
,
119 nsContentPolicyType aContentPolicyType
,
120 bool aNeedsPersisting
= true, URIData
** aData
= nullptr);
121 bool DocumentEncoderExists(const char* aContentType
);
123 nsresult
SaveSubframeContent(nsIWebBrowserPersistDocument
* aFrameContent
,
124 nsIWebBrowserPersistDocument
* aParentDocument
,
125 const nsCString
& aURISpec
, URIData
* aData
);
126 nsresult
SendErrorStatusChange(bool aIsReadError
, nsresult aResult
,
127 nsIRequest
* aRequest
, nsIURI
* aURI
);
129 nsresult
FixRedirectedChannelEntry(nsIChannel
* aNewChannel
);
131 void FinishDownload();
132 void EndDownload(nsresult aResult
);
133 void EndDownloadInternal(nsresult aResult
);
134 void SerializeNextFile();
135 void CalcTotalProgress();
137 void SetApplyConversionIfNeeded(nsIChannel
* aChannel
);
139 nsCOMPtr
<nsIURI
> mCurrentDataPath
;
140 bool mCurrentDataPathIsRelative
;
141 nsCString mCurrentRelativePathToData
;
142 nsCOMPtr
<nsIURI
> mCurrentBaseURI
;
143 nsCString mCurrentCharset
;
144 nsCOMPtr
<nsIURI
> mTargetBaseURI
;
145 uint32_t mCurrentThingsToPersist
;
147 nsCOMPtr
<nsIMIMEService
> mMIMEService
;
148 nsCOMPtr
<nsIURI
> mURI
;
149 nsCOMPtr
<nsIWebProgressListener
> mProgressListener
;
151 * Progress listener for 64-bit values; this is the same object as
152 * mProgressListener, but is a member to avoid having to qi it for each
153 * progress notification.
155 nsCOMPtr
<nsIWebProgressListener2
> mProgressListener2
;
156 nsCOMPtr
<nsIProgressEventSink
> mEventSink
;
157 mozilla::Mutex mOutputMapMutex MOZ_UNANNOTATED
;
158 nsClassHashtable
<nsISupportsHashKey
, OutputData
> mOutputMap
;
159 nsClassHashtable
<nsISupportsHashKey
, UploadData
> mUploadList
;
160 nsCOMPtr
<nsISerialEventTarget
> mBackgroundQueue
;
161 nsTArray
<RefPtr
<ClosePromise
>> mFileClosePromises
;
162 nsClassHashtable
<nsCStringHashKey
, URIData
> mURIMap
;
163 nsCOMPtr
<nsIWebBrowserPersistURIMap
> mFlatURIMap
;
164 nsTArray
<mozilla::UniquePtr
<WalkData
>> mWalkStack
;
165 nsTArray
<DocData
*> mDocList
;
166 nsTArray
<CleanupData
*> mCleanupList
;
167 nsTArray
<nsCString
> mFilenameList
;
168 bool mFirstAndOnlyUse
;
169 bool mSavingDocument
;
170 // mCancel is used from both the main thread, and (inside OnDataAvailable)
171 // from a background thread.
172 mozilla::Atomic
<bool> mCancel
;
176 bool mReplaceExisting
;
177 bool mSerializingOutput
;
179 // mPersistFlags can be modified on the main thread, and can be read from
180 // a background thread when OnDataAvailable calls MakeOutputStreamFromFile.
181 mozilla::Atomic
<uint32_t> mPersistFlags
;
182 nsresult mPersistResult
;
183 int64_t mTotalCurrentProgress
;
184 int64_t mTotalMaxProgress
;
186 uint32_t mEncodingFlags
;
187 nsString mContentType
;