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_HTTP_ALTERNATIVE_SERVICE_H_ 6 #define NET_HTTP_ALTERNATIVE_SERVICE_H_ 7 8 #include <stdint.h> 9 10 #include <algorithm> 11 #include <ostream> 12 #include <string> 13 #include <string_view> 14 15 #include "base/time/time.h" 16 #include "net/base/host_port_pair.h" 17 #include "net/base/net_export.h" 18 #include "net/http/alternate_protocol_usage.h" 19 #include "net/quic/quic_http_utils.h" 20 #include "net/socket/next_proto.h" 21 #include "net/third_party/quiche/src/quiche/http2/core/spdy_protocol.h" 22 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h" 23 24 namespace net { 25 26 // Log a histogram to reflect |usage|. 27 NET_EXPORT void HistogramAlternateProtocolUsage(AlternateProtocolUsage usage, 28 bool is_google_host); 29 30 enum BrokenAlternateProtocolLocation { 31 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB = 0, 32 BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_SESSION_POOL = 1, 33 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB_ALT = 2, 34 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB_MAIN = 3, 35 BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_HTTP_STREAM = 4, 36 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_NETWORK_TRANSACTION = 5, 37 BROKEN_ALTERNATE_PROTOCOL_LOCATION_MAX, 38 }; 39 40 // Log a histogram to reflect |location|. 41 NET_EXPORT void HistogramBrokenAlternateProtocolLocation( 42 BrokenAlternateProtocolLocation location); 43 44 // Returns true if |protocol| is a valid protocol. 45 NET_EXPORT bool IsAlternateProtocolValid(NextProto protocol); 46 47 // Returns true if |protocol| is enabled, based on |is_http2_enabled| 48 // and |is_quic_enabled|.. 49 NET_EXPORT bool IsProtocolEnabled(NextProto protocol, 50 bool is_http2_enabled, 51 bool is_quic_enabled); 52 53 // (protocol, host, port) triple as defined in 54 // https://tools.ietf.org/id/draft-ietf-httpbis-alt-svc-06.html 55 struct NET_EXPORT AlternativeService { 56 AlternativeService() = default; 57 58 AlternativeService(NextProto protocol, std::string_view host, uint16_t port); 59 60 AlternativeService(NextProto protocol, const HostPortPair& host_port_pair); 61 62 AlternativeService(const AlternativeService& alternative_service); 63 AlternativeService(AlternativeService&& alternative_service) noexcept; 64 65 AlternativeService& operator=(AlternativeService&& alternative_service); 66 AlternativeService& operator=(const AlternativeService& alternative_service); 67 68 HostPortPair GetHostPortPair() const; 69 70 bool operator==(const AlternativeService& other) const = default; 71 72 std::strong_ordering operator<=>(const AlternativeService& other) const; 73 74 // Output format: "protocol host:port", e.g. "h2 www.google.com:1234". 75 std::string ToString() const; 76 77 NextProto protocol = kProtoUnknown; 78 std::string host; 79 uint16_t port; 80 }; 81 82 NET_EXPORT_PRIVATE std::ostream& operator<<( 83 std::ostream& os, 84 const AlternativeService& alternative_service); 85 86 class NET_EXPORT_PRIVATE AlternativeServiceInfo { 87 public: 88 static AlternativeServiceInfo CreateHttp2AlternativeServiceInfo( 89 const AlternativeService& alternative_service, 90 base::Time expiration); 91 92 static AlternativeServiceInfo CreateQuicAlternativeServiceInfo( 93 const AlternativeService& alternative_service, 94 base::Time expiration, 95 const quic::ParsedQuicVersionVector& advertised_versions); 96 97 AlternativeServiceInfo(); 98 99 AlternativeServiceInfo( 100 const AlternativeServiceInfo& alternative_service_info); 101 AlternativeServiceInfo( 102 AlternativeServiceInfo&& alternative_service_info) noexcept; 103 104 AlternativeServiceInfo& operator=( 105 const AlternativeServiceInfo& alternative_service_info); 106 AlternativeServiceInfo& operator=( 107 AlternativeServiceInfo&& alternative_service_info); 108 109 ~AlternativeServiceInfo(); 110 111 bool operator==(const AlternativeServiceInfo& other) const; 112 113 std::string ToString() const; 114 set_alternative_service(const AlternativeService & alternative_service)115 void set_alternative_service(const AlternativeService& alternative_service) { 116 alternative_service_ = alternative_service; 117 } 118 set_protocol(const NextProto & protocol)119 void set_protocol(const NextProto& protocol) { 120 alternative_service_.protocol = protocol; 121 } 122 set_host(const std::string & host)123 void set_host(const std::string& host) { alternative_service_.host = host; } 124 set_port(uint16_t port)125 void set_port(uint16_t port) { alternative_service_.port = port; } 126 set_expiration(const base::Time & expiration)127 void set_expiration(const base::Time& expiration) { 128 expiration_ = expiration; 129 } 130 131 // Sets the advertised versions for QUIC alternative services to a sorted copy 132 // of `advertised_versions`. 133 void SetAdvertisedVersions( 134 const quic::ParsedQuicVersionVector& advertised_versions); 135 alternative_service()136 const AlternativeService& alternative_service() const { 137 return alternative_service_; 138 } 139 protocol()140 NextProto protocol() const { return alternative_service_.protocol; } 141 GetHostPortPair()142 HostPortPair GetHostPortPair() const { 143 return alternative_service_.GetHostPortPair(); 144 } 145 expiration()146 base::Time expiration() const { return expiration_; } 147 advertised_versions()148 const quic::ParsedQuicVersionVector& advertised_versions() const { 149 return advertised_versions_; 150 } 151 152 private: 153 AlternativeServiceInfo( 154 const AlternativeService& alternative_service, 155 base::Time expiration, 156 const quic::ParsedQuicVersionVector& advertised_versions); 157 158 AlternativeService alternative_service_; 159 base::Time expiration_; 160 161 // Lists all the QUIC versions that are advertised by the server and supported 162 // by Chrome. If empty, defaults to versions used by the current instance of 163 // the netstack. This list is sorted according to the server's preference. 164 quic::ParsedQuicVersionVector advertised_versions_; 165 }; 166 167 using AlternativeServiceInfoVector = std::vector<AlternativeServiceInfo>; 168 169 NET_EXPORT_PRIVATE AlternativeServiceInfoVector ProcessAlternativeServices( 170 const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector& 171 alternative_service_vector, 172 bool is_http2_enabled, 173 bool is_quic_enabled, 174 const quic::ParsedQuicVersionVector& supported_quic_versions); 175 176 } // namespace net 177 178 #endif // NET_HTTP_ALTERNATIVE_SERVICE_H_ 179