xref: /aosp_15_r20/external/cronet/net/http/alternative_service.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef NET_HTTP_ALTERNATIVE_SERVICE_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_HTTP_ALTERNATIVE_SERVICE_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <algorithm>
11*6777b538SAndroid Build Coastguard Worker #include <ostream>
12*6777b538SAndroid Build Coastguard Worker #include <string>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/base/host_port_pair.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
17*6777b538SAndroid Build Coastguard Worker #include "net/http/alternate_protocol_usage.h"
18*6777b538SAndroid Build Coastguard Worker #include "net/quic/quic_http_utils.h"
19*6777b538SAndroid Build Coastguard Worker #include "net/socket/next_proto.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
21*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker namespace net {
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker // Log a histogram to reflect |usage|.
26*6777b538SAndroid Build Coastguard Worker NET_EXPORT void HistogramAlternateProtocolUsage(AlternateProtocolUsage usage,
27*6777b538SAndroid Build Coastguard Worker                                                 bool is_google_host);
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker enum BrokenAlternateProtocolLocation {
30*6777b538SAndroid Build Coastguard Worker   BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB = 0,
31*6777b538SAndroid Build Coastguard Worker   BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_SESSION_POOL = 1,
32*6777b538SAndroid Build Coastguard Worker   BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB_ALT = 2,
33*6777b538SAndroid Build Coastguard Worker   BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB_MAIN = 3,
34*6777b538SAndroid Build Coastguard Worker   BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_HTTP_STREAM = 4,
35*6777b538SAndroid Build Coastguard Worker   BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_NETWORK_TRANSACTION = 5,
36*6777b538SAndroid Build Coastguard Worker   BROKEN_ALTERNATE_PROTOCOL_LOCATION_MAX,
37*6777b538SAndroid Build Coastguard Worker };
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker // Log a histogram to reflect |location|.
40*6777b538SAndroid Build Coastguard Worker NET_EXPORT void HistogramBrokenAlternateProtocolLocation(
41*6777b538SAndroid Build Coastguard Worker     BrokenAlternateProtocolLocation location);
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker // Returns true if |protocol| is a valid protocol.
44*6777b538SAndroid Build Coastguard Worker NET_EXPORT bool IsAlternateProtocolValid(NextProto protocol);
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker // Returns true if |protocol| is enabled, based on |is_http2_enabled|
47*6777b538SAndroid Build Coastguard Worker // and |is_quic_enabled|..
48*6777b538SAndroid Build Coastguard Worker NET_EXPORT bool IsProtocolEnabled(NextProto protocol,
49*6777b538SAndroid Build Coastguard Worker                                   bool is_http2_enabled,
50*6777b538SAndroid Build Coastguard Worker                                   bool is_quic_enabled);
51*6777b538SAndroid Build Coastguard Worker 
52*6777b538SAndroid Build Coastguard Worker // (protocol, host, port) triple as defined in
53*6777b538SAndroid Build Coastguard Worker // https://tools.ietf.org/id/draft-ietf-httpbis-alt-svc-06.html
54*6777b538SAndroid Build Coastguard Worker //
55*6777b538SAndroid Build Coastguard Worker // TODO(mmenke):  Seems like most of this stuff should be de-inlined.
56*6777b538SAndroid Build Coastguard Worker struct NET_EXPORT AlternativeService {
AlternativeServiceAlternativeService57*6777b538SAndroid Build Coastguard Worker   AlternativeService() : protocol(kProtoUnknown), host(), port(0) {}
58*6777b538SAndroid Build Coastguard Worker 
AlternativeServiceAlternativeService59*6777b538SAndroid Build Coastguard Worker   AlternativeService(NextProto protocol, const std::string& host, uint16_t port)
60*6777b538SAndroid Build Coastguard Worker       : protocol(protocol), host(host), port(port) {}
61*6777b538SAndroid Build Coastguard Worker 
AlternativeServiceAlternativeService62*6777b538SAndroid Build Coastguard Worker   AlternativeService(NextProto protocol, const HostPortPair& host_port_pair)
63*6777b538SAndroid Build Coastguard Worker       : protocol(protocol),
64*6777b538SAndroid Build Coastguard Worker         host(host_port_pair.host()),
65*6777b538SAndroid Build Coastguard Worker         port(host_port_pair.port()) {}
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker   AlternativeService(const AlternativeService& alternative_service) = default;
68*6777b538SAndroid Build Coastguard Worker   AlternativeService& operator=(const AlternativeService& alternative_service) =
69*6777b538SAndroid Build Coastguard Worker       default;
70*6777b538SAndroid Build Coastguard Worker 
host_port_pairAlternativeService71*6777b538SAndroid Build Coastguard Worker   HostPortPair host_port_pair() const { return HostPortPair(host, port); }
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker   bool operator==(const AlternativeService& other) const {
74*6777b538SAndroid Build Coastguard Worker     return protocol == other.protocol && host == other.host &&
75*6777b538SAndroid Build Coastguard Worker            port == other.port;
76*6777b538SAndroid Build Coastguard Worker   }
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker   bool operator!=(const AlternativeService& other) const {
79*6777b538SAndroid Build Coastguard Worker     return !this->operator==(other);
80*6777b538SAndroid Build Coastguard Worker   }
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker   bool operator<(const AlternativeService& other) const {
83*6777b538SAndroid Build Coastguard Worker     return std::tie(protocol, host, port) <
84*6777b538SAndroid Build Coastguard Worker            std::tie(other.protocol, other.host, other.port);
85*6777b538SAndroid Build Coastguard Worker   }
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker   // Output format: "protocol host:port", e.g. "h2 www.google.com:1234".
88*6777b538SAndroid Build Coastguard Worker   std::string ToString() const;
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   NextProto protocol;
91*6777b538SAndroid Build Coastguard Worker   std::string host;
92*6777b538SAndroid Build Coastguard Worker   uint16_t port;
93*6777b538SAndroid Build Coastguard Worker };
94*6777b538SAndroid Build Coastguard Worker 
95*6777b538SAndroid Build Coastguard Worker NET_EXPORT_PRIVATE std::ostream& operator<<(
96*6777b538SAndroid Build Coastguard Worker     std::ostream& os,
97*6777b538SAndroid Build Coastguard Worker     const AlternativeService& alternative_service);
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE AlternativeServiceInfo {
100*6777b538SAndroid Build Coastguard Worker  public:
101*6777b538SAndroid Build Coastguard Worker   static AlternativeServiceInfo CreateHttp2AlternativeServiceInfo(
102*6777b538SAndroid Build Coastguard Worker       const AlternativeService& alternative_service,
103*6777b538SAndroid Build Coastguard Worker       base::Time expiration);
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker   static AlternativeServiceInfo CreateQuicAlternativeServiceInfo(
106*6777b538SAndroid Build Coastguard Worker       const AlternativeService& alternative_service,
107*6777b538SAndroid Build Coastguard Worker       base::Time expiration,
108*6777b538SAndroid Build Coastguard Worker       const quic::ParsedQuicVersionVector& advertised_versions);
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker   AlternativeServiceInfo();
111*6777b538SAndroid Build Coastguard Worker   ~AlternativeServiceInfo();
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker   AlternativeServiceInfo(
114*6777b538SAndroid Build Coastguard Worker       const AlternativeServiceInfo& alternative_service_info);
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker   AlternativeServiceInfo& operator=(
117*6777b538SAndroid Build Coastguard Worker       const AlternativeServiceInfo& alternative_service_info);
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   bool operator==(const AlternativeServiceInfo& other) const {
120*6777b538SAndroid Build Coastguard Worker     return alternative_service_ == other.alternative_service() &&
121*6777b538SAndroid Build Coastguard Worker            expiration_ == other.expiration() &&
122*6777b538SAndroid Build Coastguard Worker            advertised_versions_ == other.advertised_versions();
123*6777b538SAndroid Build Coastguard Worker   }
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker   bool operator!=(const AlternativeServiceInfo& other) const {
126*6777b538SAndroid Build Coastguard Worker     return !this->operator==(other);
127*6777b538SAndroid Build Coastguard Worker   }
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker   std::string ToString() const;
130*6777b538SAndroid Build Coastguard Worker 
set_alternative_service(const AlternativeService & alternative_service)131*6777b538SAndroid Build Coastguard Worker   void set_alternative_service(const AlternativeService& alternative_service) {
132*6777b538SAndroid Build Coastguard Worker     alternative_service_ = alternative_service;
133*6777b538SAndroid Build Coastguard Worker   }
134*6777b538SAndroid Build Coastguard Worker 
set_protocol(const NextProto & protocol)135*6777b538SAndroid Build Coastguard Worker   void set_protocol(const NextProto& protocol) {
136*6777b538SAndroid Build Coastguard Worker     alternative_service_.protocol = protocol;
137*6777b538SAndroid Build Coastguard Worker   }
138*6777b538SAndroid Build Coastguard Worker 
set_host(const std::string & host)139*6777b538SAndroid Build Coastguard Worker   void set_host(const std::string& host) { alternative_service_.host = host; }
140*6777b538SAndroid Build Coastguard Worker 
set_port(uint16_t port)141*6777b538SAndroid Build Coastguard Worker   void set_port(uint16_t port) { alternative_service_.port = port; }
142*6777b538SAndroid Build Coastguard Worker 
set_expiration(const base::Time & expiration)143*6777b538SAndroid Build Coastguard Worker   void set_expiration(const base::Time& expiration) {
144*6777b538SAndroid Build Coastguard Worker     expiration_ = expiration;
145*6777b538SAndroid Build Coastguard Worker   }
146*6777b538SAndroid Build Coastguard Worker 
set_advertised_versions(const quic::ParsedQuicVersionVector & advertised_versions)147*6777b538SAndroid Build Coastguard Worker   void set_advertised_versions(
148*6777b538SAndroid Build Coastguard Worker       const quic::ParsedQuicVersionVector& advertised_versions) {
149*6777b538SAndroid Build Coastguard Worker     if (alternative_service_.protocol != kProtoQUIC) {
150*6777b538SAndroid Build Coastguard Worker       return;
151*6777b538SAndroid Build Coastguard Worker     }
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker     advertised_versions_ = advertised_versions;
154*6777b538SAndroid Build Coastguard Worker     std::sort(advertised_versions_.begin(), advertised_versions_.end(),
155*6777b538SAndroid Build Coastguard Worker               TransportVersionLessThan);
156*6777b538SAndroid Build Coastguard Worker   }
157*6777b538SAndroid Build Coastguard Worker 
alternative_service()158*6777b538SAndroid Build Coastguard Worker   const AlternativeService& alternative_service() const {
159*6777b538SAndroid Build Coastguard Worker     return alternative_service_;
160*6777b538SAndroid Build Coastguard Worker   }
161*6777b538SAndroid Build Coastguard Worker 
protocol()162*6777b538SAndroid Build Coastguard Worker   NextProto protocol() const { return alternative_service_.protocol; }
163*6777b538SAndroid Build Coastguard Worker 
host_port_pair()164*6777b538SAndroid Build Coastguard Worker   HostPortPair host_port_pair() const {
165*6777b538SAndroid Build Coastguard Worker     return alternative_service_.host_port_pair();
166*6777b538SAndroid Build Coastguard Worker   }
167*6777b538SAndroid Build Coastguard Worker 
expiration()168*6777b538SAndroid Build Coastguard Worker   base::Time expiration() const { return expiration_; }
169*6777b538SAndroid Build Coastguard Worker 
advertised_versions()170*6777b538SAndroid Build Coastguard Worker   const quic::ParsedQuicVersionVector& advertised_versions() const {
171*6777b538SAndroid Build Coastguard Worker     return advertised_versions_;
172*6777b538SAndroid Build Coastguard Worker   }
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker  private:
175*6777b538SAndroid Build Coastguard Worker   AlternativeServiceInfo(
176*6777b538SAndroid Build Coastguard Worker       const AlternativeService& alternative_service,
177*6777b538SAndroid Build Coastguard Worker       base::Time expiration,
178*6777b538SAndroid Build Coastguard Worker       const quic::ParsedQuicVersionVector& advertised_versions);
179*6777b538SAndroid Build Coastguard Worker 
180*6777b538SAndroid Build Coastguard Worker   static bool TransportVersionLessThan(const quic::ParsedQuicVersion& lhs,
181*6777b538SAndroid Build Coastguard Worker                                        const quic::ParsedQuicVersion& rhs);
182*6777b538SAndroid Build Coastguard Worker 
183*6777b538SAndroid Build Coastguard Worker   AlternativeService alternative_service_;
184*6777b538SAndroid Build Coastguard Worker   base::Time expiration_;
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker   // Lists all the QUIC versions that are advertised by the server and supported
187*6777b538SAndroid Build Coastguard Worker   // by Chrome. If empty, defaults to versions used by the current instance of
188*6777b538SAndroid Build Coastguard Worker   // the netstack. This list is sorted according to the server's preference.
189*6777b538SAndroid Build Coastguard Worker   quic::ParsedQuicVersionVector advertised_versions_;
190*6777b538SAndroid Build Coastguard Worker };
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker using AlternativeServiceInfoVector = std::vector<AlternativeServiceInfo>;
193*6777b538SAndroid Build Coastguard Worker 
194*6777b538SAndroid Build Coastguard Worker NET_EXPORT_PRIVATE AlternativeServiceInfoVector ProcessAlternativeServices(
195*6777b538SAndroid Build Coastguard Worker     const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector&
196*6777b538SAndroid Build Coastguard Worker         alternative_service_vector,
197*6777b538SAndroid Build Coastguard Worker     bool is_http2_enabled,
198*6777b538SAndroid Build Coastguard Worker     bool is_quic_enabled,
199*6777b538SAndroid Build Coastguard Worker     const quic::ParsedQuicVersionVector& supported_quic_versions);
200*6777b538SAndroid Build Coastguard Worker 
201*6777b538SAndroid Build Coastguard Worker }  // namespace net
202*6777b538SAndroid Build Coastguard Worker 
203*6777b538SAndroid Build Coastguard Worker #endif  // NET_HTTP_ALTERNATIVE_SERVICE_H_
204