Source code

Revision control

Other Tools

1
/* vim: set ts=2 sts=2 et sw=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/. */
5
6
#ifndef mozilla_net_Predictor_h
7
#define mozilla_net_Predictor_h
8
9
#include "nsINetworkPredictor.h"
10
#include "nsINetworkPredictorVerifier.h"
11
12
#include "nsCOMPtr.h"
13
#include "nsICacheEntry.h"
14
#include "nsICacheEntryOpenCallback.h"
15
#include "nsICacheStorageService.h"
16
#include "nsICacheStorageVisitor.h"
17
#include "nsIDNSListener.h"
18
#include "nsIInterfaceRequestor.h"
19
#include "nsIObserver.h"
20
#include "nsISpeculativeConnect.h"
21
#include "nsIStreamListener.h"
22
#include "mozilla/RefPtr.h"
23
#include "nsString.h"
24
#include "nsTArray.h"
25
26
#include "mozilla/TimeStamp.h"
27
28
class nsICacheStorage;
29
class nsIDNSService;
30
class nsIIOService;
31
class nsILoadContextInfo;
32
class nsITimer;
33
34
namespace mozilla {
35
namespace net {
36
37
class nsHttpRequestHead;
38
class nsHttpResponseHead;
39
40
class Predictor final : public nsINetworkPredictor,
41
public nsIObserver,
42
public nsISpeculativeConnectionOverrider,
43
public nsIInterfaceRequestor,
44
public nsICacheEntryMetaDataVisitor,
45
public nsINetworkPredictorVerifier {
46
public:
47
NS_DECL_ISUPPORTS
48
NS_DECL_NSINETWORKPREDICTOR
49
NS_DECL_NSIOBSERVER
50
NS_DECL_NSISPECULATIVECONNECTIONOVERRIDER
51
NS_DECL_NSIINTERFACEREQUESTOR
52
NS_DECL_NSICACHEENTRYMETADATAVISITOR
53
NS_DECL_NSINETWORKPREDICTORVERIFIER
54
55
Predictor();
56
57
nsresult Init();
58
void Shutdown();
59
static nsresult Create(nsISupports* outer, const nsIID& iid, void** result);
60
61
// Used to update whether a particular URI was cacheable or not.
62
// sourceURI and targetURI are the same as the arguments to Learn
63
// and httpStatus is the status code we got while loading targetURI.
64
static void UpdateCacheability(nsIURI* sourceURI, nsIURI* targetURI,
65
uint32_t httpStatus,
66
nsHttpRequestHead& requestHead,
67
nsHttpResponseHead* reqponseHead,
68
nsILoadContextInfo* lci, bool isTracking);
69
70
private:
71
virtual ~Predictor();
72
73
// Stores callbacks for a child process predictor (for test purposes)
74
nsCOMPtr<nsINetworkPredictorVerifier> mChildVerifier;
75
76
union Reason {
77
PredictorLearnReason mLearn;
78
PredictorPredictReason mPredict;
79
};
80
81
class DNSListener : public nsIDNSListener {
82
public:
83
NS_DECL_THREADSAFE_ISUPPORTS
84
NS_DECL_NSIDNSLISTENER
85
86
DNSListener() = default;
87
88
private:
89
virtual ~DNSListener() = default;
90
};
91
92
class Action : public nsICacheEntryOpenCallback {
93
public:
94
NS_DECL_THREADSAFE_ISUPPORTS
95
NS_DECL_NSICACHEENTRYOPENCALLBACK
96
97
Action(bool fullUri, bool predict, Reason reason, nsIURI* targetURI,
98
nsIURI* sourceURI, nsINetworkPredictorVerifier* verifier,
99
Predictor* predictor);
100
Action(bool fullUri, bool predict, Reason reason, nsIURI* targetURI,
101
nsIURI* sourceURI, nsINetworkPredictorVerifier* verifier,
102
Predictor* predictor, uint8_t stackCount);
103
104
static const bool IS_FULL_URI = true;
105
static const bool IS_ORIGIN = false;
106
107
static const bool DO_PREDICT = true;
108
static const bool DO_LEARN = false;
109
110
private:
111
virtual ~Action() = default;
112
113
bool mFullUri : 1;
114
bool mPredict : 1;
115
union {
116
PredictorPredictReason mPredictReason;
117
PredictorLearnReason mLearnReason;
118
};
119
nsCOMPtr<nsIURI> mTargetURI;
120
nsCOMPtr<nsIURI> mSourceURI;
121
nsCOMPtr<nsINetworkPredictorVerifier> mVerifier;
122
TimeStamp mStartTime;
123
uint8_t mStackCount;
124
RefPtr<Predictor> mPredictor;
125
};
126
127
class CacheabilityAction : public nsICacheEntryOpenCallback,
128
public nsICacheEntryMetaDataVisitor {
129
public:
130
NS_DECL_THREADSAFE_ISUPPORTS
131
NS_DECL_NSICACHEENTRYOPENCALLBACK
132
NS_DECL_NSICACHEENTRYMETADATAVISITOR
133
134
CacheabilityAction(nsIURI* targetURI, uint32_t httpStatus,
135
const nsCString& method, bool isTracking, bool couldVary,
136
bool isNoStore, Predictor* predictor)
137
: mTargetURI(targetURI),
138
mHttpStatus(httpStatus),
139
mMethod(method),
140
mIsTracking(isTracking),
141
mCouldVary(couldVary),
142
mIsNoStore(isNoStore),
143
mPredictor(predictor) {}
144
145
private:
146
virtual ~CacheabilityAction() = default;
147
148
nsCOMPtr<nsIURI> mTargetURI;
149
uint32_t mHttpStatus;
150
nsCString mMethod;
151
bool mIsTracking;
152
bool mCouldVary;
153
bool mIsNoStore;
154
RefPtr<Predictor> mPredictor;
155
nsTArray<nsCString> mKeysToCheck;
156
nsTArray<nsCString> mValuesToCheck;
157
};
158
159
class Resetter : public nsICacheEntryOpenCallback,
160
public nsICacheEntryMetaDataVisitor,
161
public nsICacheStorageVisitor {
162
public:
163
NS_DECL_THREADSAFE_ISUPPORTS
164
NS_DECL_NSICACHEENTRYOPENCALLBACK
165
NS_DECL_NSICACHEENTRYMETADATAVISITOR
166
NS_DECL_NSICACHESTORAGEVISITOR
167
168
explicit Resetter(Predictor* predictor);
169
170
private:
171
virtual ~Resetter() = default;
172
173
void Complete();
174
175
uint32_t mEntriesToVisit;
176
nsTArray<nsCString> mKeysToDelete;
177
RefPtr<Predictor> mPredictor;
178
nsTArray<nsCOMPtr<nsIURI>> mURIsToVisit;
179
nsTArray<nsCOMPtr<nsILoadContextInfo>> mInfosToVisit;
180
};
181
182
class SpaceCleaner : public nsICacheEntryMetaDataVisitor {
183
public:
184
NS_DECL_ISUPPORTS
185
NS_DECL_NSICACHEENTRYMETADATAVISITOR
186
187
explicit SpaceCleaner(Predictor* predictor)
188
: mLRUStamp(0), mLRUKeyToDelete(nullptr), mPredictor(predictor) {}
189
190
void Finalize(nsICacheEntry* entry);
191
192
private:
193
virtual ~SpaceCleaner() = default;
194
uint32_t mLRUStamp;
195
const char* mLRUKeyToDelete;
196
nsTArray<nsCString> mLongKeysToDelete;
197
RefPtr<Predictor> mPredictor;
198
};
199
200
class PrefetchListener : public nsIStreamListener {
201
public:
202
NS_DECL_ISUPPORTS
203
NS_DECL_NSIREQUESTOBSERVER
204
NS_DECL_NSISTREAMLISTENER
205
206
PrefetchListener(nsINetworkPredictorVerifier* verifier, nsIURI* uri,
207
Predictor* predictor)
208
: mVerifier(verifier), mURI(uri), mPredictor(predictor) {}
209
210
private:
211
virtual ~PrefetchListener() = default;
212
213
nsCOMPtr<nsINetworkPredictorVerifier> mVerifier;
214
nsCOMPtr<nsIURI> mURI;
215
RefPtr<Predictor> mPredictor;
216
TimeStamp mStartTime;
217
};
218
219
// Observer-related stuff
220
nsresult InstallObserver();
221
void RemoveObserver();
222
223
// Service startup utilities
224
void MaybeCleanupOldDBFiles();
225
226
// The guts of prediction
227
228
// This is the top-level driver for doing any prediction that needs
229
// information from the cache. Returns true if any predictions were queued up
230
// * reason - What kind of prediction this is/why this prediction is
231
// happening (pageload, startup)
232
// * entry - the cache entry with the information we need
233
// * isNew - whether or not the cache entry is brand new and empty
234
// * fullUri - whether we are doing predictions based on a full page URI, or
235
// just the origin of the page
236
// * targetURI - the URI that we are predicting based upon - IOW, the URI
237
// that is being loaded or being redirected to
238
// * verifier - used for testing to verify the expected predictions happen
239
// * stackCount - used to ensure we don't recurse too far trying to find the
240
// final redirection in a redirect chain
241
bool PredictInternal(PredictorPredictReason reason, nsICacheEntry* entry,
242
bool isNew, bool fullUri, nsIURI* targetURI,
243
nsINetworkPredictorVerifier* verifier,
244
uint8_t stackCount);
245
246
// Used when predicting because the user's mouse hovered over a link
247
// * targetURI - the URI target of the link
248
// * sourceURI - the URI of the page on which the link appears
249
// * originAttributes - the originAttributes for this prediction
250
// * verifier - used for testing to verify the expected predictions happen
251
void PredictForLink(nsIURI* targetURI, nsIURI* sourceURI,
252
const OriginAttributes& originAttributes,
253
nsINetworkPredictorVerifier* verifier);
254
255
// Used when predicting because a page is being loaded (which may include
256
// being the target of a redirect). All arguments are the same as for
257
// PredictInternal. Returns true if any predictions were queued up.
258
bool PredictForPageload(nsICacheEntry* entry, nsIURI* targetURI,
259
uint8_t stackCount, bool fullUri,
260
nsINetworkPredictorVerifier* verifier);
261
262
// Used when predicting pages that will be used near browser startup. All
263
// arguments are the same as for PredictInternal. Returns true if any
264
// predictions were queued up.
265
bool PredictForStartup(nsICacheEntry* entry, bool fullUri,
266
nsINetworkPredictorVerifier* verifier);
267
268
// Utilities related to prediction
269
270
// Used to update our rolling load count (how many of the last n loads was a
271
// partular resource loaded on?)
272
// * entry - cache entry of page we're loading
273
// * flags - value that contains our rolling count as the top 20 bits (but
274
// we may use fewer than those 20 bits for calculations)
275
// * key - metadata key that we will update on entry
276
// * hitCount - part of the metadata we need to preserve
277
// * lastHit - part of the metadata we need to preserve
278
void UpdateRollingLoadCount(nsICacheEntry* entry, const uint32_t flags,
279
const char* key, const uint32_t hitCount,
280
const uint32_t lastHit);
281
282
// Used to calculate how much to degrade our confidence for all resources
283
// on a particular page, because of how long ago the most recent load of that
284
// page was. Returns a value between 0 (very recent most recent load) and 100
285
// (very distant most recent load)
286
// * lastLoad - time stamp of most recent load of a page
287
int32_t CalculateGlobalDegradation(uint32_t lastLoad);
288
289
// Used to calculate how confident we are that a particular resource will be
290
// used. Returns a value between 0 (no confidence) and 100 (very confident)
291
// * hitCount - number of times this resource has been seen when loading
292
// this page
293
// * hitsPossible - number of times this page has been loaded
294
// * lastHit - timestamp of the last time this resource was seen when
295
// loading this page
296
// * lastPossible - timestamp of the last time this page was loaded
297
// * globalDegradation - value calculated by CalculateGlobalDegradation for
298
// this page
299
int32_t CalculateConfidence(uint32_t hitCount, uint32_t hitsPossible,
300
uint32_t lastHit, uint32_t lastPossible,
301
int32_t globalDegradation);
302
303
// Used to calculate all confidence values for all resources associated with a
304
// page.
305
// * entry - the cache entry with all necessary information about this page
306
// * referrer - the URI that we are loading (may be null)
307
// * lastLoad - timestamp of the last time this page was loaded
308
// * loadCount - number of times this page has been loaded
309
// * gloablDegradation - value calculated by CalculateGlobalDegradation for
310
// this page
311
// * fullUri - whether we're predicting for a full URI or origin-only
312
void CalculatePredictions(nsICacheEntry* entry, nsIURI* referrer,
313
uint32_t lastLoad, uint32_t loadCount,
314
int32_t globalDegradation, bool fullUri);
315
316
enum PrefetchIgnoreReason {
317
PREFETCH_OK,
318
NOT_FULL_URI,
319
NO_REFERRER,
320
MISSED_A_LOAD,
321
PREFETCH_DISABLED,
322
PREFETCH_DISABLED_VIA_COUNT,
323
CONFIDENCE_TOO_LOW
324
};
325
326
// Used to prepare any necessary prediction for a resource on a page
327
// * confidence - value calculated by CalculateConfidence for this resource
328
// * flags - the flags taken from the resource
329
// * uri - the ascii spec of the URI of the resource
330
void SetupPrediction(int32_t confidence, uint32_t flags, const nsCString& uri,
331
PrefetchIgnoreReason reason);
332
333
// Used to kick off a prefetch from RunPredictions if necessary
334
// * uri - the URI to prefetch
335
// * referrer - the URI of the referring page
336
// * originAttributes - the originAttributes of this prefetch
337
// * verifier - used for testing to ensure the expected prefetch happens
338
nsresult Prefetch(nsIURI* uri, nsIURI* referrer,
339
const OriginAttributes& originAttributes,
340
nsINetworkPredictorVerifier* verifier);
341
342
// Used to actually perform any predictions set up via SetupPrediction.
343
// Returns true if any predictions were performed.
344
// * referrer - the URI we are predicting from
345
// * originAttributs - the originAttributes we are predicting from
346
// * verifier - used for testing to ensure the expected predictions happen
347
bool RunPredictions(nsIURI* referrer,
348
const OriginAttributes& originAttributes,
349
nsINetworkPredictorVerifier* verifier);
350
351
// Used to guess whether a page will redirect to another page or not. Returns
352
// true if a redirection is likely.
353
// * entry - cache entry with all necessary information about this page
354
// * loadCount - number of times this page has been loaded
355
// * lastLoad - timestamp of the last time this page was loaded
356
// * globalDegradation - value calculated by CalculateGlobalDegradation for
357
// this page
358
// * redirectURI - if this returns true, the URI that is likely to be
359
// redirected to, otherwise null
360
bool WouldRedirect(nsICacheEntry* entry, uint32_t loadCount,
361
uint32_t lastLoad, int32_t globalDegradation,
362
nsIURI** redirectURI);
363
364
// The guts of learning information
365
366
// This is the top-level driver for doing any updating of our information in
367
// the cache
368
// * reason - why this learn is happening (pageload, startup, redirect)
369
// * entry - the cache entry with the information we need
370
// * isNew - whether or not the cache entry is brand new and empty
371
// * fullUri - whether we are doing predictions based on a full page URI, or
372
// just the origin of the page
373
// * targetURI - the URI that we are adding to our data - most often a
374
// resource loaded by a page the user navigated to
375
// * sourceURI - the URI that caused targetURI to be loaded, usually the
376
// page the user navigated to
377
void LearnInternal(PredictorLearnReason reason, nsICacheEntry* entry,
378
bool isNew, bool fullUri, nsIURI* targetURI,
379
nsIURI* sourceURI);
380
381
// Used when learning about a resource loaded by a page
382
// * entry - the cache entry with information that needs updating
383
// * targetURI - the URI of the resource that was loaded by the page
384
void LearnForSubresource(nsICacheEntry* entry, nsIURI* targetURI);
385
386
// Used when learning about a redirect from one page to another
387
// * entry - the cache entry of the page that was redirected from
388
// * targetURI - the URI of the redirect target
389
void LearnForRedirect(nsICacheEntry* entry, nsIURI* targetURI);
390
391
// Used to learn about pages loaded close to browser startup. This results in
392
// LearnForStartup being called if we are, in fact, near browser startup
393
// * uri - the URI of a page that has been loaded (may not have been near
394
// browser startup)
395
// * fullUri - true if this is a full page uri, false if it's an origin
396
// * originAttributes - the originAttributes for this learning.
397
void MaybeLearnForStartup(nsIURI* uri, bool fullUri,
398
const OriginAttributes& originAttributes);
399
400
// Used in conjunction with MaybeLearnForStartup to learn about pages loaded
401
// close to browser startup
402
// * entry - the cache entry that stores the startup page list
403
// * targetURI - the URI of a page that was loaded near browser startup
404
void LearnForStartup(nsICacheEntry* entry, nsIURI* targetURI);
405
406
// Used to parse the data we store in cache metadata
407
// * key - the cache metadata key
408
// * value - the cache metadata value
409
// * uri - (out) the ascii spec of the URI this metadata entry was about
410
// * hitCount - (out) the number of times this URI has been seen
411
// * lastHit - (out) timestamp of the last time this URI was seen
412
// * flags - (out) flags for this metadata entry
413
bool ParseMetaDataEntry(const char* key, const char* value, nsCString& uri,
414
uint32_t& hitCount, uint32_t& lastHit,
415
uint32_t& flags);
416
417
// Used to update whether a particular URI was cacheable or not.
418
// sourceURI and targetURI are the same as the arguments to Learn
419
// and httpStatus is the status code we got while loading targetURI.
420
void UpdateCacheabilityInternal(nsIURI* sourceURI, nsIURI* targetURI,
421
uint32_t httpStatus, const nsCString& method,
422
const OriginAttributes& originAttributes,
423
bool isTracking, bool couldVary,
424
bool isNoStore);
425
426
// Gets the pref value and clamps it within the acceptable range.
427
uint32_t ClampedPrefetchRollingLoadCount();
428
429
// Our state
430
bool mInitialized;
431
432
bool mCleanedUp;
433
nsCOMPtr<nsITimer> mCleanupTimer;
434
435
nsTArray<nsCString> mKeysToOperateOn;
436
nsTArray<nsCString> mValuesToOperateOn;
437
438
nsCOMPtr<nsICacheStorageService> mCacheStorageService;
439
440
nsCOMPtr<nsIIOService> mIOService;
441
nsCOMPtr<nsISpeculativeConnect> mSpeculativeService;
442
443
nsCOMPtr<nsIURI> mStartupURI;
444
uint32_t mStartupTime;
445
uint32_t mLastStartupTime;
446
int32_t mStartupCount;
447
448
nsCOMPtr<nsIDNSService> mDnsService;
449
450
RefPtr<DNSListener> mDNSListener;
451
452
nsTArray<nsCOMPtr<nsIURI>> mPrefetches;
453
nsTArray<nsCOMPtr<nsIURI>> mPreconnects;
454
nsTArray<nsCOMPtr<nsIURI>> mPreresolves;
455
456
static Predictor* sSelf;
457
};
458
459
} // namespace net
460
} // namespace mozilla
461
462
#endif // mozilla_net_Predictor_h