• 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_MANAGER_H_
6 #define NET_URL_REQUEST_URL_REQUEST_THROTTLER_MANAGER_H_
7 
8 #include <map>
9 #include <set>
10 #include <string>
11 
12 #include "base/memory/scoped_refptr.h"
13 #include "base/threading/platform_thread.h"
14 #include "base/threading/thread_checker.h"
15 #include "net/base/net_export.h"
16 #include "net/base/network_change_notifier.h"
17 #include "net/url_request/url_request_throttler_entry.h"
18 #include "url/gurl.h"
19 
20 namespace net {
21 
22 class NetLog;
23 class NetLogWithSource;
24 
25 // Class that registers URL request throttler entries for URLs being accessed
26 // in order to supervise traffic. URL requests for HTTP contents should
27 // register their URLs in this manager on each request.
28 //
29 // URLRequestThrottlerManager maintains a map of URL IDs to URL request
30 // throttler entries. It creates URL request throttler entries when new URLs
31 // are registered, and does garbage collection from time to time in order to
32 // clean out outdated entries. URL ID consists of lowercased scheme, host, port
33 // and path. All URLs converted to the same ID will share the same entry.
34 class NET_EXPORT_PRIVATE URLRequestThrottlerManager
35     : public NetworkChangeNotifier::IPAddressObserver,
36       public NetworkChangeNotifier::ConnectionTypeObserver {
37  public:
38   URLRequestThrottlerManager();
39 
40   URLRequestThrottlerManager(const URLRequestThrottlerManager&) = delete;
41   URLRequestThrottlerManager& operator=(const URLRequestThrottlerManager&) =
42       delete;
43 
44   ~URLRequestThrottlerManager() override;
45 
46   // Must be called for every request, returns the URL request throttler entry
47   // associated with the URL. The caller must inform this entry of some events.
48   // Please refer to url_request_throttler_entry_interface.h for further
49   // informations.
50   scoped_refptr<URLRequestThrottlerEntryInterface> RegisterRequestUrl(
51       const GURL& url);
52 
53   // Registers a new entry in this service and overrides the existing entry (if
54   // any) for the URL. The service will hold a reference to the entry.
55   // It is only used by unit tests.
56   void OverrideEntryForTests(const GURL& url,
57                              scoped_refptr<URLRequestThrottlerEntry> entry);
58 
59   // Explicitly erases an entry.
60   // This is useful to remove those entries which have got infinite lifetime and
61   // thus won't be garbage collected.
62   // It is only used by unit tests.
63   void EraseEntryForTests(const GURL& url);
64 
65   // Whether throttling is enabled or not.
66   void set_enforce_throttling(bool enforce);
67   bool enforce_throttling();
68 
69   // Sets the NetLog instance to use.
70   void set_net_log(NetLog* net_log);
71   NetLog* net_log() const;
72 
73   // IPAddressObserver interface.
74   void OnIPAddressChanged() override;
75 
76   // ConnectionTypeObserver interface.
77   void OnConnectionTypeChanged(
78       NetworkChangeNotifier::ConnectionType type) override;
79 
80   // Method that allows us to transform a URL into an ID that can be used in our
81   // map. Resulting IDs will be lowercase and consist of the scheme, host, port
82   // and path (without query string, fragment, etc.).
83   // If the URL is invalid, the invalid spec will be returned, without any
84   // transformation.
85   std::string GetIdFromUrl(const GURL& url) const;
86 
87   // Method that ensures the map gets cleaned from time to time. The period at
88   // which garbage collecting happens is adjustable with the
89   // kRequestBetweenCollecting constant.
90   void GarbageCollectEntriesIfNecessary();
91 
92   // Method that does the actual work of garbage collecting.
93   void GarbageCollectEntries();
94 
95   // When we switch from online to offline or change IP addresses, we
96   // clear all back-off history. This is a precaution in case the change in
97   // online state now lets us communicate without error with servers that
98   // we were previously getting 500 or 503 responses from (perhaps the
99   // responses are from a badly-written proxy that should have returned a
100   // 502 or 504 because it's upstream connection was down or it had no route
101   // to the server).
102   void OnNetworkChange();
103 
104   // Used by tests.
GetNumberOfEntriesForTests()105   int GetNumberOfEntriesForTests() const {
106     return static_cast<int>(url_entries_.size());
107   }
108 
109  private:
110   // From each URL we generate an ID composed of the scheme, host, port and path
111   // that allows us to uniquely map an entry to it.
112   typedef std::map<std::string, scoped_refptr<URLRequestThrottlerEntry> >
113       UrlEntryMap;
114 
115   // Maximum number of entries that we are willing to collect in our map.
116   static const unsigned int kMaximumNumberOfEntries;
117   // Number of requests that will be made between garbage collection.
118   static const unsigned int kRequestsBetweenCollecting;
119 
120   // Map that contains a list of URL ID and their matching
121   // URLRequestThrottlerEntry.
122   UrlEntryMap url_entries_;
123 
124   // This keeps track of how many requests have been made. Used with
125   // GarbageCollectEntries.
126   unsigned int requests_since_last_gc_ = 0;
127 
128   // Valid after construction.
129   GURL::Replacements url_id_replacements_;
130 
131   // Certain tests do not obey the net component's threading policy, so we
132   // keep track of whether we're being used by tests, and turn off certain
133   // checks.
134   //
135   // TODO(joi): See if we can fix the offending unit tests and remove this
136   // workaround.
137   bool enable_thread_checks_;
138 
139   // Initially false, switches to true once we have logged because of back-off
140   // being disabled for localhost.
141   bool logged_for_localhost_disabled_ = false;
142 
143   // NetLog to use, if configured.
144   NetLogWithSource net_log_;
145 
146   // Valid once we've registered for network notifications.
147   base::PlatformThreadId registered_from_thread_ = base::kInvalidThreadId;
148 
149   THREAD_CHECKER(thread_checker_);
150 };
151 
152 }  // namespace net
153 
154 #endif  // NET_URL_REQUEST_URL_REQUEST_THROTTLER_MANAGER_H_
155