Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / net / url_request / url_request_backoff_manager.h
blob232ebdc02b664f1e95057500a022f8039999f3d4
1 // Copyright 2015 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.
5 #ifndef NET_URL_REQUEST_URL_REQUEST_BACKOFF_MANAGER_H_
6 #define NET_URL_REQUEST_URL_REQUEST_BACKOFF_MANAGER_H_
8 #include <map>
9 #include <string>
11 #include "base/basictypes.h"
12 #include "base/threading/non_thread_safe.h"
13 #include "base/time/time.h"
14 #include "net/base/net_export.h"
15 #include "net/base/network_change_notifier.h"
16 #include "url/gurl.h"
18 namespace net {
20 class HttpResponseHeaders;
22 // Class that manages information on Backoff headers. URL requests for HTTPS
23 // contents should update their URLs in this manager on each response.
25 // Design doc:
26 // https://docs.google.com/document/d/1aAxwXK7Vw3VigFd6MmrItbAIgMdKAf-XxXXbhWXdID0/edit?usp=sharing
28 // URLRequestBackoffManager maintains a map of URL IDs to
29 // URLRequestBackoffManager::Entry. It creates an entry when a request receives
30 // a Backoff header, and does garbage collection from time to time in order to
31 // clean out outdated entries. URL ID consists of lowercased scheme, host, port
32 // and path. A newer request with the same ID will override the old entry.
34 // Note that the class does not implement logic to retry a request at random
35 // with uniform distribution.
36 // TODO(xunjieli): Expose release time so that the caller can retry accordingly.
37 class NET_EXPORT URLRequestBackoffManager
38 : NON_EXPORTED_BASE(public base::NonThreadSafe),
39 public NetworkChangeNotifier::IPAddressObserver,
40 public NetworkChangeNotifier::ConnectionTypeObserver {
41 public:
42 // Minimum number of seconds that a Backoff header can specify.
43 static const uint16 kMinimumBackoffInSeconds;
44 // Maximum number of seconds that a Backoff header can specify.
45 static const uint16 kMaximumBackoffInSeconds;
46 // Number of throttled requests that will be made between garbage collection.
47 static const uint16 kNewEntriesBetweenCollecting;
49 URLRequestBackoffManager();
50 ~URLRequestBackoffManager() override;
52 // Updates internal states with a response.
53 void UpdateWithResponse(const GURL& url,
54 HttpResponseHeaders* headers,
55 const base::Time& response_time);
57 // Returns whether the request should be rejected because of a Backoff header.
58 bool ShouldRejectRequest(const GURL& url, const base::Time& request_time);
60 // IPAddressObserver implementation.
61 void OnIPAddressChanged() override;
63 // ConnectionTypeObserver implementation.
64 void OnConnectionTypeChanged(
65 NetworkChangeNotifier::ConnectionType type) override;
67 // Used by tests.
68 int GetNumberOfEntriesForTests() const;
70 private:
71 // An struct that holds relevant information obtained from a Backoff header.
72 struct Entry {
73 Entry(const base::Time& time1, const base::Time& time2)
74 : throttled_time(time1), release_time(time2), used(false) {}
75 ~Entry() {}
77 // Returns whether this entry is outdated.
78 bool IsOutDated() { return base::Time::Now() >= release_time; }
80 // Before this time, requests with the same URL ID should be throttled.
81 const base::Time throttled_time;
83 // Only one request with the same URL ID should be allowed in
84 // [|throttled_time|, |release_time|).
85 // After this time, all requests with the same URL ID are allowed.
86 const base::Time release_time;
88 // Indicates whether a request has been made in
89 // [|throttled_time|, |release_time|).
90 bool used;
93 // From each URL, generate an ID composed of the scheme, host, port and path
94 // that allows unique mapping an entry to it.
95 typedef std::map<std::string, Entry*> UrlEntryMap;
97 // Method that ensures the map gets cleaned from time to time. The period at
98 // which garbage collecting happens is adjustable with the
99 // kNewEntriesBetweenCollecting constant.
100 void GarbageCollectEntriesIfNecessary();
102 // Return true if there is a well-formed Backoff header key-value pair,
103 // and write the Backoff header value in |result|. Return false if no header
104 // is found or the value is invalid (i.e. less than kMinimumBackoffInSeconds
105 // or greater than kMaximumBackoffInSeconds).
106 bool GetBackoffTime(HttpResponseHeaders* headers,
107 base::TimeDelta* result) const;
109 // Method that transforms a URL into an ID that can be used in the map.
110 // Resulting IDs will be lowercase and consist of the scheme, host, port
111 // and path (without query string, fragment, etc.).
112 // If the URL is invalid, the invalid spec will be returned, without any
113 // transformation.
114 std::string GetIdFromUrl(const GURL& url) const;
116 // When switching from online to offline or change IP addresses,
117 // clear all back-off history. This is a precaution in case the change in
118 // online state now allows communicating without errors with servers that
119 // were previously returning Backoff headers.
120 void OnNetworkChange();
122 UrlEntryMap url_entries_;
124 // Keeps track of how many new entries are created since last garbage
125 // collection.
126 unsigned int new_entries_since_last_gc_;
128 // Valid after construction.
129 GURL::Replacements url_id_replacements_;
131 DISALLOW_COPY_AND_ASSIGN(URLRequestBackoffManager);
134 } // namespace net
136 #endif // NET_URL_REQUEST_URL_REQUEST_BACKOFF_MANAGER_H_