uriloader/prefetch/nsOfflineCacheUpdate.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:0e9ac3021c98
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

mercurial