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_
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"
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.
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
{
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
;
68 int GetNumberOfEntriesForTests() const;
71 // An struct that holds relevant information obtained from a Backoff header.
73 Entry(const base::Time
& time1
, const base::Time
& time2
)
74 : throttled_time(time1
), release_time(time2
), used(false) {}
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|).
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
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
126 unsigned int new_entries_since_last_gc_
;
128 // Valid after construction.
129 GURL::Replacements url_id_replacements_
;
131 DISALLOW_COPY_AND_ASSIGN(URLRequestBackoffManager
);
136 #endif // NET_URL_REQUEST_URL_REQUEST_BACKOFF_MANAGER_H_