~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/net/instaweb/rewriter/public/critical_finder_support_util.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2013 Google Inc.
3
 
 *
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
7
 
 *
8
 
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
 
17
 
// Author: jmaessen@google.com (Jan Maessen)
18
 
//
19
 
// This contains some utilities for working with the critical_keys
20
 
// proto, and for updating support values. This is primarily used by
21
 
// CriticalSelectorFinder and CriticalImagesFinder.  These finders use the
22
 
// critical_keys proto to store a "support value" for each possible key (image
23
 
// URL or selector name) in the property cache.  When a beacon result arrives,
24
 
// the support for each critical key in the result is increased by
25
 
// support_interval.  When a new beacon is sent, existing support is decayed by
26
 
// multiplying by support_interval/(support_interval+1) and rounding down.  This
27
 
// means that a single key returned with a beacon will be considered critical
28
 
// until support_interval subsequent beacons have been injected.  Because
29
 
// support decays exponentially, repeated support for a key in multiple beacon
30
 
// results cause that key to be considered critical longer: two beacon results
31
 
// will expire after somewhat less than twice as long, three after rather less
32
 
// than three times as long, and so forth. This class also handles converting
33
 
// over old protobufs that did not use the support system.
34
 
 
35
 
#ifndef NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_FINDER_SUPPORT_UTIL_H_
36
 
#define NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_FINDER_SUPPORT_UTIL_H_
37
 
 
38
 
#include "net/instaweb/rewriter/critical_keys.pb.h"
39
 
#include "net/instaweb/util/public/basictypes.h"
40
 
#include "net/instaweb/util/public/property_cache.h"
41
 
#include "net/instaweb/util/public/string.h"
42
 
#include "net/instaweb/util/public/string_util.h"
43
 
#include "net/instaweb/util/public/timer.h"
44
 
 
45
 
namespace net_instaweb {
46
 
 
47
 
// The amount of time after generating a nonce that we will accept it as valid.
48
 
// This keeps an attacker from accumulating large numbers of valid nonces to
49
 
// send many beacon responses at once.
50
 
const int64 kBeaconTimeoutIntervalMs = Timer::kMinuteMs;
51
 
 
52
 
// The number of valid beacons received that will switch from high frequency to
53
 
// low frequency beaconing.
54
 
const int64 kHighFreqBeaconCount = 3;
55
 
 
56
 
// The multiplier to apply to RewriteOptions::beacon_reinstrument_time_sec() to
57
 
// determine the low frequency beaconing interval. For example, the default
58
 
// value rebeaconing value is 5 seconds, so we will rebeacon every 5 seconds in
59
 
// high frequency mode, and every 500 seconds (~8 minutes) in low frequency
60
 
// mode.
61
 
const int64 kLowFreqBeaconMult = 100;
62
 
 
63
 
// The limit on the number of nonces that can expire before we stop trying to do
64
 
// high frequency beaconing. This is a signal that beacons are not configured
65
 
// correctly and so we drop into low frequency beaconing mode.
66
 
const int64 kNonceExpirationLimit = 5;
67
 
 
68
 
class MessageHandler;
69
 
class NonceGenerator;
70
 
class RewriteDriver;
71
 
 
72
 
enum BeaconStatus {
73
 
  kDoNotBeacon,
74
 
  kBeaconNoNonce,
75
 
  kBeaconWithNonce
76
 
};
77
 
 
78
 
struct BeaconMetadata {
79
 
  BeaconMetadata() : status(kDoNotBeacon) { }
80
 
  BeaconStatus status;
81
 
