xref: /aosp_15_r20/external/cronet/net/http/http_response_info.cc (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 #include "net/http/http_response_info.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <optional>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/pickle.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/cert/sct_status_flags.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/cert/signed_certificate_timestamp.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/cert/x509_certificate.h"
17*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_headers.h"
18*6777b538SAndroid Build Coastguard Worker #include "net/ssl/ssl_cert_request_info.h"
19*6777b538SAndroid Build Coastguard Worker #include "net/ssl/ssl_connection_status_flags.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
21*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/ssl.h"
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker using base::Time;
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker namespace net {
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker namespace {
28*6777b538SAndroid Build Coastguard Worker 
KeyExchangeGroupIsValid(int ssl_connection_status)29*6777b538SAndroid Build Coastguard Worker bool KeyExchangeGroupIsValid(int ssl_connection_status) {
30*6777b538SAndroid Build Coastguard Worker   // TLS 1.3 and later always treat the field correctly.
31*6777b538SAndroid Build Coastguard Worker   if (SSLConnectionStatusToVersion(ssl_connection_status) >=
32*6777b538SAndroid Build Coastguard Worker       SSL_CONNECTION_VERSION_TLS1_3) {
33*6777b538SAndroid Build Coastguard Worker     return true;
34*6777b538SAndroid Build Coastguard Worker   }
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker   // Prior to TLS 1.3, only ECDHE ciphers have groups.
37*6777b538SAndroid Build Coastguard Worker   const SSL_CIPHER* cipher = SSL_get_cipher_by_value(
38*6777b538SAndroid Build Coastguard Worker       SSLConnectionStatusToCipherSuite(ssl_connection_status));
39*6777b538SAndroid Build Coastguard Worker   return cipher && SSL_CIPHER_get_kx_nid(cipher) == NID_kx_ecdhe;
40*6777b538SAndroid Build Coastguard Worker }
41*6777b538SAndroid Build Coastguard Worker 
42*6777b538SAndroid Build Coastguard Worker }  // namespace
43*6777b538SAndroid Build Coastguard Worker 
44*6777b538SAndroid Build Coastguard Worker // These values can be bit-wise combined to form the flags field of the
45*6777b538SAndroid Build Coastguard Worker // serialized HttpResponseInfo.
46*6777b538SAndroid Build Coastguard Worker enum {
47*6777b538SAndroid Build Coastguard Worker   // The version of the response info used when persisting response info.
48*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_VERSION = 3,
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   // The minimum version supported for deserializing response info.
51*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_MINIMUM_VERSION = 3,
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker   // We reserve up to 8 bits for the version number.
54*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_VERSION_MASK = 0xFF,
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response info has a cert at the end.
57*6777b538SAndroid Build Coastguard Worker   // Version 1 serialized only the end-entity certificate, while subsequent
58*6777b538SAndroid Build Coastguard Worker   // versions include the available certificate chain.
59*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_CERT = 1 << 8,
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker   // This bit was historically set if the response info had a security-bits
62*6777b538SAndroid Build Coastguard Worker   // field (security strength, in bits, of the SSL connection) at the end.
63*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_SECURITY_BITS = 1 << 9,
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response info has a cert status at the end.
66*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_CERT_STATUS = 1 << 10,
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response info has vary header data.
69*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_VARY_DATA = 1 << 11,
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker   // This bit is set if the request was cancelled before completion.
72*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_TRUNCATED = 1 << 12,
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response was received via SPDY.
75*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_WAS_SPDY = 1 << 13,
76*6777b538SAndroid Build Coastguard Worker 
77*6777b538SAndroid Build Coastguard Worker   // This bit is set if the request has ALPN negotiated.
78*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_WAS_ALPN = 1 << 14,
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker   // This bit is set if the request was fetched via an explicit proxy.
81*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_WAS_PROXY = 1 << 15,
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response info has an SSL connection status field.
84*6777b538SAndroid Build Coastguard Worker   // This contains the ciphersuite used to fetch the resource as well as the
85*6777b538SAndroid Build Coastguard Worker   // protocol version, compression method and whether SSLv3 fallback was used.
86*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS = 1 << 16,
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response info has protocol version.
89*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL = 1 << 17,
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response info has connection info.
92*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_CONNECTION_INFO = 1 << 18,
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker   // This bit is set if the request has http authentication.
95*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_USE_HTTP_AUTHENTICATION = 1 << 19,
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker   // This bit is set if ssl_info has SCTs.
98*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS = 1 << 20,
99*6777b538SAndroid Build Coastguard Worker 
100*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_UNUSED_SINCE_PREFETCH = 1 << 21,
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response has a key exchange group.
103*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP = 1 << 22,
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker   // This bit is set if ssl_info recorded that PKP was bypassed due to a local
106*6777b538SAndroid Build Coastguard Worker   // trust anchor.
107*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_PKP_BYPASSED = 1 << 23,
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker   // This bit is set if stale_revalidate_time is stored.
110*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_STALENESS = 1 << 24,
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response has a peer signature algorithm.
113*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_PEER_SIGNATURE_ALGORITHM = 1 << 25,
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response is a prefetch whose reuse should be
116*6777b538SAndroid Build Coastguard Worker   // restricted in some way.
117*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_RESTRICTED_PREFETCH = 1 << 26,
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response has a nonempty `dns_aliases` entry.
120*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_DNS_ALIASES = 1 << 27,
121*6777b538SAndroid Build Coastguard Worker 
122*6777b538SAndroid Build Coastguard Worker   // This bit is now unused. It may be set on existing entries. Previously it
123*6777b538SAndroid Build Coastguard Worker   // was set for an entry in the single-keyed cache that had been marked
124*6777b538SAndroid Build Coastguard Worker   // unusable due to the cache transparency checksum not matching.
125*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_UNUSED_WAS_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE = 1 << 28,
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response has `encrypted_client_hello` set.
128*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_ENCRYPTED_CLIENT_HELLO = 1 << 29,
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response has `browser_run_id` set.
131*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_BROWSER_RUN_ID = 1 << 30,
132*6777b538SAndroid Build Coastguard Worker 
133*6777b538SAndroid Build Coastguard Worker   // This bit is set if the response has extra bit set.
134*6777b538SAndroid Build Coastguard Worker   RESPONSE_INFO_HAS_EXTRA_FLAGS = 1 << 31,
135*6777b538SAndroid Build Coastguard Worker };
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker // These values can be bit-wise combined to form the extra flags field of the
138*6777b538SAndroid Build Coastguard Worker // serialized HttpResponseInfo.
139*6777b538SAndroid Build Coastguard Worker enum {
140*6777b538SAndroid Build Coastguard Worker   // This bit is set if the request usd a shared dictionary for decoding its
141*6777b538SAndroid Build Coastguard Worker   // body.
142*6777b538SAndroid Build Coastguard Worker   RESPONSE_EXTRA_INFO_DID_USE_SHARED_DICTIONARY = 1,
143*6777b538SAndroid Build Coastguard Worker };
144*6777b538SAndroid Build Coastguard Worker 
145*6777b538SAndroid Build Coastguard Worker HttpResponseInfo::HttpResponseInfo() = default;
146*6777b538SAndroid Build Coastguard Worker 
147*6777b538SAndroid Build Coastguard Worker HttpResponseInfo::HttpResponseInfo(const HttpResponseInfo& rhs) = default;
148*6777b538SAndroid Build Coastguard Worker 
149*6777b538SAndroid Build Coastguard Worker HttpResponseInfo::~HttpResponseInfo() = default;
150*6777b538SAndroid Build Coastguard Worker 
151*6777b538SAndroid Build Coastguard Worker HttpResponseInfo& HttpResponseInfo::operator=(const HttpResponseInfo& rhs) =
152*6777b538SAndroid Build Coastguard Worker     default;
153*6777b538SAndroid Build Coastguard Worker 
InitFromPickle(const base::Pickle & pickle,bool * response_truncated)154*6777b538SAndroid Build Coastguard Worker bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle,
155*6777b538SAndroid Build Coastguard Worker                                       bool* response_truncated) {
156*6777b538SAndroid Build Coastguard Worker   base::PickleIterator iter(pickle);
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker   // Read flags and verify version
159*6777b538SAndroid Build Coastguard Worker   int flags;
160*6777b538SAndroid Build Coastguard Worker   int extra_flags = 0;
161*6777b538SAndroid Build Coastguard Worker   if (!iter.ReadInt(&flags))
162*6777b538SAndroid Build Coastguard Worker     return false;
163*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_EXTRA_FLAGS) {
164*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt(&extra_flags)) {
165*6777b538SAndroid Build Coastguard Worker       return false;
166*6777b538SAndroid Build Coastguard Worker     }
167*6777b538SAndroid Build Coastguard Worker   }
168*6777b538SAndroid Build Coastguard Worker   int version = flags & RESPONSE_INFO_VERSION_MASK;
169*6777b538SAndroid Build Coastguard Worker   if (version < RESPONSE_INFO_MINIMUM_VERSION ||
170*6777b538SAndroid Build Coastguard Worker       version > RESPONSE_INFO_VERSION) {
171*6777b538SAndroid Build Coastguard Worker     DLOG(ERROR) << "unexpected response info version: " << version;
172*6777b538SAndroid Build Coastguard Worker     return false;
173*6777b538SAndroid Build Coastguard Worker   }
174*6777b538SAndroid Build Coastguard Worker 
175*6777b538SAndroid Build Coastguard Worker   // Read request-time
176*6777b538SAndroid Build Coastguard Worker   int64_t time_val;
177*6777b538SAndroid Build Coastguard Worker   if (!iter.ReadInt64(&time_val))
178*6777b538SAndroid Build Coastguard Worker     return false;
179*6777b538SAndroid Build Coastguard Worker   request_time = Time::FromInternalValue(time_val);
180*6777b538SAndroid Build Coastguard Worker   was_cached = true;  // Set status to show cache resurrection.
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   // Read response-time
183*6777b538SAndroid Build Coastguard Worker   if (!iter.ReadInt64(&time_val))
184*6777b538SAndroid Build Coastguard Worker     return false;
185*6777b538SAndroid Build Coastguard Worker   response_time = Time::FromInternalValue(time_val);
186*6777b538SAndroid Build Coastguard Worker 
187*6777b538SAndroid Build Coastguard Worker   // Read response-headers
188*6777b538SAndroid Build Coastguard Worker   headers = base::MakeRefCounted<HttpResponseHeaders>(&iter);
189*6777b538SAndroid Build Coastguard Worker   if (headers->response_code() == -1)
190*6777b538SAndroid Build Coastguard Worker     return false;
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   // Read ssl-info
193*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_CERT) {
194*6777b538SAndroid Build Coastguard Worker     ssl_info.cert = X509Certificate::CreateFromPickle(&iter);
195*6777b538SAndroid Build Coastguard Worker     if (!ssl_info.cert.get())
196*6777b538SAndroid Build Coastguard Worker       return false;
197*6777b538SAndroid Build Coastguard Worker   }
198*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_CERT_STATUS) {
199*6777b538SAndroid Build Coastguard Worker     CertStatus cert_status;
200*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadUInt32(&cert_status))
201*6777b538SAndroid Build Coastguard Worker       return false;
202*6777b538SAndroid Build Coastguard Worker     ssl_info.cert_status = cert_status;
203*6777b538SAndroid Build Coastguard Worker   }
204*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_SECURITY_BITS) {
205*6777b538SAndroid Build Coastguard Worker     // The security_bits field has been removed from ssl_info. For backwards
206*6777b538SAndroid Build Coastguard Worker     // compatibility, we should still read the value out of iter.
207*6777b538SAndroid Build Coastguard Worker     int security_bits;
208*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt(&security_bits))
209*6777b538SAndroid Build Coastguard Worker       return false;
210*6777b538SAndroid Build Coastguard Worker   }
211*6777b538SAndroid Build Coastguard Worker 
212*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS) {
213*6777b538SAndroid Build Coastguard Worker     int connection_status;
214*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt(&connection_status))
215*6777b538SAndroid Build Coastguard Worker       return false;
216*6777b538SAndroid Build Coastguard Worker 
217*6777b538SAndroid Build Coastguard Worker     // SSLv3 is gone, so drop cached entries that were loaded over SSLv3.
218*6777b538SAndroid Build Coastguard Worker     if (SSLConnectionStatusToVersion(connection_status) ==
219*6777b538SAndroid Build Coastguard Worker         SSL_CONNECTION_VERSION_SSL3) {
220*6777b538SAndroid Build Coastguard Worker       return false;
221*6777b538SAndroid Build Coastguard Worker     }
222*6777b538SAndroid Build Coastguard Worker     ssl_info.connection_status = connection_status;
223*6777b538SAndroid Build Coastguard Worker   }
224*6777b538SAndroid Build Coastguard Worker 
225*6777b538SAndroid Build Coastguard Worker   // Signed Certificate Timestamps are no longer persisted to the cache, so
226*6777b538SAndroid Build Coastguard Worker   // ignore them when reading them out.
227*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS) {
228*6777b538SAndroid Build Coastguard Worker     int num_scts;
229*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt(&num_scts))
230*6777b538SAndroid Build Coastguard Worker       return false;
231*6777b538SAndroid Build Coastguard Worker     for (int i = 0; i < num_scts; ++i) {
232*6777b538SAndroid Build Coastguard Worker       scoped_refptr<ct::SignedCertificateTimestamp> sct(
233*6777b538SAndroid Build Coastguard Worker           ct::SignedCertificateTimestamp::CreateFromPickle(&iter));
234*6777b538SAndroid Build Coastguard Worker       uint16_t status;
235*6777b538SAndroid Build Coastguard Worker       if (!sct.get() || !iter.ReadUInt16(&status))
236*6777b538SAndroid Build Coastguard Worker         return false;
237*6777b538SAndroid Build Coastguard Worker     }
238*6777b538SAndroid Build Coastguard Worker   }
239*6777b538SAndroid Build Coastguard Worker 
240*6777b538SAndroid Build Coastguard Worker   // Read vary-data
241*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_VARY_DATA) {
242*6777b538SAndroid Build Coastguard Worker     if (!vary_data.InitFromPickle(&iter))
243*6777b538SAndroid Build Coastguard Worker       return false;
244*6777b538SAndroid Build Coastguard Worker   }
245*6777b538SAndroid Build Coastguard Worker 
246*6777b538SAndroid Build Coastguard Worker   // Read socket_address.
247*6777b538SAndroid Build Coastguard Worker   std::string socket_address_host;
248*6777b538SAndroid Build Coastguard Worker   if (!iter.ReadString(&socket_address_host))
249*6777b538SAndroid Build Coastguard Worker     return false;
250*6777b538SAndroid Build Coastguard Worker   // If the host was written, we always expect the port to follow.
251*6777b538SAndroid Build Coastguard Worker   uint16_t socket_address_port;
252*6777b538SAndroid Build Coastguard Worker   if (!iter.ReadUInt16(&socket_address_port))
253*6777b538SAndroid Build Coastguard Worker     return false;
254*6777b538SAndroid Build Coastguard Worker 
255*6777b538SAndroid Build Coastguard Worker   IPAddress ip_address;
256*6777b538SAndroid Build Coastguard Worker   if (ip_address.AssignFromIPLiteral(socket_address_host)) {
257*6777b538SAndroid Build Coastguard Worker     remote_endpoint = IPEndPoint(ip_address, socket_address_port);
258*6777b538SAndroid Build Coastguard Worker   } else if (ParseURLHostnameToAddress(socket_address_host, &ip_address)) {
259*6777b538SAndroid Build Coastguard Worker     remote_endpoint = IPEndPoint(ip_address, socket_address_port);
260*6777b538SAndroid Build Coastguard Worker   }
261*6777b538SAndroid Build Coastguard Worker 
262*6777b538SAndroid Build Coastguard Worker   // Read protocol-version.
263*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL) {
264*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadString(&alpn_negotiated_protocol))
265*6777b538SAndroid Build Coastguard Worker       return false;
266*6777b538SAndroid Build Coastguard Worker   }
267*6777b538SAndroid Build Coastguard Worker 
268*6777b538SAndroid Build Coastguard Worker   // Read connection info.
269*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_CONNECTION_INFO) {
270*6777b538SAndroid Build Coastguard Worker     int value;
271*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt(&value))
272*6777b538SAndroid Build Coastguard Worker       return false;
273*6777b538SAndroid Build Coastguard Worker 
274*6777b538SAndroid Build Coastguard Worker     if (value > static_cast<int>(HttpConnectionInfo::kUNKNOWN) &&
275*6777b538SAndroid Build Coastguard Worker         value <= static_cast<int>(HttpConnectionInfo::kMaxValue)) {
276*6777b538SAndroid Build Coastguard Worker       connection_info = static_cast<HttpConnectionInfo>(value);
277*6777b538SAndroid Build Coastguard Worker     }
278*6777b538SAndroid Build Coastguard Worker   }
279*6777b538SAndroid Build Coastguard Worker 
280*6777b538SAndroid Build Coastguard Worker   // Read key_exchange_group
281*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP) {
282*6777b538SAndroid Build Coastguard Worker     int key_exchange_group;
283*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt(&key_exchange_group))
284*6777b538SAndroid Build Coastguard Worker       return false;
285*6777b538SAndroid Build Coastguard Worker 
286*6777b538SAndroid Build Coastguard Worker     // Historically, the key_exchange_group field was key_exchange_info which
287*6777b538SAndroid Build Coastguard Worker     // conflated a number of different values based on the cipher suite, so some
288*6777b538SAndroid Build Coastguard Worker     // values must be discarded. See https://crbug.com/639421.
289*6777b538SAndroid Build Coastguard Worker     if (KeyExchangeGroupIsValid(ssl_info.connection_status))
290*6777b538SAndroid Build Coastguard Worker       ssl_info.key_exchange_group = key_exchange_group;
291*6777b538SAndroid Build Coastguard Worker   }
292*6777b538SAndroid Build Coastguard Worker 
293*6777b538SAndroid Build Coastguard Worker   // Read staleness time.
294*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_STALENESS) {
295*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt64(&time_val))
296*6777b538SAndroid Build Coastguard Worker       return false;
297*6777b538SAndroid Build Coastguard Worker     stale_revalidate_timeout = base::Time() + base::Microseconds(time_val);
298*6777b538SAndroid Build Coastguard Worker   }
299*6777b538SAndroid Build Coastguard Worker 
300*6777b538SAndroid Build Coastguard Worker   was_fetched_via_spdy = (flags & RESPONSE_INFO_WAS_SPDY) != 0;
301*6777b538SAndroid Build Coastguard Worker 
302*6777b538SAndroid Build Coastguard Worker   was_alpn_negotiated = (flags & RESPONSE_INFO_WAS_ALPN) != 0;
303*6777b538SAndroid Build Coastguard Worker 
304*6777b538SAndroid Build Coastguard Worker   was_fetched_via_proxy = (flags & RESPONSE_INFO_WAS_PROXY) != 0;
305*6777b538SAndroid Build Coastguard Worker 
306*6777b538SAndroid Build Coastguard Worker   *response_truncated = (flags & RESPONSE_INFO_TRUNCATED) != 0;
307*6777b538SAndroid Build Coastguard Worker 
308*6777b538SAndroid Build Coastguard Worker   did_use_http_auth = (flags & RESPONSE_INFO_USE_HTTP_AUTHENTICATION) != 0;
309*6777b538SAndroid Build Coastguard Worker 
310*6777b538SAndroid Build Coastguard Worker   unused_since_prefetch = (flags & RESPONSE_INFO_UNUSED_SINCE_PREFETCH) != 0;
311*6777b538SAndroid Build Coastguard Worker 
312*6777b538SAndroid Build Coastguard Worker   restricted_prefetch = (flags & RESPONSE_INFO_RESTRICTED_PREFETCH) != 0;
313*6777b538SAndroid Build Coastguard Worker 
314*6777b538SAndroid Build Coastguard Worker   // RESPONSE_INFO_UNUSED_WAS_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE is unused.
315*6777b538SAndroid Build Coastguard Worker 
316*6777b538SAndroid Build Coastguard Worker   ssl_info.pkp_bypassed = (flags & RESPONSE_INFO_PKP_BYPASSED) != 0;
317*6777b538SAndroid Build Coastguard Worker 
318*6777b538SAndroid Build Coastguard Worker   // Read peer_signature_algorithm.
319*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_PEER_SIGNATURE_ALGORITHM) {
320*6777b538SAndroid Build Coastguard Worker     int peer_signature_algorithm;
321*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt(&peer_signature_algorithm) ||
322*6777b538SAndroid Build Coastguard Worker         !base::IsValueInRangeForNumericType<uint16_t>(
323*6777b538SAndroid Build Coastguard Worker             peer_signature_algorithm)) {
324*6777b538SAndroid Build Coastguard Worker       return false;
325*6777b538SAndroid Build Coastguard Worker     }
326*6777b538SAndroid Build Coastguard Worker     ssl_info.peer_signature_algorithm =
327*6777b538SAndroid Build Coastguard Worker         base::checked_cast<uint16_t>(peer_signature_algorithm);
328*6777b538SAndroid Build Coastguard Worker   }
329*6777b538SAndroid Build Coastguard Worker 
330*6777b538SAndroid Build Coastguard Worker   // Read DNS aliases.
331*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_DNS_ALIASES) {
332*6777b538SAndroid Build Coastguard Worker     int num_aliases;
333*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt(&num_aliases))
334*6777b538SAndroid Build Coastguard Worker       return false;
335*6777b538SAndroid Build Coastguard Worker 
336*6777b538SAndroid Build Coastguard Worker     std::string alias;
337*6777b538SAndroid Build Coastguard Worker     for (int i = 0; i < num_aliases; i++) {
338*6777b538SAndroid Build Coastguard Worker       if (!iter.ReadString(&alias))
339*6777b538SAndroid Build Coastguard Worker         return false;
340*6777b538SAndroid Build Coastguard Worker       dns_aliases.insert(alias);
341*6777b538SAndroid Build Coastguard Worker     }
342*6777b538SAndroid Build Coastguard Worker   }
343*6777b538SAndroid Build Coastguard Worker 
344*6777b538SAndroid Build Coastguard Worker   ssl_info.encrypted_client_hello =
345*6777b538SAndroid Build Coastguard Worker       (flags & RESPONSE_INFO_ENCRYPTED_CLIENT_HELLO) != 0;
346*6777b538SAndroid Build Coastguard Worker 
347*6777b538SAndroid Build Coastguard Worker   // Read browser_run_id.
348*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_BROWSER_RUN_ID) {
349*6777b538SAndroid Build Coastguard Worker     int64_t id;
350*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt64(&id))
351*6777b538SAndroid Build Coastguard Worker       return false;
352*6777b538SAndroid Build Coastguard Worker     browser_run_id = std::make_optional(id);
353*6777b538SAndroid Build Coastguard Worker   }
354*6777b538SAndroid Build Coastguard Worker 
355*6777b538SAndroid Build Coastguard Worker   did_use_shared_dictionary =
356*6777b538SAndroid Build Coastguard Worker       (extra_flags & RESPONSE_EXTRA_INFO_DID_USE_SHARED_DICTIONARY) != 0;
357*6777b538SAndroid Build Coastguard Worker   return true;
358*6777b538SAndroid Build Coastguard Worker }
359*6777b538SAndroid Build Coastguard Worker 
Persist(base::Pickle * pickle,bool skip_transient_headers,bool response_truncated) const360*6777b538SAndroid Build Coastguard Worker void HttpResponseInfo::Persist(base::Pickle* pickle,
361*6777b538SAndroid Build Coastguard Worker                                bool skip_transient_headers,
362*6777b538SAndroid Build Coastguard Worker                                bool response_truncated) const {
363*6777b538SAndroid Build Coastguard Worker   int flags = RESPONSE_INFO_VERSION;
364*6777b538SAndroid Build Coastguard Worker   int extra_flags = 0;
365*6777b538SAndroid Build Coastguard Worker   if (ssl_info.is_valid()) {
366*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_HAS_CERT;
367*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_HAS_CERT_STATUS;
368*6777b538SAndroid Build Coastguard Worker     if (ssl_info.key_exchange_group != 0)
369*6777b538SAndroid Build Coastguard Worker       flags |= RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP;
370*6777b538SAndroid Build Coastguard Worker     if (ssl_info.connection_status != 0)
371*6777b538SAndroid Build Coastguard Worker       flags |= RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS;
372*6777b538SAndroid Build Coastguard Worker     if (ssl_info.peer_signature_algorithm != 0)
373*6777b538SAndroid Build Coastguard Worker       flags |= RESPONSE_INFO_HAS_PEER_SIGNATURE_ALGORITHM;
374*6777b538SAndroid Build Coastguard Worker   }
375*6777b538SAndroid Build Coastguard Worker   if (vary_data.is_valid())
376*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_HAS_VARY_DATA;
377*6777b538SAndroid Build Coastguard Worker   if (response_truncated)
378*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_TRUNCATED;
379*6777b538SAndroid Build Coastguard Worker   if (was_fetched_via_spdy)
380*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_WAS_SPDY;
381*6777b538SAndroid Build Coastguard Worker   if (was_alpn_negotiated) {
382*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_WAS_ALPN;
383*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL;
384*6777b538SAndroid Build Coastguard Worker   }
385*6777b538SAndroid Build Coastguard Worker   if (was_fetched_via_proxy)
386*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_WAS_PROXY;
387*6777b538SAndroid Build Coastguard Worker   if (connection_info != HttpConnectionInfo::kUNKNOWN) {
388*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_HAS_CONNECTION_INFO;
389*6777b538SAndroid Build Coastguard Worker   }
390*6777b538SAndroid Build Coastguard Worker   if (did_use_http_auth)
391*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_USE_HTTP_AUTHENTICATION;
392*6777b538SAndroid Build Coastguard Worker   if (unused_since_prefetch)
393*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_UNUSED_SINCE_PREFETCH;
394*6777b538SAndroid Build Coastguard Worker   if (restricted_prefetch)
395*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_RESTRICTED_PREFETCH;
396*6777b538SAndroid Build Coastguard Worker   // RESPONSE_INFO_UNUSED_WAS_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE is not used.
397*6777b538SAndroid Build Coastguard Worker   if (ssl_info.pkp_bypassed)
398*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_PKP_BYPASSED;
399*6777b538SAndroid Build Coastguard Worker   if (!stale_revalidate_timeout.is_null())
400*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_HAS_STALENESS;
401*6777b538SAndroid Build Coastguard Worker   if (!dns_aliases.empty())
402*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_HAS_DNS_ALIASES;
403*6777b538SAndroid Build Coastguard Worker   if (ssl_info.encrypted_client_hello)
404*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_ENCRYPTED_CLIENT_HELLO;
405*6777b538SAndroid Build Coastguard Worker   if (browser_run_id.has_value())
406*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_BROWSER_RUN_ID;
407*6777b538SAndroid Build Coastguard Worker 
408*6777b538SAndroid Build Coastguard Worker   if (did_use_shared_dictionary) {
409*6777b538SAndroid Build Coastguard Worker     extra_flags |= RESPONSE_EXTRA_INFO_DID_USE_SHARED_DICTIONARY;
410*6777b538SAndroid Build Coastguard Worker   }
411*6777b538SAndroid Build Coastguard Worker 
412*6777b538SAndroid Build Coastguard Worker   if (extra_flags) {
413*6777b538SAndroid Build Coastguard Worker     flags |= RESPONSE_INFO_HAS_EXTRA_FLAGS;
414*6777b538SAndroid Build Coastguard Worker   }
415*6777b538SAndroid Build Coastguard Worker 
416*6777b538SAndroid Build Coastguard Worker   pickle->WriteInt(flags);
417*6777b538SAndroid Build Coastguard Worker   if (extra_flags) {
418*6777b538SAndroid Build Coastguard Worker     pickle->WriteInt(extra_flags);
419*6777b538SAndroid Build Coastguard Worker   }
420*6777b538SAndroid Build Coastguard Worker   pickle->WriteInt64(request_time.ToInternalValue());
421*6777b538SAndroid Build Coastguard Worker   pickle->WriteInt64(response_time.ToInternalValue());
422*6777b538SAndroid Build Coastguard Worker 
423*6777b538SAndroid Build Coastguard Worker   HttpResponseHeaders::PersistOptions persist_options =
424*6777b538SAndroid Build Coastguard Worker       HttpResponseHeaders::PERSIST_RAW;
425*6777b538SAndroid Build Coastguard Worker 
426*6777b538SAndroid Build Coastguard Worker   if (skip_transient_headers) {
427*6777b538SAndroid Build Coastguard Worker     persist_options = HttpResponseHeaders::PERSIST_SANS_COOKIES |
428*6777b538SAndroid Build Coastguard Worker                       HttpResponseHeaders::PERSIST_SANS_CHALLENGES |
429*6777b538SAndroid Build Coastguard Worker                       HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP |
430*6777b538SAndroid Build Coastguard Worker                       HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE |
431*6777b538SAndroid Build Coastguard Worker                       HttpResponseHeaders::PERSIST_SANS_RANGES |
432*6777b538SAndroid Build Coastguard Worker                       HttpResponseHeaders::PERSIST_SANS_SECURITY_STATE;
433*6777b538SAndroid Build Coastguard Worker   }
434*6777b538SAndroid Build Coastguard Worker 
435*6777b538SAndroid Build Coastguard Worker   headers->Persist(pickle, persist_options);
436*6777b538SAndroid Build Coastguard Worker 
437*6777b538SAndroid Build Coastguard Worker   if (ssl_info.is_valid()) {
438*6777b538SAndroid Build Coastguard Worker     ssl_info.cert->Persist(pickle);
439*6777b538SAndroid Build Coastguard Worker     pickle->WriteUInt32(ssl_info.cert_status);
440*6777b538SAndroid Build Coastguard Worker     if (ssl_info.connection_status != 0)
441*6777b538SAndroid Build Coastguard Worker       pickle->WriteInt(ssl_info.connection_status);
442*6777b538SAndroid Build Coastguard Worker   }
443*6777b538SAndroid Build Coastguard Worker 
444*6777b538SAndroid Build Coastguard Worker   if (vary_data.is_valid())
445*6777b538SAndroid Build Coastguard Worker     vary_data.Persist(pickle);
446*6777b538SAndroid Build Coastguard Worker 
447*6777b538SAndroid Build Coastguard Worker   pickle->WriteString(remote_endpoint.ToStringWithoutPort());
448*6777b538SAndroid Build Coastguard Worker   pickle->WriteUInt16(remote_endpoint.port());
449*6777b538SAndroid Build Coastguard Worker 
450*6777b538SAndroid Build Coastguard Worker   if (was_alpn_negotiated)
451*6777b538SAndroid Build Coastguard Worker     pickle->WriteString(alpn_negotiated_protocol);
452*6777b538SAndroid Build Coastguard Worker 
453*6777b538SAndroid Build Coastguard Worker   if (connection_info != HttpConnectionInfo::kUNKNOWN) {
454*6777b538SAndroid Build Coastguard Worker     pickle->WriteInt(static_cast<int>(connection_info));
455*6777b538SAndroid Build Coastguard Worker   }
456*6777b538SAndroid Build Coastguard Worker 
457*6777b538SAndroid Build Coastguard Worker   if (ssl_info.is_valid() && ssl_info.key_exchange_group != 0)
458*6777b538SAndroid Build Coastguard Worker     pickle->WriteInt(ssl_info.key_exchange_group);
459*6777b538SAndroid Build Coastguard Worker 
460*6777b538SAndroid Build Coastguard Worker   if (flags & RESPONSE_INFO_HAS_STALENESS) {
461*6777b538SAndroid Build Coastguard Worker     pickle->WriteInt64(
462*6777b538SAndroid Build Coastguard Worker         (stale_revalidate_timeout - base::Time()).InMicroseconds());
463*6777b538SAndroid Build Coastguard Worker   }
464*6777b538SAndroid Build Coastguard Worker 
465*6777b538SAndroid Build Coastguard Worker   if (ssl_info.is_valid() && ssl_info.peer_signature_algorithm != 0)
466*6777b538SAndroid Build Coastguard Worker     pickle->WriteInt(ssl_info.peer_signature_algorithm);
467*6777b538SAndroid Build Coastguard Worker 
468*6777b538SAndroid Build Coastguard Worker   if (!dns_aliases.empty()) {
469*6777b538SAndroid Build Coastguard Worker     pickle->WriteInt(dns_aliases.size());
470*6777b538SAndroid Build Coastguard Worker     for (const auto& alias : dns_aliases)
471*6777b538SAndroid Build Coastguard Worker       pickle->WriteString(alias);
472*6777b538SAndroid Build Coastguard Worker   }
473*6777b538SAndroid Build Coastguard Worker 
474*6777b538SAndroid Build Coastguard Worker   if (browser_run_id.has_value()) {
475*6777b538SAndroid Build Coastguard Worker     pickle->WriteInt64(browser_run_id.value());
476*6777b538SAndroid Build Coastguard Worker   }
477*6777b538SAndroid Build Coastguard Worker }
478*6777b538SAndroid Build Coastguard Worker 
DidUseQuic() const479*6777b538SAndroid Build Coastguard Worker bool HttpResponseInfo::DidUseQuic() const {
480*6777b538SAndroid Build Coastguard Worker   switch (connection_info) {
481*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kUNKNOWN:
482*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kHTTP1_1:
483*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kDEPRECATED_SPDY2:
484*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kDEPRECATED_SPDY3:
485*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kHTTP2:
486*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kDEPRECATED_HTTP2_14:
487*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kDEPRECATED_HTTP2_15:
488*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kHTTP0_9:
489*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kHTTP1_0:
490*6777b538SAndroid Build Coastguard Worker       return false;
491*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_UNKNOWN_VERSION:
492*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_32:
493*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_33:
494*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_34:
495*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_35:
496*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_36:
497*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_37:
498*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_38:
499*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_39:
500*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_40:
501*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_41:
502*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_42:
503*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_43:
504*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_44:
505*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_45:
506*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_46:
507*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_47:
508*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_Q048:
509*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_T048:
510*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_Q049:
511*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_T049:
512*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_Q050:
513*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_T050:
514*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_Q099:
515*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_T099:
516*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_999:
517*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_DRAFT_25:
518*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_DRAFT_27:
519*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_DRAFT_28:
520*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_DRAFT_29:
521*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_T051:
522*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_RFC_V1:
523*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kDEPRECATED_QUIC_2_DRAFT_1:
524*6777b538SAndroid Build Coastguard Worker     case HttpConnectionInfo::kQUIC_2_DRAFT_8:
525*6777b538SAndroid Build Coastguard Worker       return true;
526*6777b538SAndroid Build Coastguard Worker   }
527*6777b538SAndroid Build Coastguard Worker }
528*6777b538SAndroid Build Coastguard Worker 
529*6777b538SAndroid Build Coastguard Worker }  // namespace net
530