Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: net/http/broken_alternative_services.h

Issue 2898983006: Fix and refactor HttpServerPropertiesImpl's alternative services brokenness expiration behavior (Closed)
Patch Set: Added checks for contents of expired_alt_svcs_ in BrokenAlternativeServicesTest Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ 5 #ifndef NET_HTTP_BROKEN_ALTERNATIVE_SERVICES_H_
6 #define NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ 6 #define NET_HTTP_BROKEN_ALTERNATIVE_SERVICES_H_
7 7
8 #include <stddef.h> 8 #include <list>
9 #include <stdint.h> 9 #include <unordered_map>
10 10
11 #include <deque>
12 #include <map>
13 #include <set>
14 #include <string>
15 #include <vector>
16
17 #include "base/macros.h"
18 #include "base/memory/weak_ptr.h" 11 #include "base/memory/weak_ptr.h"
19 #include "base/threading/non_thread_safe.h" 12 #include "base/timer/timer.h"
20 #include "base/values.h"
21 #include "net/base/host_port_pair.h"
22 #include "net/base/ip_address.h"
23 #include "net/base/linked_hash_map.h"
24 #include "net/base/net_export.h"
25 #include "net/http/http_server_properties.h" 13 #include "net/http/http_server_properties.h"
26 14
27 namespace base { 15 namespace base {
28 class ListValue; 16 class TickClock;
29 } 17 }
30 18
31 namespace net { 19 namespace net {
32 20
33 struct AlternativeServiceHash { 21 struct AlternativeServiceHash {
34 size_t operator()(const net::AlternativeService& entry) const { 22 size_t operator()(const net::AlternativeService& entry) const {
35 return entry.protocol ^ std::hash<std::string>()(entry.host) ^ entry.port; 23 return entry.protocol ^ std::hash<std::string>()(entry.host) ^ entry.port;
36 } 24 }
37 }; 25 };
38 26
39 // The implementation for setting/retrieving the HTTP server properties. 27 // This class tracks HTTP alternative services that have been marked as broken.
40 class NET_EXPORT HttpServerPropertiesImpl 28 // The brokenness of an alt-svc will expire after some time according to an
41 : public HttpServerProperties, 29 // exponential back-off formula: each time an alt-svc is marked broken, the
42 NON_EXPORTED_BASE(public base::NonThreadSafe) { 30 // expiration delay will be some constant multiple of its previous expiration
31 // delay. This prevents broken alt-svcs from being retried too often by the
32 // network stack.
33 class NET_EXPORT_PRIVATE BrokenAlternativeServices {
43 public: 34 public:
44 HttpServerPropertiesImpl(); 35 // Delegate to be used by owner so it can notified when the brokenness of an
45 ~HttpServerPropertiesImpl() override; 36 // AlternativeService expires.
37 class NET_EXPORT Delegate {
38 public:
39 // Will be called when a broken alternative service's expiration time is
40 // reached.
41 virtual void OnExpireBrokenAlternativeService(
42 const AlternativeService& expired_alternative_service) = 0;
43 virtual ~Delegate() {}
44 };
46 45
47 // Sets |spdy_servers_map_| with the servers (host/port) from 46 // |delegate| will be notified when a broken alternative service expires. It
48 // |spdy_servers| that either support SPDY or not. 47 // must not null.
49 void SetSpdyServers(std::vector<std::string>* spdy_servers, 48 // |clock| is used for setting expiration times and scheduling the
50 bool support_spdy); 49 // expiration of broken alternative services. It must not be null.
50 // |delegate| and |clock| are both unowned and must outlive this.
51 BrokenAlternativeServices(Delegate* delegate, base::TickClock* clock);
51 52
52 void SetAlternativeServiceServers( 53 BrokenAlternativeServices(const BrokenAlternativeServices&) = delete;
53 AlternativeServiceMap* alternate_protocol_servers); 54 void operator=(const BrokenAlternativeServices&) = delete;
54 55
55 void SetSupportsQuic(IPAddress* last_address); 56 ~BrokenAlternativeServices();
56 57
57 void SetServerNetworkStats(ServerNetworkStatsMap* server_network_stats_map); 58 // Marks |alternative_service| as broken until after some expiration delay
Ryan Hamilton 2017/05/27 13:28:16 nit: newlines before each of these method comments
wangyix1 2017/05/30 21:18:18 Discussed; will ignore comment.
59 // (determined by how many times it's been marked broken before). Being broken
60 // will cause IsAlternativeServiceBroken(alternative_service) to return true
61 // until the expiration time is reached, or until
62 // ConfirmAlternativeService(alternative_service) is called.
63 void MarkAlternativeServiceBroken(
64 const AlternativeService& alternative_service);
58 65
59 void SetQuicServerInfoMap(QuicServerInfoMap* quic_server_info_map); 66 // Marks |alternative_service| as recently broken. Being recently broken will
67 // cause WasAlternativeServiceRecentlyBroken(alternative_service) to return
68 // true until ConfirmAlternativeService(alternative_service) is called.
69 void MarkAlternativeServiceRecentlyBroken(
70 const AlternativeService& alternative_service);
60 71
61 // Get the list of servers (host/port) that support SPDY. The max_size is the 72 // Returns true if MarkAlternativeServiceBroken(alternative_service) was
62 // number of MRU servers that support SPDY that are to be returned. 73 // called, the expiration time has not been reached, and
63 void GetSpdyServerList(base::ListValue* spdy_server_list, 74 // ConfirmAlternativeService(alternative_service) has not been called
64 size_t max_size) const; 75 // afterwards.
76 bool IsAlternativeServiceBroken(
77 const AlternativeService& alternative_service) const;
65 78
66 // Returns flattened string representation of the |host_port_pair|. Used by 79 // Returns true MarkAlternativeServiceRecentlyBroken(alternative_service) was
Ryan Hamilton 2017/05/27 13:28:16 nit: I think "if" is missing from this comment?
wangyix1 2017/05/30 21:18:18 Done.
67 // unittests. 80 // called and ConfirmAlternativeService(alternative_service) has not been
68 static std::string GetFlattenedSpdyServer(const HostPortPair& host_port_pair); 81 // called afterwards.
82 bool WasAlternativeServiceRecentlyBroken(
83 const AlternativeService& alternative_service);
69 84
70 // Returns the canonical host suffix for |host|, or nullptr if none 85 // Marks |alternative_service| as not broken and not recently broken.
71 // exists. 86 void ConfirmAlternativeService(const AlternativeService& alternative_service);
72 const std::string* GetCanonicalSuffix(const std::string& host) const;
73
74 // -----------------------------
75 // HttpServerProperties methods:
76 // -----------------------------
77
78 void Clear() override;
79 bool SupportsRequestPriority(const url::SchemeHostPort& server) override;
80 bool GetSupportsSpdy(const url::SchemeHostPort& server) override;
81 void SetSupportsSpdy(const url::SchemeHostPort& server,
82 bool support_spdy) override;
83 bool RequiresHTTP11(const HostPortPair& server) override;
84 void SetHTTP11Required(const HostPortPair& server) override;
85 void MaybeForceHTTP11(const HostPortPair& server,
86 SSLConfig* ssl_config) override;
87 AlternativeServiceVector GetAlternativeServices(
88 const url::SchemeHostPort& origin) override;
89 bool SetAlternativeService(const url::SchemeHostPort& origin,
90 const AlternativeService& alternative_service,
91 base::Time expiration) override;
92 bool SetAlternativeServices(const url::SchemeHostPort& origin,
93 const AlternativeServiceInfoVector&
94 alternative_service_info_vector) override;
95 void MarkAlternativeServiceBroken(
96 const AlternativeService& alternative_service) override;
97 void MarkAlternativeServiceRecentlyBroken(
98 const AlternativeService& alternative_service) override;
99 bool IsAlternativeServiceBroken(
100 const AlternativeService& alternative_service) const override;
101 bool WasAlternativeServiceRecentlyBroken(
102 const AlternativeService& alternative_service) override;
103 void ConfirmAlternativeService(
104 const AlternativeService& alternative_service) override;
105 const AlternativeServiceMap& alternative_service_map() const override;
106 std::unique_ptr<base::Value> GetAlternativeServiceInfoAsValue()
107 const override;
108 bool GetSupportsQuic(IPAddress* last_address) const override;
109 void SetSupportsQuic(bool used_quic, const IPAddress& address) override;
110 void SetServerNetworkStats(const url::SchemeHostPort& server,
111 ServerNetworkStats stats) override;
112 void ClearServerNetworkStats(const url::SchemeHostPort& server) override;
113 const ServerNetworkStats* GetServerNetworkStats(
114 const url::SchemeHostPort& server) override;
115 const ServerNetworkStatsMap& server_network_stats_map() const override;
116 bool SetQuicServerInfo(const QuicServerId& server_id,
117 const std::string& server_info) override;
118 const std::string* GetQuicServerInfo(const QuicServerId& server_id) override;
119 const QuicServerInfoMap& quic_server_info_map() const override;
120 size_t max_server_configs_stored_in_properties() const override;
121 void SetMaxServerConfigsStoredInProperties(
122 size_t max_server_configs_stored_in_properties) override;
123 bool IsInitialized() const override;
124 87
125 private: 88 private:
89 // TODO (wangyix): modify HttpServerPropertiesImpl unit tests so this
90 // friendness is no longer required.
126 friend class HttpServerPropertiesImplPeer; 91 friend class HttpServerPropertiesImplPeer;
127 92
128 // |spdy_servers_map_| has flattened representation of servers 93 // A pair containing an AlternativeService and its expiration time.
129 // (scheme, host, port) that either support or not support SPDY protocol. 94 struct BrokenAltSvcExpireInfo {
130 typedef base::MRUCache<std::string, bool> SpdyServersMap; 95 BrokenAltSvcExpireInfo(const AlternativeService& alt_svc,
131 typedef std::map<url::SchemeHostPort, url::SchemeHostPort> CanonicalHostMap; 96 base::TimeTicks expire)
132 typedef std::vector<std::string> CanonicalSufficList; 97 : alternative_service(alt_svc), expiration(expire) {}
133 typedef std::set<HostPortPair> Http11ServerHostPortSet;
134 98
135 // Linked hash map from AlternativeService to expiration time. This container 99 AlternativeService alternative_service;
136 // is a queue with O(1) enqueue and dequeue, and a hash_map with O(1) lookup 100 base::TimeTicks expiration;
137 // at the same time. 101 };
138 typedef linked_hash_map<AlternativeService,
139 base::TimeTicks,
140 AlternativeServiceHash>
141 BrokenAlternativeServices;
142 102
143 // Return the iterator for |server|, or for its canonical host, or end. 103 typedef std::list<BrokenAltSvcExpireInfo> BrokenAlternativeServiceList;
144 AlternativeServiceMap::const_iterator GetAlternateProtocolIterator(
145 const url::SchemeHostPort& server);
146 104
147 // Return the canonical host for |server|, or end if none exists. 105 typedef std::unordered_map<AlternativeService,
148 CanonicalHostMap::const_iterator GetCanonicalHost( 106 BrokenAlternativeServiceList::iterator,
149 const url::SchemeHostPort& server) const; 107 AlternativeServiceHash>
108 BrokenAlternativeServiceMap;
150 109
151 // Remove the cononical host for |server|. 110 // Inserts |alternative_service| and its |expiration| time into
Ryan Hamilton 2017/05/27 13:28:16 nit: newlines before these comments. a bit more ve
wangyix1 2017/05/30 21:18:18 Discussed; will ignore comment.
152 void RemoveCanonicalHost(const url::SchemeHostPort& server); 111 // |broken_alternative_service_list_| and |broken_alternative_service_map_|.
112 // |it| is the position in |broken_alternative_service_list_| where it was
113 // inserted.
114 bool AddToBrokenAlternativeServiceListAndMap(
115 const AlternativeService& alternative_service,
116 base::TimeTicks expiration,
117 BrokenAlternativeServiceList::iterator* it);
118
153 void ExpireBrokenAlternateProtocolMappings(); 119 void ExpireBrokenAlternateProtocolMappings();
154 void ScheduleBrokenAlternateProtocolMappingsExpiration(); 120 void ScheduleBrokenAlternateProtocolMappingsExpiration();
155 121
156 SpdyServersMap spdy_servers_map_; 122 Delegate* delegate_; // Unowned
157 Http11ServerHostPortSet http11_servers_; 123 base::TickClock* clock_; // Unowned
158 124
159 AlternativeServiceMap alternative_service_map_; 125 // List of <broken alt svc, expiration time> pairs sorted by expiration time.
160 BrokenAlternativeServices broken_alternative_services_; 126 BrokenAlternativeServiceList broken_alternative_service_list_;
161 // Class invariant: Every alternative service in broken_alternative_services_ 127 // A map from broken alt-svcs to their iterator pointing to that alt-svc's
162 // must also be in recently_broken_alternative_services_. 128 // position in |broken_alternative_service_list_|.
129 BrokenAlternativeServiceMap broken_alternative_service_map_;
130
131 // Maps broken alternative services to how many times they've been marked
132 // broken.
163 RecentlyBrokenAlternativeServices recently_broken_alternative_services_; 133 RecentlyBrokenAlternativeServices recently_broken_alternative_services_;
164 134
165 IPAddress last_quic_address_; 135 // Used for scheduling the task that expires the brokenness of alternative
166 ServerNetworkStatsMap server_network_stats_map_; 136 // services.
167 // Contains a map of servers which could share the same alternate protocol. 137 base::OneShotTimer expiration_timer_;
168 // Map from a Canonical scheme/host/port (host is some postfix of host names)
169 // to an actual origin, which has a plausible alternate protocol mapping.
170 CanonicalHostMap canonical_host_to_origin_map_;
171 // Contains list of suffixes (for exmaple ".c.youtube.com",
172 // ".googlevideo.com", ".googleusercontent.com") of canonical hostnames.
173 CanonicalSufficList canonical_suffixes_;
174 138
175 QuicServerInfoMap quic_server_info_map_; 139 base::WeakPtrFactory<BrokenAlternativeServices> weak_ptr_factory_;
176 size_t max_server_configs_stored_in_properties_;
177
178 base::WeakPtrFactory<HttpServerPropertiesImpl> weak_ptr_factory_;
179
180 DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesImpl);
181 }; 140 };
182 141
183 } // namespace net 142 } // namespace net
184 143
185 #endif // NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ 144 #endif // NET_HTTP_BROKEN_ALTERNATIVE_SERVICES_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698