• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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