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