OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_ | |
6 #define NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_ | |
7 | |
8 #include <queue> | |
9 #include <string> | |
10 | |
11 #include "base/basictypes.h" | |
12 #include "base/time/time.h" | |
13 #include "net/base/backoff_entry.h" | |
14 #include "net/base/net_log.h" | |
15 #include "net/url_request/url_request_throttler_entry_interface.h" | |
16 | |
17 namespace net { | |
18 | |
19 class NetworkDelegate; | |
20 class URLRequestThrottlerManager; | |
21 | |
22 // URLRequestThrottlerEntry represents an entry of URLRequestThrottlerManager. | |
23 // It analyzes requests of a specific URL over some period of time, in order to | |
24 // deduce the back-off time for every request. | |
25 // The back-off algorithm consists of two parts. Firstly, exponential back-off | |
26 // is used when receiving 5XX server errors or malformed response bodies. | |
27 // The exponential back-off rule is enforced by URLRequestHttpJob. Any | |
28 // request sent during the back-off period will be cancelled. | |
29 // Secondly, a sliding window is used to count recent requests to a given | |
30 // destination and provide guidance (to the application level only) on whether | |
31 // too many requests have been sent and when a good time to send the next one | |
32 // would be. This is never used to deny requests at the network level. | |
33 class NET_EXPORT URLRequestThrottlerEntry | |
34 : public URLRequestThrottlerEntryInterface { | |
35 public: | |
36 // Sliding window period. | |
37 static const int kDefaultSlidingWindowPeriodMs; | |
38 | |
39 // Maximum number of requests allowed in sliding window period. | |
40 static const int kDefaultMaxSendThreshold; | |
41 | |
42 // Number of initial errors to ignore before starting exponential back-off. | |
43 static const int kDefaultNumErrorsToIgnore; | |
44 | |
45 // Initial delay for exponential back-off. | |
46 static const int kDefaultInitialDelayMs; | |
47 | |
48 // Factor by which the waiting time will be multiplied. | |
49 static const double kDefaultMultiplyFactor; | |
50 | |
51 // Fuzzing percentage. ex: 10% will spread requests randomly | |
52 // between 90%-100% of the calculated time. | |
53 static const double kDefaultJitterFactor; | |
54 | |
55 // Maximum amount of time we are willing to delay our request. | |
56 static const int kDefaultMaximumBackoffMs; | |
57 | |
58 // Time after which the entry is considered outdated. | |
59 static const int kDefaultEntryLifetimeMs; | |
60 | |
61 // Name of the header that sites can use to opt out of exponential back-off | |
62 // throttling. | |
63 static const char kExponentialThrottlingHeader[]; | |
64 | |
65 // Value for exponential throttling header that can be used to opt out of | |
66 // exponential back-off throttling. | |
67 static const char kExponentialThrottlingDisableValue[]; | |
68 | |
69 // The manager object's lifetime must enclose the lifetime of this object. | |
70 URLRequestThrottlerEntry(URLRequestThrottlerManager* manager, | |
71 const std::string& url_id); | |
72 | |
73 // The life span of instances created with this constructor is set to | |
74 // infinite, and the number of initial errors to ignore is set to 0. | |
75 // It is only used by unit tests. | |
76 URLRequestThrottlerEntry(URLRequestThrottlerManager* manager, | |
77 const std::string& url_id, | |
78 int sliding_window_period_ms, | |
79 int max_send_threshold, | |
80 int initial_backoff_ms, | |
81 double multiply_factor, | |
82 double jitter_factor, | |
83 int maximum_backoff_ms); | |
84 | |
85 // Used by the manager, returns true if the entry needs to be garbage | |
86 // collected. | |
87 bool IsEntryOutdated() const; | |
88 | |
89 // Causes this entry to never reject requests due to back-off. | |
90 void DisableBackoffThrottling(); | |
91 | |
92 // Causes this entry to NULL its manager pointer. | |
93 void DetachManager(); | |
94 | |
95 // Implementation of URLRequestThrottlerEntryInterface. | |
96 bool ShouldRejectRequest(const URLRequest& request, | |
97 NetworkDelegate* network_delegate) const override; | |
98 int64 ReserveSendingTimeForNextRequest( | |
99 const base::TimeTicks& earliest_time) override; | |
100 base::TimeTicks GetExponentialBackoffReleaseTime() const override; | |
101 void UpdateWithResponse( | |
102 const std::string& host, | |
103 const URLRequestThrottlerHeaderInterface* response) override; | |
104 void ReceivedContentWasMalformed(int response_code) override; | |
105 | |
106 protected: | |
107 ~URLRequestThrottlerEntry() override; | |
108 | |
109 void Initialize(); | |
110 | |
111 // Returns true if the given response code is considered an error for | |
112 // throttling purposes. | |
113 bool IsConsideredError(int response_code); | |
114 | |
115 // Equivalent to TimeTicks::Now(), virtual to be mockable for testing purpose. | |
116 virtual base::TimeTicks ImplGetTimeNow() const; | |
117 | |
118 // Used internally to handle the opt-out header. | |
119 void HandleThrottlingHeader(const std::string& header_value, | |
120 const std::string& host); | |
121 | |
122 // Retrieves the back-off entry object we're using. Used to enable a | |
123 // unit testing seam for dependency injection in tests. | |
124 virtual const BackoffEntry* GetBackoffEntry() const; | |
125 virtual BackoffEntry* GetBackoffEntry(); | |
126 | |
127 // Returns true if |load_flags| contains a flag that indicates an | |
128 // explicit request by the user to load the resource. We never | |
129 // throttle requests with such load flags. | |
130 static bool ExplicitUserRequest(const int load_flags); | |
131 | |
132 // Used by tests. | |
133 base::TimeTicks sliding_window_release_time() const { | |
134 return sliding_window_release_time_; | |
135 } | |
136 | |
137 // Used by tests. | |
138 void set_sliding_window_release_time(const base::TimeTicks& release_time) { | |
139 sliding_window_release_time_ = release_time; | |
140 } | |
141 | |
142 // Valid and immutable after construction time. | |
143 BackoffEntry::Policy backoff_policy_; | |
144 | |
145 private: | |
146 // Timestamp calculated by the sliding window algorithm for when we advise | |
147 // clients the next request should be made, at the earliest. Advisory only, | |
148 // not used to deny requests. | |
149 base::TimeTicks sliding_window_release_time_; | |
150 | |
151 // A list of the recent send events. We use them to decide whether there are | |
152 // too many requests sent in sliding window. | |
153 std::queue<base::TimeTicks> send_log_; | |
154 | |
155 const base::TimeDelta sliding_window_period_; | |
156 const int max_send_threshold_; | |
157 | |
158 // True if DisableBackoffThrottling() has been called on this object. | |
159 bool is_backoff_disabled_; | |
160 | |
161 // Access it through GetBackoffEntry() to allow a unit test seam. | |
162 BackoffEntry backoff_entry_; | |
163 | |
164 // Weak back-reference to the manager object managing us. | |
165 URLRequestThrottlerManager* manager_; | |
166 | |
167 // Canonicalized URL string that this entry is for; used for logging only. | |
168 std::string url_id_; | |
169 | |
170 BoundNetLog net_log_; | |
171 | |
172 DISALLOW_COPY_AND_ASSIGN(URLRequestThrottlerEntry); | |
173 }; | |
174 | |
175 } // namespace net | |
176 | |
177 #endif // NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_ | |
OLD | NEW |