1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Mozilla Corporation
19 : * Portions created by the Initial Developer are Copyright (C) 2007
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Dave Camp <dcamp@mozilla.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef nsOfflineCacheUpdate_h__
40 : #define nsOfflineCacheUpdate_h__
41 :
42 : #include "nsIOfflineCacheUpdate.h"
43 :
44 : #include "nsAutoPtr.h"
45 : #include "nsCOMArray.h"
46 : #include "nsCOMPtr.h"
47 : #include "nsICacheService.h"
48 : #include "nsIChannelEventSink.h"
49 : #include "nsIDOMDocument.h"
50 : #include "nsIDOMNode.h"
51 : #include "nsIDOMLoadStatus.h"
52 : #include "nsIInterfaceRequestor.h"
53 : #include "nsIMutableArray.h"
54 : #include "nsIObserver.h"
55 : #include "nsIObserverService.h"
56 : #include "nsIApplicationCache.h"
57 : #include "nsIRequestObserver.h"
58 : #include "nsIRunnable.h"
59 : #include "nsIStreamListener.h"
60 : #include "nsIURI.h"
61 : #include "nsIWebProgressListener.h"
62 : #include "nsClassHashtable.h"
63 : #include "nsString.h"
64 : #include "nsTArray.h"
65 : #include "nsWeakReference.h"
66 : #include "nsICryptoHash.h"
67 :
68 : class nsOfflineCacheUpdate;
69 :
70 : class nsICacheEntryDescriptor;
71 : class nsIUTF8StringEnumerator;
72 :
73 : class nsOfflineCacheUpdateItem : public nsIDOMLoadStatus
74 : , public nsIStreamListener
75 : , public nsIRunnable
76 : , public nsIInterfaceRequestor
77 : , public nsIChannelEventSink
78 : {
79 : public:
80 : NS_DECL_ISUPPORTS
81 : NS_DECL_NSIDOMLOADSTATUS
82 : NS_DECL_NSIREQUESTOBSERVER
83 : NS_DECL_NSISTREAMLISTENER
84 : NS_DECL_NSIRUNNABLE
85 : NS_DECL_NSIINTERFACEREQUESTOR
86 : NS_DECL_NSICHANNELEVENTSINK
87 :
88 : nsOfflineCacheUpdateItem(nsOfflineCacheUpdate *aUpdate,
89 : nsIURI *aURI,
90 : nsIURI *aReferrerURI,
91 : nsIApplicationCache *aPreviousApplicationCache,
92 : const nsACString &aClientID,
93 : PRUint32 aType);
94 : virtual ~nsOfflineCacheUpdateItem();
95 :
96 : nsCOMPtr<nsIURI> mURI;
97 : nsCOMPtr<nsIURI> mReferrerURI;
98 : nsCOMPtr<nsIApplicationCache> mPreviousApplicationCache;
99 : nsCString mClientID;
100 : nsCString mCacheKey;
101 : PRUint32 mItemType;
102 :
103 : nsresult OpenChannel();
104 : nsresult Cancel();
105 : nsresult GetRequestSucceeded(bool * succeeded);
106 :
107 : private:
108 : nsOfflineCacheUpdate* mUpdate;
109 : nsCOMPtr<nsIChannel> mChannel;
110 : PRUint16 mState;
111 :
112 : protected:
113 : PRInt32 mBytesRead;
114 : };
115 :
116 :
117 : class nsOfflineManifestItem : public nsOfflineCacheUpdateItem
118 : {
119 : public:
120 : NS_DECL_NSISTREAMLISTENER
121 : NS_DECL_NSIREQUESTOBSERVER
122 :
123 : nsOfflineManifestItem(nsOfflineCacheUpdate *aUpdate,
124 : nsIURI *aURI,
125 : nsIURI *aReferrerURI,
126 : nsIApplicationCache *aPreviousApplicationCache,
127 : const nsACString &aClientID);
128 : virtual ~nsOfflineManifestItem();
129 :
130 8 : nsCOMArray<nsIURI> &GetExplicitURIs() { return mExplicitURIs; }
131 8 : nsCOMArray<nsIURI> &GetFallbackURIs() { return mFallbackURIs; }
132 :
133 8 : nsTArray<nsCString> &GetOpportunisticNamespaces()
134 8 : { return mOpportunisticNamespaces; }
135 8 : nsIArray *GetNamespaces()
136 8 : { return mNamespaces.get(); }
137 :
138 16 : bool ParseSucceeded()
139 16 : { return (mParserState != PARSE_INIT && mParserState != PARSE_ERROR); }
140 8 : bool NeedsUpdate() { return mParserState != PARSE_INIT && mNeedsUpdate; }
141 :
142 8 : void GetManifestHash(nsCString &aManifestHash)
143 8 : { aManifestHash = mManifestHashValue; }
144 :
145 : private:
146 : static NS_METHOD ReadManifest(nsIInputStream *aInputStream,
147 : void *aClosure,
148 : const char *aFromSegment,
149 : PRUint32 aOffset,
150 : PRUint32 aCount,
151 : PRUint32 *aBytesConsumed);
152 :
153 : nsresult AddNamespace(PRUint32 namespaceType,
154 : const nsCString &namespaceSpec,
155 : const nsCString &data);
156 :
157 : nsresult HandleManifestLine(const nsCString::const_iterator &aBegin,
158 : const nsCString::const_iterator &aEnd);
159 :
160 : /**
161 : * Saves "offline-manifest-hash" meta data from the old offline cache
162 : * token to mOldManifestHashValue member to be compared on
163 : * successfull load.
164 : */
165 : nsresult GetOldManifestContentHash(nsIRequest *aRequest);
166 : /**
167 : * This method setups the mNeedsUpdate to false when hash value
168 : * of the just downloaded manifest file is the same as stored in cache's
169 : * "offline-manifest-hash" meta data. Otherwise stores the new value
170 : * to this meta data.
171 : */
172 : nsresult CheckNewManifestContentHash(nsIRequest *aRequest);
173 :
174 : void ReadStrictFileOriginPolicyPref();
175 :
176 : enum {
177 : PARSE_INIT,
178 : PARSE_CACHE_ENTRIES,
179 : PARSE_FALLBACK_ENTRIES,
180 : PARSE_BYPASS_ENTRIES,
181 : PARSE_ERROR
182 : } mParserState;
183 :
184 : nsCString mReadBuf;
185 :
186 : nsCOMArray<nsIURI> mExplicitURIs;
187 : nsCOMArray<nsIURI> mFallbackURIs;
188 :
189 : // All opportunistic caching namespaces. Used to decide whether
190 : // to include previously-opportunistically-cached entries.
191 : nsTArray<nsCString> mOpportunisticNamespaces;
192 :
193 : // Array of nsIApplicationCacheNamespace objects specified by the
194 : // manifest.
195 : nsCOMPtr<nsIMutableArray> mNamespaces;
196 :
197 : bool mNeedsUpdate;
198 : bool mStrictFileOriginPolicy;
199 :
200 : // manifest hash data
201 : nsCOMPtr<nsICryptoHash> mManifestHash;
202 : bool mManifestHashInitialized;
203 : nsCString mManifestHashValue;
204 : nsCString mOldManifestHashValue;
205 : };
206 :
207 : class nsOfflineCacheUpdateOwner
208 16 : {
209 : public:
210 : virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate) = 0;
211 : };
212 :
213 : class nsOfflineCacheUpdate : public nsIOfflineCacheUpdate
214 : , public nsIOfflineCacheUpdateObserver
215 : , public nsOfflineCacheUpdateOwner
216 : {
217 : public:
218 : NS_DECL_ISUPPORTS
219 : NS_DECL_NSIOFFLINECACHEUPDATE
220 : NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
221 :
222 : nsOfflineCacheUpdate();
223 : ~nsOfflineCacheUpdate();
224 :
225 : static nsresult GetCacheKey(nsIURI *aURI, nsACString &aKey);
226 :
227 : nsresult Init();
228 :
229 : nsresult Begin();
230 : nsresult Cancel();
231 :
232 : void LoadCompleted();
233 : void ManifestCheckCompleted(nsresult aStatus,
234 : const nsCString &aManifestHash);
235 : void StickDocument(nsIURI *aDocumentURI);
236 :
237 : void SetOwner(nsOfflineCacheUpdateOwner *aOwner);
238 :
239 : virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate);
240 :
241 : private:
242 : nsresult HandleManifest(bool *aDoUpdate);
243 : nsresult AddURI(nsIURI *aURI, PRUint32 aItemType);
244 :
245 : nsresult ProcessNextURI();
246 :
247 : // Adds items from the previous cache witha type matching aType.
248 : // If namespaceFilter is non-null, only items matching the
249 : // specified namespaces will be added.
250 : nsresult AddExistingItems(PRUint32 aType,
251 : nsTArray<nsCString>* namespaceFilter = nsnull);
252 : nsresult ScheduleImplicit();
253 : nsresult AssociateDocuments(nsIApplicationCache* cache);
254 :
255 : nsresult GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers);
256 : nsresult NotifyState(PRUint32 state);
257 : nsresult Finish();
258 : nsresult FinishNoNotify();
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 : nsOfflineCacheUpdateOwner *mOwner;
270 :
271 : bool mAddedItems;
272 : bool mPartialUpdate;
273 : bool mSucceeded;
274 : bool mObsolete;
275 :
276 : nsCString mUpdateDomain;
277 : nsCOMPtr<nsIURI> mManifestURI;
278 : nsCOMPtr<nsIURI> mDocumentURI;
279 :
280 : nsCString mClientID;
281 : nsCOMPtr<nsIApplicationCache> mApplicationCache;
282 : nsCOMPtr<nsIApplicationCache> mPreviousApplicationCache;
283 :
284 : nsCOMPtr<nsIObserverService> mObserverService;
285 :
286 : nsRefPtr<nsOfflineManifestItem> mManifestItem;
287 :
288 : /* Items being updated */
289 : PRInt32 mCurrentItem;
290 : nsTArray<nsRefPtr<nsOfflineCacheUpdateItem> > mItems;
291 :
292 : /* Clients watching this update for changes */
293 : nsCOMArray<nsIWeakReference> mWeakObservers;
294 : nsCOMArray<nsIOfflineCacheUpdateObserver> mObservers;
295 :
296 : /* Documents that requested this update */
297 : nsCOMArray<nsIURI> mDocumentURIs;
298 :
299 : /* Reschedule count. When an update is rescheduled due to
300 : * mismatched manifests, the reschedule count will be increased. */
301 : PRUint32 mRescheduleCount;
302 :
303 : nsRefPtr<nsOfflineCacheUpdate> mImplicitUpdate;
304 : };
305 :
306 : class nsOfflineCacheUpdateService : public nsIOfflineCacheUpdateService
307 : , public nsIObserver
308 : , public nsOfflineCacheUpdateOwner
309 : , public nsSupportsWeakReference
310 : {
311 : public:
312 : NS_DECL_ISUPPORTS
313 : NS_DECL_NSIOFFLINECACHEUPDATESERVICE
314 : NS_DECL_NSIOBSERVER
315 :
316 : nsOfflineCacheUpdateService();
317 : ~nsOfflineCacheUpdateService();
318 :
319 : nsresult Init();
320 :
321 : nsresult ScheduleUpdate(nsOfflineCacheUpdate *aUpdate);
322 : nsresult FindUpdate(nsIURI *aManifestURI,
323 : nsIURI *aDocumentURI,
324 : nsOfflineCacheUpdate **aUpdate);
325 :
326 : nsresult Schedule(nsIURI *aManifestURI,
327 : nsIURI *aDocumentURI,
328 : nsIDOMDocument *aDocument,
329 : nsIDOMWindow* aWindow,
330 : nsIOfflineCacheUpdate **aUpdate);
331 :
332 : virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate);
333 :
334 : /**
335 : * Returns the singleton nsOfflineCacheUpdateService without an addref, or
336 : * nsnull if the service couldn't be created.
337 : */
338 : static nsOfflineCacheUpdateService *EnsureService();
339 :
340 : /** Addrefs and returns the singleton nsOfflineCacheUpdateService. */
341 : static nsOfflineCacheUpdateService *GetInstance();
342 :
343 : private:
344 : nsresult ProcessNextUpdate();
345 :
346 : nsTArray<nsRefPtr<nsOfflineCacheUpdate> > mUpdates;
347 :
348 : bool mDisabled;
349 : bool mUpdateRunning;
350 : };
351 :
352 : #endif
|