1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsOfflineCacheUpdate_h__
7 #define nsOfflineCacheUpdate_h__
9 #include "nsIOfflineCacheUpdate.h"
11 #include "nsAutoPtr.h"
12 #include "nsCOMArray.h"
14 #include "nsIChannelEventSink.h"
15 #include "nsIInterfaceRequestor.h"
16 #include "nsIMutableArray.h"
17 #include "nsIObserver.h"
18 #include "nsIObserverService.h"
19 #include "nsIApplicationCache.h"
20 #include "nsIRequestObserver.h"
21 #include "nsIRunnable.h"
22 #include "nsIStreamListener.h"
24 #include "nsIWebProgressListener.h"
25 #include "nsClassHashtable.h"
28 #include "nsWeakReference.h"
29 #include "nsICryptoHash.h"
30 #include "mozilla/Attributes.h"
31 #include "mozilla/WeakPtr.h"
32 #include "nsTHashtable.h"
33 #include "nsHashKeys.h"
38 class CookieSettingsArgs
;
41 } // namespace mozilla
43 class nsOfflineCacheUpdate
;
45 class nsOfflineCacheUpdateItem
: public nsIStreamListener
,
47 public nsIInterfaceRequestor
,
48 public nsIChannelEventSink
{
51 NS_DECL_NSIREQUESTOBSERVER
52 NS_DECL_NSISTREAMLISTENER
54 NS_DECL_NSIINTERFACEREQUESTOR
55 NS_DECL_NSICHANNELEVENTSINK
57 nsOfflineCacheUpdateItem(nsIURI
* aURI
, nsIURI
* aReferrerURI
,
58 nsIPrincipal
* aLoadingPrincipal
,
59 nsIApplicationCache
* aApplicationCache
,
60 nsIApplicationCache
* aPreviousApplicationCache
,
61 uint32_t aType
, uint32_t aLoadFlags
);
63 nsCOMPtr
<nsIURI
> mURI
;
64 nsCOMPtr
<nsIURI
> mReferrerURI
;
65 nsCOMPtr
<nsIPrincipal
> mLoadingPrincipal
;
66 nsCOMPtr
<nsIApplicationCache
> mApplicationCache
;
67 nsCOMPtr
<nsIApplicationCache
> mPreviousApplicationCache
;
72 nsresult
OpenChannel(nsOfflineCacheUpdate
* aUpdate
);
74 nsresult
GetRequestSucceeded(bool* succeeded
);
80 nsresult
GetStatus(uint16_t* aStatus
);
83 enum LoadStatus
: uint16_t {
90 RefPtr
<nsOfflineCacheUpdate
> mUpdate
;
91 nsCOMPtr
<nsIChannel
> mChannel
;
95 virtual ~nsOfflineCacheUpdateItem();
100 class nsOfflineManifestItem
: public nsOfflineCacheUpdateItem
{
102 NS_DECL_NSISTREAMLISTENER
103 NS_DECL_NSIREQUESTOBSERVER
105 nsOfflineManifestItem(nsIURI
* aURI
, nsIURI
* aReferrerURI
,
106 nsIPrincipal
* aLoadingPrincipal
,
107 nsIApplicationCache
* aApplicationCache
,
108 nsIApplicationCache
* aPreviousApplicationCache
);
109 virtual ~nsOfflineManifestItem();
111 nsCOMArray
<nsIURI
>& GetExplicitURIs() { return mExplicitURIs
; }
112 nsCOMArray
<nsIURI
>& GetAnonymousURIs() { return mAnonymousURIs
; }
113 nsCOMArray
<nsIURI
>& GetFallbackURIs() { return mFallbackURIs
; }
115 nsTArray
<nsCString
>& GetOpportunisticNamespaces() {
116 return mOpportunisticNamespaces
;
118 nsIArray
* GetNamespaces() { return mNamespaces
.get(); }
120 bool ParseSucceeded() {
121 return (mParserState
!= PARSE_INIT
&& mParserState
!= PARSE_ERROR
);
123 bool NeedsUpdate() { return mParserState
!= PARSE_INIT
&& mNeedsUpdate
; }
125 void GetManifestHash(nsCString
& aManifestHash
) {
126 aManifestHash
= mManifestHashValue
;
130 static nsresult
ReadManifest(nsIInputStream
* aInputStream
, void* aClosure
,
131 const char* aFromSegment
, uint32_t aOffset
,
132 uint32_t aCount
, uint32_t* aBytesConsumed
);
134 nsresult
AddNamespace(uint32_t namespaceType
, const nsCString
& namespaceSpec
,
135 const nsCString
& data
);
137 nsresult
HandleManifestLine(const nsCString::const_iterator
& aBegin
,
138 const nsCString::const_iterator
& aEnd
);
141 * Saves "offline-manifest-hash" meta data from the old offline cache
142 * token to mOldManifestHashValue member to be compared on
145 nsresult
GetOldManifestContentHash(nsIRequest
* aRequest
);
147 * This method setups the mNeedsUpdate to false when hash value
148 * of the just downloaded manifest file is the same as stored in cache's
149 * "offline-manifest-hash" meta data. Otherwise stores the new value
152 nsresult
CheckNewManifestContentHash(nsIRequest
* aRequest
);
154 void ReadStrictFileOriginPolicyPref();
159 PARSE_FALLBACK_ENTRIES
,
160 PARSE_BYPASS_ENTRIES
,
161 PARSE_UNKNOWN_SECTION
,
167 nsCOMArray
<nsIURI
> mExplicitURIs
;
168 nsCOMArray
<nsIURI
> mAnonymousURIs
;
169 nsCOMArray
<nsIURI
> mFallbackURIs
;
171 // All opportunistic caching namespaces. Used to decide whether
172 // to include previously-opportunistically-cached entries.
173 nsTArray
<nsCString
> mOpportunisticNamespaces
;
175 // Array of nsIApplicationCacheNamespace objects specified by the
177 nsCOMPtr
<nsIMutableArray
> mNamespaces
;
180 bool mStrictFileOriginPolicy
;
182 // manifest hash data
183 nsCOMPtr
<nsICryptoHash
> mManifestHash
;
184 bool mManifestHashInitialized
;
185 nsCString mManifestHashValue
;
186 nsCString mOldManifestHashValue
;
189 class nsOfflineCacheUpdateOwner
190 : public mozilla::SupportsWeakPtr
<nsOfflineCacheUpdateOwner
> {
192 MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsOfflineCacheUpdateOwner
)
193 virtual ~nsOfflineCacheUpdateOwner() {}
194 virtual nsresult
UpdateFinished(nsOfflineCacheUpdate
* aUpdate
) = 0;
197 class nsOfflineCacheUpdate final
: public nsIOfflineCacheUpdate
,
198 public nsIOfflineCacheUpdateObserver
,
200 public nsOfflineCacheUpdateOwner
{
203 NS_DECL_NSIOFFLINECACHEUPDATE
204 NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
207 nsOfflineCacheUpdate();
209 static nsresult
GetCacheKey(nsIURI
* aURI
, nsACString
& aKey
);
215 void LoadCompleted(nsOfflineCacheUpdateItem
* aItem
);
216 void ManifestCheckCompleted(nsresult aStatus
, const nsCString
& aManifestHash
);
217 void StickDocument(nsIURI
* aDocumentURI
);
219 void SetOwner(nsOfflineCacheUpdateOwner
* aOwner
);
221 bool IsForGroupID(const nsACString
& groupID
);
222 bool IsForProfile(nsIFile
* aCustomProfileDir
);
224 virtual nsresult
UpdateFinished(nsOfflineCacheUpdate
* aUpdate
) override
;
226 nsICookieSettings
* CookieSettings() const { return mCookieSettings
; }
227 void SetCookieSettings(nsICookieSettings
* aCookieSettings
);
228 void SetCookieSettingsArgs(
229 const mozilla::net::CookieSettingsArgs
& aCookieSettingsArgs
);
232 ~nsOfflineCacheUpdate();
234 friend class nsOfflineCacheUpdateItem
;
235 void OnByteProgress(uint64_t byteIncrement
);
238 nsresult
InitInternal(nsIURI
* aManifestURI
, nsIPrincipal
* aPrincipal
);
239 nsresult
HandleManifest(bool* aDoUpdate
);
240 nsresult
AddURI(nsIURI
* aURI
, uint32_t aItemType
, uint32_t aLoadFlags
= 0);
242 nsresult
ProcessNextURI();
244 // Adds items from the previous cache witha type matching aType.
245 // If namespaceFilter is non-null, only items matching the
246 // specified namespaces will be added.
247 nsresult
AddExistingItems(uint32_t aType
,
248 nsTArray
<nsCString
>* namespaceFilter
= nullptr);
249 nsresult
ScheduleImplicit();
250 void AssociateDocuments(nsIApplicationCache
* cache
);
251 bool CheckUpdateAvailability();
252 void NotifyUpdateAvailability(bool updateAvailable
);
254 void GatherObservers(nsCOMArray
<nsIOfflineCacheUpdateObserver
>& aObservers
);
255 void NotifyState(uint32_t state
);
257 nsresult
FinishNoNotify();
259 void AsyncFinishWithError();
261 // Find one non-pinned cache group and evict it.
262 nsresult
EvictOneNonPinned();
273 mozilla::WeakPtr
<nsOfflineCacheUpdateOwner
> mOwner
;
277 bool mOnlyCheckUpdate
;
281 nsCString mUpdateDomain
;
283 nsCOMPtr
<nsIURI
> mManifestURI
;
284 nsCOMPtr
<nsIURI
> mDocumentURI
;
285 nsCOMPtr
<nsIPrincipal
> mLoadingPrincipal
;
286 nsCOMPtr
<nsIFile
> mCustomProfileDir
;
287 nsCOMPtr
<nsICookieSettings
> mCookieSettings
;
289 nsCOMPtr
<nsIObserver
> mUpdateAvailableObserver
;
291 nsCOMPtr
<nsIApplicationCache
> mApplicationCache
;
292 nsCOMPtr
<nsIApplicationCache
> mPreviousApplicationCache
;
294 nsCOMPtr
<nsIObserverService
> mObserverService
;
296 RefPtr
<nsOfflineManifestItem
> mManifestItem
;
298 /* Items being updated */
299 uint32_t mItemsInProgress
;
300 nsTArray
<RefPtr
<nsOfflineCacheUpdateItem
> > mItems
;
302 /* Clients watching this update for changes */
303 nsCOMArray
<nsIWeakReference
> mWeakObservers
;
304 nsCOMArray
<nsIOfflineCacheUpdateObserver
> mObservers
;
306 /* Documents that requested this update */
307 nsCOMArray
<nsIURI
> mDocumentURIs
;
309 /* Reschedule count. When an update is rescheduled due to
310 * mismatched manifests, the reschedule count will be increased. */
311 uint32_t mRescheduleCount
;
313 /* Whena an entry for a pinned app is retried, retries count is
315 uint32_t mPinnedEntryRetriesCount
;
317 RefPtr
<nsOfflineCacheUpdate
> mImplicitUpdate
;
321 uint64_t mByteProgress
;
324 class nsOfflineCacheUpdateService final
: public nsIOfflineCacheUpdateService
,
326 public nsOfflineCacheUpdateOwner
,
327 public nsSupportsWeakReference
{
330 NS_DECL_NSIOFFLINECACHEUPDATESERVICE
333 nsOfflineCacheUpdateService();
337 nsresult
ScheduleUpdate(nsOfflineCacheUpdate
* aUpdate
);
338 nsresult
FindUpdate(nsIURI
* aManifestURI
, nsACString
const& aOriginSuffix
,
339 nsIFile
* aCustomProfileDir
,
340 nsOfflineCacheUpdate
** aUpdate
);
342 nsresult
Schedule(nsIURI
* aManifestURI
, nsIURI
* aDocumentURI
,
343 nsIPrincipal
* aLoadingPrincipal
,
344 mozilla::dom::Document
* aDocument
,
345 nsPIDOMWindowInner
* aWindow
, nsIFile
* aCustomProfileDir
,
346 nsIOfflineCacheUpdate
** aUpdate
);
348 virtual nsresult
UpdateFinished(nsOfflineCacheUpdate
* aUpdate
) override
;
351 * Returns the singleton nsOfflineCacheUpdateService without an addref, or
352 * nullptr if the service couldn't be created.
354 static nsOfflineCacheUpdateService
* EnsureService();
356 static already_AddRefed
<nsOfflineCacheUpdateService
> GetInstance();
358 static nsresult
OfflineAppPinnedForURI(nsIURI
* aDocumentURI
, bool* aPinned
);
360 static nsTHashtable
<nsCStringHashKey
>* AllowedDomains();
363 ~nsOfflineCacheUpdateService();
365 nsresult
ProcessNextUpdate();
367 nsTArray
<RefPtr
<nsOfflineCacheUpdate
> > mUpdates
;
368 static nsTHashtable
<nsCStringHashKey
>* mAllowedDomains
;