| OLD | NEW |
| 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 be notified when the brokenness of |
| 45 ~HttpServerPropertiesImpl() override; | 36 // an AlternativeService expires. |
| 37 class NET_EXPORT Delegate { |
| 38 public: |
| 39 // Called when a broken alternative service's expiration time is reached. |
| 40 virtual void OnExpireBrokenAlternativeService( |
| 41 const AlternativeService& expired_alternative_service) = 0; |
| 42 virtual ~Delegate() {} |
| 43 }; |
| 46 | 44 |
| 47 // Sets |spdy_servers_map_| with the servers (host/port) from | 45 // |delegate| will be notified when a broken alternative service expires. It |
| 48 // |spdy_servers| that either support SPDY or not. | 46 // must not be null. |
| 49 void SetSpdyServers(std::vector<std::string>* spdy_servers, | 47 // |clock| is used for setting expiration times and scheduling the |
| 50 bool support_spdy); | 48 // expiration of broken alternative services. It must not be null. |
| 49 // |delegate| and |clock| are both unowned and must outlive this. |
| 50 BrokenAlternativeServices(Delegate* delegate, base::TickClock* clock); |
| 51 | 51 |
| 52 void SetAlternativeServiceServers( | 52 BrokenAlternativeServices(const BrokenAlternativeServices&) = delete; |
| 53 AlternativeServiceMap* alternate_protocol_servers); | 53 void operator=(const BrokenAlternativeServices&) = delete; |
| 54 | 54 |
| 55 void SetSupportsQuic(IPAddress* last_address); | 55 ~BrokenAlternativeServices(); |
| 56 | 56 |
| 57 void SetServerNetworkStats(ServerNetworkStatsMap* server_network_stats_map); | 57 // Marks |alternative_service| as broken until after some expiration delay |
| 58 // (determined by how many times it's been marked broken before). Being broken |
| 59 // will cause IsAlternativeServiceBroken(alternative_service) to return true |
| 60 // until the expiration time is reached, or until |
| 61 // ConfirmAlternativeService(alternative_service) is called. |
| 62 void MarkAlternativeServiceBroken( |
| 63 const AlternativeService& alternative_service); |
| 58 | 64 |
| 59 void SetQuicServerInfoMap(QuicServerInfoMap* quic_server_info_map); | 65 // Marks |alternative_service| as recently broken. Being recently broken will |
| 66 // cause WasAlternativeServiceRecentlyBroken(alternative_service) to return |
| 67 // true until ConfirmAlternativeService(alternative_service) is called. |
| 68 void MarkAlternativeServiceRecentlyBroken( |
| 69 const AlternativeService& alternative_service); |
| 60 | 70 |
| 61 // Get the list of servers (host/port) that support SPDY. The max_size is the | 71 // Returns true if MarkAlternativeServiceBroken(alternative_service) has been |
| 62 // number of MRU servers that support SPDY that are to be returned. | 72 // called, the expiration time has not been reached, and |
| 63 void GetSpdyServerList(base::ListValue* spdy_server_list, | 73 // ConfirmAlternativeService(alternative_service) has not been called |
| 64 size_t max_size) const; | 74 // afterwards. |
| 75 bool IsAlternativeServiceBroken( |
| 76 const AlternativeService& alternative_service) const; |
| 65 | 77 |
| 66 // Returns flattened string representation of the |host_port_pair|. Used by | 78 // Returns true if MarkAlternativeServiceRecentlyBroken(alternative_service) |
| 67 // unittests. | 79 // or MarkAlternativeServiceBroken(alternative_service) has been called and |
| 68 static std::string GetFlattenedSpdyServer(const HostPortPair& host_port_pair); | 80 // ConfirmAlternativeService(alternative_service) has not been called |
| 81 // afterwards (even if brokenness of |alternative_service| has expired). |
| 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 AlternativeServiceInfoVector GetAlternativeServiceInfos( | |
| 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 a broken AlternativeService and the expiration time of |
| 129 // (scheme, host, port) that either support or not support SPDY protocol. | 94 // its brokenness. |
| 130 typedef base::MRUCache<std::string, bool> SpdyServersMap; | 95 struct BrokenAltSvcExpireInfo { |
| 131 typedef std::map<url::SchemeHostPort, url::SchemeHostPort> CanonicalHostMap; | 96 BrokenAltSvcExpireInfo(const AlternativeService& alt_svc, |
| 132 typedef std::vector<std::string> CanonicalSufficList; | 97 base::TimeTicks expire) |
| 133 typedef std::set<HostPortPair> Http11ServerHostPortSet; | 98 : alternative_service(alt_svc), expiration(expire) {} |
| 134 | 99 |
| 135 // Linked hash map from AlternativeService to expiration time. This container | 100 AlternativeService alternative_service; |
| 136 // is a queue with O(1) enqueue and dequeue, and a hash_map with O(1) lookup | 101 base::TimeTicks expiration; |
| 137 // at the same time. | 102 }; |
| 138 typedef linked_hash_map<AlternativeService, | |
| 139 base::TimeTicks, | |
| 140 AlternativeServiceHash> | |
| 141 BrokenAlternativeServices; | |
| 142 | 103 |
| 143 // Return the iterator for |server|, or for its canonical host, or end. | 104 typedef std::list<BrokenAltSvcExpireInfo> BrokenAlternativeServiceList; |
| 144 AlternativeServiceMap::const_iterator GetAlternateProtocolIterator( | |
| 145 const url::SchemeHostPort& server); | |
| 146 | 105 |
| 147 // Return the canonical host for |server|, or end if none exists. | 106 typedef std::unordered_map<AlternativeService, |
| 148 CanonicalHostMap::const_iterator GetCanonicalHost( | 107 BrokenAlternativeServiceList::iterator, |
| 149 const url::SchemeHostPort& server) const; | 108 AlternativeServiceHash> |
| 109 BrokenAlternativeServiceMap; |
| 150 | 110 |
| 151 // Remove the cononical host for |server|. | 111 // Inserts |alternative_service| and its |expiration| time into |
| 152 void RemoveCanonicalHost(const url::SchemeHostPort& server); | 112 // |broken_alternative_service_list_| and |broken_alternative_service_map_|. |
| 113 // |it| is the position in |broken_alternative_service_list_| where it was |
| 114 // inserted. |
| 115 bool AddToBrokenAlternativeServiceListAndMap( |
| 116 const AlternativeService& alternative_service, |
| 117 base::TimeTicks expiration, |
| 118 BrokenAlternativeServiceList::iterator* it); |
| 119 |
| 153 void ExpireBrokenAlternateProtocolMappings(); | 120 void ExpireBrokenAlternateProtocolMappings(); |
| 154 void ScheduleBrokenAlternateProtocolMappingsExpiration(); | 121 void ScheduleBrokenAlternateProtocolMappingsExpiration(); |
| 155 | 122 |
| 156 SpdyServersMap spdy_servers_map_; | 123 Delegate* delegate_; // Unowned |
| 157 Http11ServerHostPortSet http11_servers_; | 124 base::TickClock* clock_; // Unowned |
| 158 | 125 |
| 159 AlternativeServiceMap alternative_service_map_; | 126 // List of <broken alt svc, expiration time> pairs sorted by expiration time. |
| 160 BrokenAlternativeServices broken_alternative_services_; | 127 BrokenAlternativeServiceList broken_alternative_service_list_; |
| 161 // Class invariant: Every alternative service in broken_alternative_services_ | 128 // A map from broken alt-svcs to their iterator pointing to that alt-svc's |
| 162 // must also be in recently_broken_alternative_services_. | 129 // position in |broken_alternative_service_list_|. |
| 130 BrokenAlternativeServiceMap broken_alternative_service_map_; |
| 131 |
| 132 // Maps broken alternative services to how many times they've been marked |
| 133 // broken. |
| 163 RecentlyBrokenAlternativeServices recently_broken_alternative_services_; | 134 RecentlyBrokenAlternativeServices recently_broken_alternative_services_; |
| 164 | 135 |
| 165 IPAddress last_quic_address_; | 136 // Used for scheduling the task that expires the brokenness of alternative |
| 166 ServerNetworkStatsMap server_network_stats_map_; | 137 // services. |
| 167 // Contains a map of servers which could share the same alternate protocol. | 138 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 | 139 |
| 175 QuicServerInfoMap quic_server_info_map_; | 140 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 }; | 141 }; |
| 182 | 142 |
| 183 } // namespace net | 143 } // namespace net |
| 184 | 144 |
| 185 #endif // NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ | 145 #endif // NET_HTTP_BROKEN_ALTERNATIVE_SERVICES_H_ |
| OLD | NEW |