blob: 356d58226cb3b464b2cc5720cc2b1c6276018833 [file] [log] [blame]
xunjieli413a68782015-06-16 17:15:431// 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 EXTENSIONS_BROWSER_EXTENSION_THROTTLE_ENTRY_H_
6#define EXTENSIONS_BROWSER_EXTENSION_THROTTLE_ENTRY_H_
7
avic9cec102015-12-23 00:39:268#include <stdint.h>
9
xunjieli413a68782015-06-16 17:15:4310#include <queue>
11#include <string>
12
avic9cec102015-12-23 00:39:2613#include "base/macros.h"
xunjieli413a68782015-06-16 17:15:4314#include "base/time/time.h"
15#include "extensions/browser/extension_throttle_entry_interface.h"
16#include "net/base/backoff_entry.h"
mikecironef22f9812016-10-04 03:40:1917#include "net/log/net_log_with_source.h"
xunjieli413a68782015-06-16 17:15:4318
19namespace extensions {
20
21class ExtensionThrottleManager;
22
23// ExtensionThrottleEntry represents an entry of ExtensionThrottleManager.
24// It analyzes requests of a specific URL over some period of time, in order to
25// deduce the back-off time for every request.
26// The back-off algorithm consists of two parts. Firstly, exponential back-off
27// is used when receiving 5XX server errors or malformed response bodies.
28// The exponential back-off rule is enforced by URLRequestHttpJob. Any
29// request sent during the back-off period will be cancelled.
30// Secondly, a sliding window is used to count recent requests to a given
31// destination and provide guidance (to the application level only) on whether
32// too many requests have been sent and when a good time to send the next one
33// would be. This is never used to deny requests at the network level.
34class ExtensionThrottleEntry : public ExtensionThrottleEntryInterface {
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 // The manager object's lifetime must enclose the lifetime of this object.
62 ExtensionThrottleEntry(ExtensionThrottleManager* manager,
63 const std::string& url_id);
64
65 // Same as above, but exposes the option to ignore
66 // net::LOAD_MAYBE_USER_GESTURE flag of the request.
67 ExtensionThrottleEntry(ExtensionThrottleManager* manager,
68 const std::string& url_id,
69 bool ignore_user_gesture_load_flag_for_tests);
70
71 // The life span of instances created with this constructor is set to
72 // infinite, and the number of initial errors to ignore is set to 0.
73 // It is only used by unit tests.
74 ExtensionThrottleEntry(ExtensionThrottleManager* manager,
75 const std::string& url_id,
xunjielie484e2d62015-06-19 14:31:2176 const net::BackoffEntry::Policy* backoff_policy,
77 bool ignore_user_gesture_load_flag_for_tests);
xunjieli413a68782015-06-16 17:15:4378
79 // Used by the manager, returns true if the entry needs to be garbage
80 // collected.
81 bool IsEntryOutdated() const;
82
83 // Causes this entry to never reject requests due to back-off.
84 void DisableBackoffThrottling();
85
86 // Causes this entry to NULL its manager pointer.
87 void DetachManager();
88
89 // Implementation of ExtensionThrottleEntryInterface.
90 bool ShouldRejectRequest(const net::URLRequest& request) const override;
avic9cec102015-12-23 00:39:2691 int64_t ReserveSendingTimeForNextRequest(
xunjieli413a68782015-06-16 17:15:4392 const base::TimeTicks& earliest_time) override;
93 base::TimeTicks GetExponentialBackoffReleaseTime() const override;
94 void UpdateWithResponse(int status_code) override;
95 void ReceivedContentWasMalformed(int response_code) override;
96 const std::string& GetURLIdForDebugging() const override;
97
98 protected:
99 ~ExtensionThrottleEntry() override;
100
101 void Initialize();
102
103 // Returns true if the given response code is considered a success for
104 // throttling purposes.
105 bool IsConsideredSuccess(int response_code);
106
107 // Equivalent to TimeTicks::Now(), virtual to be mockable for testing purpose.
108 virtual base::TimeTicks ImplGetTimeNow() const;
109
110 // Retrieves the back-off entry object we're using. Used to enable a
111 // unit testing seam for dependency injection in tests.
112 virtual const net::BackoffEntry* GetBackoffEntry() const;
113 virtual net::BackoffEntry* GetBackoffEntry();
114
115 // Returns true if |load_flags| contains a flag that indicates an
116 // explicit request by the user to load the resource. We never
117 // throttle requests with such load flags.
118 static bool ExplicitUserRequest(const int load_flags);
119
120 // Used by tests.
121 base::TimeTicks sliding_window_release_time() const {
122 return sliding_window_release_time_;
123 }
124
125 // Used by tests.
126 void set_sliding_window_release_time(const base::TimeTicks& release_time) {
127 sliding_window_release_time_ = release_time;
128 }
129
130 // Valid and immutable after construction time.
131 net::BackoffEntry::Policy backoff_policy_;
132
133 private:
134 // Timestamp calculated by the sliding window algorithm for when we advise
135 // clients the next request should be made, at the earliest. Advisory only,
136 // not used to deny requests.
137 base::TimeTicks sliding_window_release_time_;
138
139 // A list of the recent send events. We use them to decide whether there are
140 // too many requests sent in sliding window.
141 std::queue<base::TimeTicks> send_log_;
142
143 const base::TimeDelta sliding_window_period_;
144 const int max_send_threshold_;
145
146 // True if DisableBackoffThrottling() has been called on this object.
147 bool is_backoff_disabled_;
148
149 // Access it through GetBackoffEntry() to allow a unit test seam.
150 net::BackoffEntry backoff_entry_;
151
152 // Weak back-reference to the manager object managing us.
153 ExtensionThrottleManager* manager_;
154
155 // Canonicalized URL string that this entry is for; used for logging only.
156 std::string url_id_;
157
tfarina428341112016-09-22 13:38:20158 net::NetLogWithSource net_log_;
xunjieli413a68782015-06-16 17:15:43159 bool ignore_user_gesture_load_flag_for_tests_;
160
161 DISALLOW_COPY_AND_ASSIGN(ExtensionThrottleEntry);
162};
163
164} // namespace extensions
165
166#endif // EXTENSIONS_BROWSER_EXTENSION_THROTTLE_ENTRY_H_