  GoogleString nonce;
82
 
};
83
 
 
84
 
// Check whether the given nonce is valid, invalidating any expired nonce
85
 
// entries we might encounter.  To avoid the need to copy and clear the nonce
86
 
// list, we invalidate the entry used and any expired entries by clearing the
87
 
// nonce value and timestamp.  These entries will be reused by
88
 
// AddNonceToCriticalSelectors.
89
 
bool ValidateAndExpireNonce(int64 now_ms, StringPiece nonce,
90
 
                            CriticalKeys* critical_keys);
91
 
 
92
 
// Generate a list of the critical keys from a proto, storing it into keys.
93
 
// Takes into account legacy keys that may have been added before.  A key is
94
 
// considered critical if its support is at least support_percentage of the
95
 
// maximum possible support value (which ramps up as beacon results arrive).
96
 
// When support_percentage = 0, any support is sufficient; when
97
 
// support_percentage = 100 all beacon results must support criticality.
98
 
void GetCriticalKeysFromProto(int64 support_percentage,
99
 
                              const CriticalKeys& critical_keys,
100
 
                              StringSet* keys);
101
 
 
102
 
// Add support for new_set to existing support.  The new_set should be obtained
103
 
// from a fully-validated beacon result -- this means PrepareForBeaconInsertion
104
 
// should have been called if required, and the resulting nonce should have been
105
 
// checked.  If require_prior_support then there must be an existing support
106
 
// entry (possibly 0) for new support to be registered.
107
 
void UpdateCriticalKeys(bool require_prior_support,
108
 
                        const StringSet& new_set, int support_value,
109
 
                        CriticalKeys* critical_keys);
110
 
 
111
 
bool ShouldBeacon(const CriticalKeys& proto, const RewriteDriver& driver);
112
 
 
113
 
// Update the property cache with a new set of keys. This will update the
114
 
// support value for the new keys. If require_prior_support is set, any keys
115
 
// that are not already present in the property cache will be ignored (to
116
 
// prevent spurious keys from being injected). Note that it only increases the
117
 
// support value for the new keys, it does not decay values that are not
118
 
// present. PrepareForBeaconInsertion should have been called previously if
119
 
// !should_replace_prior_result and nonces must be checked.
120
 
void WriteCriticalKeysToPropertyCache(
121
 
    const StringSet& new_keys, StringPiece nonce, int support_interval,
122
 
    bool should_replace_prior_result, bool require_prior_support,
123
 
    StringPiece property_name, const PropertyCache* cache,
124
 
    const PropertyCache::Cohort* cohort, AbstractPropertyPage* page,
125
 
    MessageHandler* message_handler, Timer* timer);
126
 
 
127
 
// Given a set of candidate critical keys, decide whether beaconing should take
128
 
// place.  We should *always* beacon if there's new critical key data. Otherwise
129
 
// re-beaconing is based on a time and request interval, and 2 modes of
130
 
// beaconing frequency are supported. At first, beaconing occurs at a
131
 
// high frequency until we have collected kHighFreqBeaconCount beacons; after
132
 
// that, we transition into low frequency beaconing mode, where beaconing occurs
133
 
// less often. We also track the number of expired nonces since the last valid
134
 
// beacon was received to see if beaconing is set up correctly, and if it looks
135
 
// like it isn't, only do low frequency beaconing. Sets status and nonce
136
 
// appropriately in *result (nonce will be empty if no nonce is required).  If
137
 
// candidate keys are not required, keys may be empty (but new candidate
138
 
// detection will not occur).  If result->status != kDontBeacon, caller should
139
 
// write proto back to the property cache using UpdateInPropertyCache.
140
 
void PrepareForBeaconInsertionHelper(CriticalKeys* proto,
141
 
                                     NonceGenerator* nonce_generator,
142
 
                                     RewriteDriver* driver,
143
 
                                     bool using_candidate_key_detection,
144
 
                                     BeaconMetadata* result);
145
 
 
146
 
// Update the candidate key set in proto. If new candidate keys are detected,
147
 
// they are inserted into proto with a support value of 0, and true is returned.
148
 
// Otherwise returns false. If clear_rebeacon_timestamp is set, the rebeacon
149
 
// timestamp field in the proto is cleared to force rebeaconing on the next
150
 
// request.
151
 
bool UpdateCandidateKeys(const StringSet& keys, CriticalKeys* proto,
152
 
                         bool clear_rebeacon_timestamp);
153
 
 
154
 
// Based on the CriticalKeys data seen so far, describe whether beacon metadata
155
 
// is available.  This returns false until data is received.
156
 
inline bool IsBeaconDataAvailable(const CriticalKeys& proto) {
157
 
  return (proto.valid_beacons_received() > 0);
158
 
}
159
 
 
160
 
}  // namespace net_instaweb
161
 
 
162
 
#endif  // NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_FINDER_SUPPORT_UTIL_H_