Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: net/url_request/url_request_throttler_entry.cc

Issue 1148603003: Remove X-Chrome-Exponential-Throttling header (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/url_request/url_request_throttler_entry.h" 5 #include "net/url_request/url_request_throttler_entry.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/field_trial.h" 10 #include "base/metrics/field_trial.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/rand_util.h" 12 #include "base/rand_util.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "net/base/load_flags.h" 15 #include "net/base/load_flags.h"
16 #include "net/log/net_log.h" 16 #include "net/log/net_log.h"
17 #include "net/url_request/url_request.h" 17 #include "net/url_request/url_request.h"
18 #include "net/url_request/url_request_context.h" 18 #include "net/url_request/url_request_context.h"
19 #include "net/url_request/url_request_throttler_header_interface.h"
20 #include "net/url_request/url_request_throttler_manager.h" 19 #include "net/url_request/url_request_throttler_manager.h"
21 20
22 namespace net { 21 namespace net {
23 22
24 const int URLRequestThrottlerEntry::kDefaultSlidingWindowPeriodMs = 2000; 23 const int URLRequestThrottlerEntry::kDefaultSlidingWindowPeriodMs = 2000;
25 const int URLRequestThrottlerEntry::kDefaultMaxSendThreshold = 20; 24 const int URLRequestThrottlerEntry::kDefaultMaxSendThreshold = 20;
26 25
27 // This set of back-off parameters will (at maximum values, i.e. without 26 // This set of back-off parameters will (at maximum values, i.e. without
28 // the reduction caused by jitter) add 0-41% (distributed uniformly 27 // the reduction caused by jitter) add 0-41% (distributed uniformly
29 // in that range) to the "perceived downtime" of the remote server, once 28 // in that range) to the "perceived downtime" of the remote server, once
30 // exponential back-off kicks in and is throttling requests for more than 29 // exponential back-off kicks in and is throttling requests for more than
31 // about a second at a time. Once the maximum back-off is reached, the added 30 // about a second at a time. Once the maximum back-off is reached, the added
32 // perceived downtime decreases rapidly, percentage-wise. 31 // perceived downtime decreases rapidly, percentage-wise.
33 // 32 //
34 // Another way to put it is that the maximum additional perceived downtime 33 // Another way to put it is that the maximum additional perceived downtime
35 // with these numbers is a couple of seconds shy of 15 minutes, and such 34 // with these numbers is a couple of seconds shy of 15 minutes, and such
36 // a delay would not occur until the remote server has been actually 35 // a delay would not occur until the remote server has been actually
37 // unavailable at the end of each back-off period for a total of about 36 // unavailable at the end of each back-off period for a total of about
38 // 48 minutes. 37 // 48 minutes.
39 // 38 //
40 // Ignoring the first couple of errors is just a conservative measure to 39 // Ignoring the first couple of errors is just a conservative measure to
41 // avoid false positives. It should help avoid back-off from kicking in e.g. 40 // avoid false positives. It should help avoid back-off from kicking in e.g.
42 // on flaky connections. 41 // on flaky connections.
43 const int URLRequestThrottlerEntry::kDefaultNumErrorsToIgnore = 2; 42 const int URLRequestThrottlerEntry::kDefaultNumErrorsToIgnore = 2;
44 const int URLRequestThrottlerEntry::kDefaultInitialDelayMs = 700; 43 const int URLRequestThrottlerEntry::kDefaultInitialDelayMs = 700;
45 const double URLRequestThrottlerEntry::kDefaultMultiplyFactor = 1.4; 44 const double URLRequestThrottlerEntry::kDefaultMultiplyFactor = 1.4;
46 const double URLRequestThrottlerEntry::kDefaultJitterFactor = 0.4; 45 const double URLRequestThrottlerEntry::kDefaultJitterFactor = 0.4;
47 const int URLRequestThrottlerEntry::kDefaultMaximumBackoffMs = 15 * 60 * 1000; 46 const int URLRequestThrottlerEntry::kDefaultMaximumBackoffMs = 15 * 60 * 1000;
48 const int URLRequestThrottlerEntry::kDefaultEntryLifetimeMs = 2 * 60 * 1000; 47 const int URLRequestThrottlerEntry::kDefaultEntryLifetimeMs = 2 * 60 * 1000;
49 const char URLRequestThrottlerEntry::kExponentialThrottlingHeader[] =
50 "X-Chrome-Exponential-Throttling";
51 const char URLRequestThrottlerEntry::kExponentialThrottlingDisableValue[] =
52 "disable";
53 48
54 // Returns NetLog parameters when a request is rejected by throttling. 49 // Returns NetLog parameters when a request is rejected by throttling.
55 base::Value* NetLogRejectedRequestCallback( 50 base::Value* NetLogRejectedRequestCallback(
56 const std::string* url_id, 51 const std::string* url_id,
57 int num_failures, 52 int num_failures,
58 const base::TimeDelta& release_after, 53 const base::TimeDelta& release_after,
59 NetLogCaptureMode /* capture_mode */) { 54 NetLogCaptureMode /* capture_mode */) {
60 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 55 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
61 dict->SetString("url", *url_id); 56 dict->SetString("url", *url_id);
62 dict->SetInteger("num_failures", num_failures); 57 dict->SetInteger("num_failures", num_failures);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 // the back-off mechanism when it shouldn't be triggered, in which case 210 // the back-off mechanism when it shouldn't be triggered, in which case
216 // returning the calculated back-off release time would probably be the 211 // returning the calculated back-off release time would probably be the
217 // wrong thing to do (i.e. it would likely be too long). Therefore, we 212 // wrong thing to do (i.e. it would likely be too long). Therefore, we
218 // return "now" so that retries are not delayed. 213 // return "now" so that retries are not delayed.
219 if (is_backoff_disabled_) 214 if (is_backoff_disabled_)
220 return ImplGetTimeNow(); 215 return ImplGetTimeNow();
221 216
222 return GetBackoffEntry()->GetReleaseTime(); 217 return GetBackoffEntry()->GetReleaseTime();
223 } 218 }
224 219
225 void URLRequestThrottlerEntry::UpdateWithResponse( 220 void URLRequestThrottlerEntry::UpdateWithResponse(int status_code) {
226 const std::string& host, 221 GetBackoffEntry()->InformOfRequest(IsConsideredSuccess(status_code));
227 const URLRequestThrottlerHeaderInterface* response) {
228 if (IsConsideredError(response->GetResponseCode())) {
229 GetBackoffEntry()->InformOfRequest(false);
230 } else {
231 GetBackoffEntry()->InformOfRequest(true);
232
233 std::string throttling_header = response->GetNormalizedValue(
234 kExponentialThrottlingHeader);
235 if (!throttling_header.empty())
236 HandleThrottlingHeader(throttling_header, host);
237 }
238 } 222 }
239 223
240 void URLRequestThrottlerEntry::ReceivedContentWasMalformed(int response_code) { 224 void URLRequestThrottlerEntry::ReceivedContentWasMalformed(int response_code) {
241 // A malformed body can only occur when the request to fetch a resource 225 // A malformed body can only occur when the request to fetch a resource
242 // was successful. Therefore, in such a situation, we will receive one 226 // was successful. Therefore, in such a situation, we will receive one
243 // call to ReceivedContentWasMalformed() and one call to 227 // call to ReceivedContentWasMalformed() and one call to
244 // UpdateWithResponse() with a response categorized as "good". To end 228 // UpdateWithResponse() with a response categorized as "good". To end
245 // up counting one failure, we need to count two failures here against 229 // up counting one failure, we need to count two failures here against
246 // the one success in UpdateWithResponse(). 230 // the one success in UpdateWithResponse().
247 // 231 //
248 // We do nothing for a response that is already being considered an error 232 // We do nothing for a response that is already being considered an error
249 // based on its status code (otherwise we would count 3 errors instead of 1). 233 // based on its status code (otherwise we would count 3 errors instead of 1).
250 if (!IsConsideredError(response_code)) { 234 if (IsConsideredSuccess(response_code)) {
251 GetBackoffEntry()->InformOfRequest(false); 235 GetBackoffEntry()->InformOfRequest(false);
252 GetBackoffEntry()->InformOfRequest(false); 236 GetBackoffEntry()->InformOfRequest(false);
253 } 237 }
254 } 238 }
255 239
256 URLRequestThrottlerEntry::~URLRequestThrottlerEntry() { 240 URLRequestThrottlerEntry::~URLRequestThrottlerEntry() {
257 } 241 }
258 242
259 void URLRequestThrottlerEntry::Initialize() { 243 void URLRequestThrottlerEntry::Initialize() {
260 sliding_window_release_time_ = base::TimeTicks::Now(); 244 sliding_window_release_time_ = base::TimeTicks::Now();
261 backoff_policy_.num_errors_to_ignore = kDefaultNumErrorsToIgnore; 245 backoff_policy_.num_errors_to_ignore = kDefaultNumErrorsToIgnore;
262 backoff_policy_.initial_delay_ms = kDefaultInitialDelayMs; 246 backoff_policy_.initial_delay_ms = kDefaultInitialDelayMs;
263 backoff_policy_.multiply_factor = kDefaultMultiplyFactor; 247 backoff_policy_.multiply_factor = kDefaultMultiplyFactor;
264 backoff_policy_.jitter_factor = kDefaultJitterFactor; 248 backoff_policy_.jitter_factor = kDefaultJitterFactor;
265 backoff_policy_.maximum_backoff_ms = kDefaultMaximumBackoffMs; 249 backoff_policy_.maximum_backoff_ms = kDefaultMaximumBackoffMs;
266 backoff_policy_.entry_lifetime_ms = kDefaultEntryLifetimeMs; 250 backoff_policy_.entry_lifetime_ms = kDefaultEntryLifetimeMs;
267 backoff_policy_.always_use_initial_delay = false; 251 backoff_policy_.always_use_initial_delay = false;
268 } 252 }
269 253
270 bool URLRequestThrottlerEntry::IsConsideredError(int response_code) { 254 bool URLRequestThrottlerEntry::IsConsideredSuccess(int response_code) {
271 // We throttle only for the status codes most likely to indicate the server 255 // We throttle only for the status codes most likely to indicate the server
272 // is failing because it is too busy or otherwise are likely to be 256 // is failing because it is too busy or otherwise are likely to be
273 // because of DDoS. 257 // because of DDoS.
274 // 258 //
275 // 500 is the generic error when no better message is suitable, and 259 // 500 is the generic error when no better message is suitable, and
276 // as such does not necessarily indicate a temporary state, but 260 // as such does not necessarily indicate a temporary state, but
277 // other status codes cover most of the permanent error states. 261 // other status codes cover most of the permanent error states.
278 // 503 is explicitly documented as a temporary state where the server 262 // 503 is explicitly documented as a temporary state where the server
279 // is either overloaded or down for maintenance. 263 // is either overloaded or down for maintenance.
280 // 509 is the (non-standard but widely implemented) Bandwidth Limit Exceeded 264 // 509 is the (non-standard but widely implemented) Bandwidth Limit Exceeded
281 // status code, which might indicate DDoS. 265 // status code, which might indicate DDoS.
282 // 266 //
283 // We do not back off on 502 or 504, which are reported by gateways 267 // We do not back off on 502 or 504, which are reported by gateways
284 // (proxies) on timeouts or failures, because in many cases these requests 268 // (proxies) on timeouts or failures, because in many cases these requests
285 // have not made it to the destination server and so we do not actually 269 // have not made it to the destination server and so we do not actually
286 // know that it is down or busy. One degenerate case could be a proxy on 270 // know that it is down or busy. One degenerate case could be a proxy on
287 // localhost, where you are not actually connected to the network. 271 // localhost, where you are not actually connected to the network.
288 return (response_code == 500 || 272 return !(response_code == 500 || response_code == 503 ||
289 response_code == 503 || 273 response_code == 509);
290 response_code == 509);
291 } 274 }
292 275
293 base::TimeTicks URLRequestThrottlerEntry::ImplGetTimeNow() const { 276 base::TimeTicks URLRequestThrottlerEntry::ImplGetTimeNow() const {
294 return base::TimeTicks::Now(); 277 return base::TimeTicks::Now();
295 } 278 }
296 279
297 void URLRequestThrottlerEntry::HandleThrottlingHeader(
298 const std::string& header_value,
299 const std::string& host) {
300 if (header_value == kExponentialThrottlingDisableValue) {
301 DisableBackoffThrottling();
302 if (manager_)
303 manager_->AddToOptOutList(host);
304 }
305 }
306
307 const BackoffEntry* URLRequestThrottlerEntry::GetBackoffEntry() const { 280 const BackoffEntry* URLRequestThrottlerEntry::GetBackoffEntry() const {
308 return &backoff_entry_; 281 return &backoff_entry_;
309 } 282 }
310 283
311 BackoffEntry* URLRequestThrottlerEntry::GetBackoffEntry() { 284 BackoffEntry* URLRequestThrottlerEntry::GetBackoffEntry() {
312 return &backoff_entry_; 285 return &backoff_entry_;
313 } 286 }
314 287
315 // static 288 // static
316 bool URLRequestThrottlerEntry::ExplicitUserRequest(const int load_flags) { 289 bool URLRequestThrottlerEntry::ExplicitUserRequest(const int load_flags) {
317 return (load_flags & LOAD_MAYBE_USER_GESTURE) != 0; 290 return (load_flags & LOAD_MAYBE_USER_GESTURE) != 0;
318 } 291 }
319 292
320 } // namespace net 293 } // namespace net
OLDNEW
« no previous file with comments | « net/url_request/url_request_throttler_entry.h ('k') | net/url_request/url_request_throttler_entry_interface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698