|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
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/. */ |
|
5 |
|
6 #ifndef nsOfflineCacheUpdate_h__ |
|
7 #define nsOfflineCacheUpdate_h__ |
|
8 |
|
9 #include "nsIOfflineCacheUpdate.h" |
|
10 |
|
11 #include "nsAutoPtr.h" |
|
12 #include "nsCOMArray.h" |
|
13 #include "nsCOMPtr.h" |
|
14 #include "nsICacheService.h" |
|
15 #include "nsIChannelEventSink.h" |
|
16 #include "nsIDOMDocument.h" |
|
17 #include "nsIDOMNode.h" |
|
18 #include "nsIInterfaceRequestor.h" |
|
19 #include "nsIMutableArray.h" |
|
20 #include "nsIObserver.h" |
|
21 #include "nsIObserverService.h" |
|
22 #include "nsIApplicationCache.h" |
|
23 #include "nsIRequestObserver.h" |
|
24 #include "nsIRunnable.h" |
|
25 #include "nsIStreamListener.h" |
|
26 #include "nsIURI.h" |
|
27 #include "nsIWebProgressListener.h" |
|
28 #include "nsClassHashtable.h" |
|
29 #include "nsString.h" |
|
30 #include "nsTArray.h" |
|
31 #include "nsWeakReference.h" |
|
32 #include "nsICryptoHash.h" |
|
33 #include "mozilla/Attributes.h" |
|
34 #include "mozilla/WeakPtr.h" |
|
35 #include "nsTHashtable.h" |
|
36 #include "nsHashKeys.h" |
|
37 |
|
38 class nsOfflineCacheUpdate; |
|
39 |
|
40 class nsICacheEntryDescriptor; |
|
41 class nsIUTF8StringEnumerator; |
|
42 class nsILoadContext; |
|
43 |
|
44 class nsOfflineCacheUpdateItem : public nsIStreamListener |
|
45 , public nsIRunnable |
|
46 , public nsIInterfaceRequestor |
|
47 , public nsIChannelEventSink |
|
48 { |
|
49 public: |
|
50 NS_DECL_ISUPPORTS |
|
51 NS_DECL_NSIREQUESTOBSERVER |
|
52 NS_DECL_NSISTREAMLISTENER |
|
53 NS_DECL_NSIRUNNABLE |
|
54 NS_DECL_NSIINTERFACEREQUESTOR |
|
55 NS_DECL_NSICHANNELEVENTSINK |
|
56 |
|
57 nsOfflineCacheUpdateItem(nsIURI *aURI, |
|
58 nsIURI *aReferrerURI, |
|
59 nsIApplicationCache *aApplicationCache, |
|
60 nsIApplicationCache *aPreviousApplicationCache, |
|
61 uint32_t aType); |
|
62 virtual ~nsOfflineCacheUpdateItem(); |
|
63 |
|
64 nsCOMPtr<nsIURI> mURI; |
|
65 nsCOMPtr<nsIURI> mReferrerURI; |
|
66 nsCOMPtr<nsIApplicationCache> mApplicationCache; |
|
67 nsCOMPtr<nsIApplicationCache> mPreviousApplicationCache; |
|
68 nsCString mCacheKey; |
|
69 uint32_t mItemType; |
|
70 |
|
71 nsresult OpenChannel(nsOfflineCacheUpdate *aUpdate); |
|
72 nsresult Cancel(); |
|
73 nsresult GetRequestSucceeded(bool * succeeded); |
|
74 |
|
75 bool IsInProgress(); |
|
76 bool IsScheduled(); |
|
77 bool IsCompleted(); |
|
78 |
|
79 nsresult GetStatus(uint16_t *aStatus); |
|
80 |
|
81 private: |
|
82 enum LoadStatus MOZ_ENUM_TYPE(uint16_t) { |
|
83 UNINITIALIZED = 0U, |
|
84 REQUESTED = 1U, |
|
85 RECEIVING = 2U, |
|
86 LOADED = 3U |
|
87 }; |
|
88 |
|
89 nsRefPtr<nsOfflineCacheUpdate> mUpdate; |
|
90 nsCOMPtr<nsIChannel> mChannel; |
|
91 uint16_t mState; |
|
92 |
|
93 protected: |
|
94 int64_t mBytesRead; |
|
95 }; |
|
96 |
|
97 |
|
98 class nsOfflineManifestItem : public nsOfflineCacheUpdateItem |
|
99 { |
|
100 public: |
|
101 NS_DECL_NSISTREAMLISTENER |
|
102 NS_DECL_NSIREQUESTOBSERVER |
|
103 |
|
104 nsOfflineManifestItem(nsIURI *aURI, |
|
105 nsIURI *aReferrerURI, |
|
106 nsIApplicationCache *aApplicationCache, |
|
107 nsIApplicationCache *aPreviousApplicationCache); |
|
108 virtual ~nsOfflineManifestItem(); |
|
109 |
|
110 nsCOMArray<nsIURI> &GetExplicitURIs() { return mExplicitURIs; } |
|
111 nsCOMArray<nsIURI> &GetFallbackURIs() { return mFallbackURIs; } |
|
112 |
|
113 nsTArray<nsCString> &GetOpportunisticNamespaces() |
|
114 { return mOpportunisticNamespaces; } |
|
115 nsIArray *GetNamespaces() |
|
116 { return mNamespaces.get(); } |
|
117 |
|
118 bool ParseSucceeded() |
|
119 { return (mParserState != PARSE_INIT && mParserState != PARSE_ERROR); } |
|
120 bool NeedsUpdate() { return mParserState != PARSE_INIT && mNeedsUpdate; } |
|
121 |
|
122 void GetManifestHash(nsCString &aManifestHash) |
|
123 { aManifestHash = mManifestHashValue; } |
|
124 |
|
125 private: |
|
126 static NS_METHOD ReadManifest(nsIInputStream *aInputStream, |
|
127 void *aClosure, |
|
128 const char *aFromSegment, |
|
129 uint32_t aOffset, |
|
130 uint32_t aCount, |
|
131 uint32_t *aBytesConsumed); |
|
132 |
|
133 nsresult AddNamespace(uint32_t namespaceType, |
|
134 const nsCString &namespaceSpec, |
|
135 const nsCString &data); |
|
136 |
|
137 nsresult HandleManifestLine(const nsCString::const_iterator &aBegin, |
|
138 const nsCString::const_iterator &aEnd); |
|
139 |
|
140 /** |
|
141 * Saves "offline-manifest-hash" meta data from the old offline cache |
|
142 * token to mOldManifestHashValue member to be compared on |
|
143 * successfull load. |
|
144 */ |
|
145 nsresult GetOldManifestContentHash(nsIRequest *aRequest); |
|
146 /** |
|
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 |
|
150 * to this meta data. |
|
151 */ |
|
152 nsresult CheckNewManifestContentHash(nsIRequest *aRequest); |
|
153 |
|
154 void ReadStrictFileOriginPolicyPref(); |
|
155 |
|
156 enum { |
|
157 PARSE_INIT, |
|
158 PARSE_CACHE_ENTRIES, |
|
159 PARSE_FALLBACK_ENTRIES, |
|
160 PARSE_BYPASS_ENTRIES, |
|
161 PARSE_UNKNOWN_SECTION, |
|
162 PARSE_ERROR |
|
163 } mParserState; |
|
164 |
|
165 nsCString mReadBuf; |
|
166 |
|
167 nsCOMArray<nsIURI> mExplicitURIs; |
|
168 nsCOMArray<nsIURI> mFallbackURIs; |
|
169 |
|
170 // All opportunistic caching namespaces. Used to decide whether |
|
171 // to include previously-opportunistically-cached entries. |
|
172 nsTArray<nsCString> mOpportunisticNamespaces; |
|
173 |
|
174 // Array of nsIApplicationCacheNamespace objects specified by the |
|
175 // manifest. |
|
176 nsCOMPtr<nsIMutableArray> mNamespaces; |
|
177 |
|
178 bool mNeedsUpdate; |
|
179 bool mStrictFileOriginPolicy; |
|
180 |
|
181 // manifest hash data |
|
182 nsCOMPtr<nsICryptoHash> mManifestHash; |
|
183 bool mManifestHashInitialized; |
|
184 nsCString mManifestHashValue; |
|
185 nsCString mOldManifestHashValue; |
|
186 }; |
|
187 |
|
188 class nsOfflineCacheUpdateOwner |
|
189 : public mozilla::SupportsWeakPtr<nsOfflineCacheUpdateOwner> |
|
190 { |
|
191 public: |
|
192 MOZ_DECLARE_REFCOUNTED_TYPENAME(nsOfflineCacheUpdateOwner) |
|
193 virtual ~nsOfflineCacheUpdateOwner() {} |
|
194 virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate) = 0; |
|
195 }; |
|
196 |
|
197 class nsOfflineCacheUpdate MOZ_FINAL : public nsIOfflineCacheUpdate |
|
198 , public nsIOfflineCacheUpdateObserver |
|
199 , public nsIRunnable |
|
200 , public nsOfflineCacheUpdateOwner |
|
201 { |
|
202 public: |
|
203 MOZ_DECLARE_REFCOUNTED_TYPENAME(nsOfflineCacheUpdate) |
|
204 NS_DECL_ISUPPORTS |
|
205 NS_DECL_NSIOFFLINECACHEUPDATE |
|
206 NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER |
|
207 NS_DECL_NSIRUNNABLE |
|
208 |
|
209 nsOfflineCacheUpdate(); |
|
210 ~nsOfflineCacheUpdate(); |
|
211 |
|
212 static nsresult GetCacheKey(nsIURI *aURI, nsACString &aKey); |
|
213 |
|
214 nsresult Init(); |
|
215 |
|
216 nsresult Begin(); |
|
217 |
|
218 void LoadCompleted(nsOfflineCacheUpdateItem *aItem); |
|
219 void ManifestCheckCompleted(nsresult aStatus, |
|
220 const nsCString &aManifestHash); |
|
221 void StickDocument(nsIURI *aDocumentURI); |
|
222 |
|
223 void SetOwner(nsOfflineCacheUpdateOwner *aOwner); |
|
224 |
|
225 bool IsForGroupID(const nsCSubstring &groupID); |
|
226 |
|
227 virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate); |
|
228 |
|
229 protected: |
|
230 friend class nsOfflineCacheUpdateItem; |
|
231 void OnByteProgress(uint64_t byteIncrement); |
|
232 |
|
233 private: |
|
234 nsresult InitInternal(nsIURI *aManifestURI); |
|
235 nsresult HandleManifest(bool *aDoUpdate); |
|
236 nsresult AddURI(nsIURI *aURI, uint32_t aItemType); |
|
237 |
|
238 nsresult ProcessNextURI(); |
|
239 |
|
240 // Adds items from the previous cache witha type matching aType. |
|
241 // If namespaceFilter is non-null, only items matching the |
|
242 // specified namespaces will be added. |
|
243 nsresult AddExistingItems(uint32_t aType, |
|
244 nsTArray<nsCString>* namespaceFilter = nullptr); |
|
245 nsresult ScheduleImplicit(); |
|
246 void AssociateDocuments(nsIApplicationCache* cache); |
|
247 bool CheckUpdateAvailability(); |
|
248 void NotifyUpdateAvailability(bool updateAvailable); |
|
249 |
|
250 void GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers); |
|
251 void NotifyState(uint32_t state); |
|
252 nsresult Finish(); |
|
253 nsresult FinishNoNotify(); |
|
254 |
|
255 void AsyncFinishWithError(); |
|
256 |
|
257 // Find one non-pinned cache group and evict it. |
|
258 nsresult EvictOneNonPinned(); |
|
259 |
|
260 enum { |
|
261 STATE_UNINITIALIZED, |
|
262 STATE_INITIALIZED, |
|
263 STATE_CHECKING, |
|
264 STATE_DOWNLOADING, |
|
265 STATE_CANCELLED, |
|
266 STATE_FINISHED |
|
267 } mState; |
|
268 |
|
269 mozilla::WeakPtr<nsOfflineCacheUpdateOwner> mOwner; |
|
270 |
|
271 bool mAddedItems; |
|
272 bool mPartialUpdate; |
|
273 bool mOnlyCheckUpdate; |
|
274 bool mSucceeded; |
|
275 bool mObsolete; |
|
276 |
|
277 nsCString mUpdateDomain; |
|
278 nsCString mGroupID; |
|
279 nsCOMPtr<nsIURI> mManifestURI; |
|
280 nsCOMPtr<nsIURI> mDocumentURI; |
|
281 nsCOMPtr<nsIFile> mCustomProfileDir; |
|
282 |
|
283 uint32_t mAppID; |
|
284 bool mInBrowser; |
|
285 |
|
286 nsCOMPtr<nsIObserver> mUpdateAvailableObserver; |
|
287 |
|
288 nsCOMPtr<nsIApplicationCache> mApplicationCache; |
|
289 nsCOMPtr<nsIApplicationCache> mPreviousApplicationCache; |
|
290 |
|
291 nsCOMPtr<nsIObserverService> mObserverService; |
|
292 |
|
293 nsRefPtr<nsOfflineManifestItem> mManifestItem; |
|
294 |
|
295 /* Items being updated */ |
|
296 uint32_t mItemsInProgress; |
|
297 nsTArray<nsRefPtr<nsOfflineCacheUpdateItem> > mItems; |
|
298 |
|
299 /* Clients watching this update for changes */ |
|
300 nsCOMArray<nsIWeakReference> mWeakObservers; |
|
301 nsCOMArray<nsIOfflineCacheUpdateObserver> mObservers; |
|
302 |
|
303 /* Documents that requested this update */ |
|
304 nsCOMArray<nsIURI> mDocumentURIs; |
|
305 |
|
306 /* Reschedule count. When an update is rescheduled due to |
|
307 * mismatched manifests, the reschedule count will be increased. */ |
|
308 uint32_t mRescheduleCount; |
|
309 |
|
310 /* Whena an entry for a pinned app is retried, retries count is |
|
311 * increaded. */ |
|
312 uint32_t mPinnedEntryRetriesCount; |
|
313 |
|
314 nsRefPtr<nsOfflineCacheUpdate> mImplicitUpdate; |
|
315 |
|
316 bool mPinned; |
|
317 |
|
318 uint64_t mByteProgress; |
|
319 }; |
|
320 |
|
321 class nsOfflineCacheUpdateService MOZ_FINAL : public nsIOfflineCacheUpdateService |
|
322 , public nsIObserver |
|
323 , public nsOfflineCacheUpdateOwner |
|
324 , public nsSupportsWeakReference |
|
325 { |
|
326 public: |
|
327 NS_DECL_ISUPPORTS |
|
328 NS_DECL_NSIOFFLINECACHEUPDATESERVICE |
|
329 NS_DECL_NSIOBSERVER |
|
330 |
|
331 nsOfflineCacheUpdateService(); |
|
332 ~nsOfflineCacheUpdateService(); |
|
333 |
|
334 nsresult Init(); |
|
335 |
|
336 nsresult ScheduleUpdate(nsOfflineCacheUpdate *aUpdate); |
|
337 nsresult FindUpdate(nsIURI *aManifestURI, |
|
338 uint32_t aAppID, |
|
339 bool aInBrowser, |
|
340 nsOfflineCacheUpdate **aUpdate); |
|
341 |
|
342 nsresult Schedule(nsIURI *aManifestURI, |
|
343 nsIURI *aDocumentURI, |
|
344 nsIDOMDocument *aDocument, |
|
345 nsIDOMWindow* aWindow, |
|
346 nsIFile* aCustomProfileDir, |
|
347 uint32_t aAppID, |
|
348 bool aInBrowser, |
|
349 nsIOfflineCacheUpdate **aUpdate); |
|
350 |
|
351 virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate); |
|
352 |
|
353 /** |
|
354 * Returns the singleton nsOfflineCacheUpdateService without an addref, or |
|
355 * nullptr if the service couldn't be created. |
|
356 */ |
|
357 static nsOfflineCacheUpdateService *EnsureService(); |
|
358 |
|
359 /** Addrefs and returns the singleton nsOfflineCacheUpdateService. */ |
|
360 static nsOfflineCacheUpdateService *GetInstance(); |
|
361 |
|
362 static nsresult OfflineAppPinnedForURI(nsIURI *aDocumentURI, |
|
363 nsIPrefBranch *aPrefBranch, |
|
364 bool *aPinned); |
|
365 |
|
366 static nsTHashtable<nsCStringHashKey>* AllowedDomains(); |
|
367 |
|
368 private: |
|
369 nsresult ProcessNextUpdate(); |
|
370 |
|
371 nsTArray<nsRefPtr<nsOfflineCacheUpdate> > mUpdates; |
|
372 static nsTHashtable<nsCStringHashKey>* mAllowedDomains; |
|
373 |
|
374 bool mDisabled; |
|
375 bool mUpdateRunning; |
|
376 bool mLowFreeSpace; |
|
377 }; |
|
378 |
|
379 #endif |