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 #include "net/http/http_response_info.h"
6
7 #include "base/logging.h"
8 #include "base/numerics/safe_conversions.h"
9 #include "base/pickle.h"
10 #include "base/time/time.h"
11 #include "net/base/net_errors.h"
12 #include "net/cert/sct_status_flags.h"
13 #include "net/cert/signed_certificate_timestamp.h"
14 #include "net/cert/x509_certificate.h"
15 #include "net/http/http_response_headers.h"
16 #include "net/ssl/ssl_cert_request_info.h"
17 #include "net/ssl/ssl_connection_status_flags.h"
18 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
19 #include "third_party/abseil-cpp/absl/types/optional.h"
20 #include "third_party/boringssl/src/include/openssl/ssl.h"
21
22 using base::Time;
23
24 namespace net {
25
26 namespace {
27
KeyExchangeGroupIsValid(int ssl_connection_status)28 bool KeyExchangeGroupIsValid(int ssl_connection_status) {
29 // TLS 1.3 and later always treat the field correctly.
30 if (SSLConnectionStatusToVersion(ssl_connection_status) >=
31 SSL_CONNECTION_VERSION_TLS1_3) {
32 return true;
33 }
34
35 // Prior to TLS 1.3, only ECDHE ciphers have groups.
36 const SSL_CIPHER* cipher = SSL_get_cipher_by_value(
37 SSLConnectionStatusToCipherSuite(ssl_connection_status));
38 return cipher && SSL_CIPHER_get_kx_nid(cipher) == NID_kx_ecdhe;
39 }
40
41 } // namespace
42
43 // These values can be bit-wise combined to form the flags field of the
44 // serialized HttpResponseInfo.
45 enum {
46 // The version of the response info used when persisting response info.
47 RESPONSE_INFO_VERSION = 3,
48
49 // The minimum version supported for deserializing response info.
50 RESPONSE_INFO_MINIMUM_VERSION = 3,
51
52 // We reserve up to 8 bits for the version number.
53 RESPONSE_INFO_VERSION_MASK = 0xFF,
54
55 // This bit is set if the response info has a cert at the end.
56 // Version 1 serialized only the end-entity certificate, while subsequent
57 // versions include the available certificate chain.
58 RESPONSE_INFO_HAS_CERT = 1 << 8,
59
60 // This bit was historically set if the response info had a security-bits
61 // field (security strength, in bits, of the SSL connection) at the end.
62 RESPONSE_INFO_HAS_SECURITY_BITS = 1 << 9,
63
64 // This bit is set if the response info has a cert status at the end.
65 RESPONSE_INFO_HAS_CERT_STATUS = 1 << 10,
66
67 // This bit is set if the response info has vary header data.
68 RESPONSE_INFO_HAS_VARY_DATA = 1 << 11,
69
70 // This bit is set if the request was cancelled before completion.
71 RESPONSE_INFO_TRUNCATED = 1 << 12,
72
73 // This bit is set if the response was received via SPDY.
74 RESPONSE_INFO_WAS_SPDY = 1 << 13,
75
76 // This bit is set if the request has ALPN negotiated.
77 RESPONSE_INFO_WAS_ALPN = 1 << 14,
78
79 // This bit is set if the request was fetched via an explicit proxy.
80 RESPONSE_INFO_WAS_PROXY = 1 << 15,
81
82 // This bit is set if the response info has an SSL connection status field.
83 // This contains the ciphersuite used to fetch the resource as well as the
84 // protocol version, compression method and whether SSLv3 fallback was used.
85 RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS = 1 << 16,
86
87 // This bit is set if the response info has protocol version.
88 RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL = 1 << 17,
89
90 // This bit is set if the response info has connection info.
91 RESPONSE_INFO_HAS_CONNECTION_INFO = 1 << 18,
92
93 // This bit is set if the request has http authentication.
94 RESPONSE_INFO_USE_HTTP_AUTHENTICATION = 1 << 19,
95
96 // This bit is set if ssl_info has SCTs.
97 RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS = 1 << 20,
98
99 RESPONSE_INFO_UNUSED_SINCE_PREFETCH = 1 << 21,
100
101 // This bit is set if the response has a key exchange group.
102 RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP = 1 << 22,
103
104 // This bit is set if ssl_info recorded that PKP was bypassed due to a local
105 // trust anchor.
106 RESPONSE_INFO_PKP_BYPASSED = 1 << 23,
107
108 // This bit is set if stale_revalidate_time is stored.
109 RESPONSE_INFO_HAS_STALENESS = 1 << 24,
110
111 // This bit is set if the response has a peer signature algorithm.
112 RESPONSE_INFO_HAS_PEER_SIGNATURE_ALGORITHM = 1 << 25,
113
114 // This bit is set if the response is a prefetch whose reuse should be
115 // restricted in some way.
116 RESPONSE_INFO_RESTRICTED_PREFETCH = 1 << 26,
117
118 // This bit is set if the response has a nonempty `dns_aliases` entry.
119 RESPONSE_INFO_HAS_DNS_ALIASES = 1 << 27,
120
121 // This bit is set for an entry in the single-keyed cache that has been marked
122 // unusable due to the checksum not matching.
123 RESPONSE_INFO_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE = 1 << 28,
124
125 // This bit is set if the response has `encrypted_client_hello` set.
126 RESPONSE_INFO_ENCRYPTED_CLIENT_HELLO = 1 << 29,
127
128 // This bit is set if the response has `browser_run_id` set.
129 RESPONSE_INFO_BROWSER_RUN_ID = 1 << 30,
130
131 // This enum only has a few bits (`1 << 31` is the limit). If allocating the
132 // last flag, instead allocate it as `RESPONSE_INFO_HAS_EXTRA_FLAGS` to
133 // signal another flags word.
134 };
135
ConnectionInfoToCoarse(ConnectionInfo info)136 HttpResponseInfo::ConnectionInfoCoarse HttpResponseInfo::ConnectionInfoToCoarse(
137 ConnectionInfo info) {
138 switch (info) {
139 case CONNECTION_INFO_HTTP0_9:
140 case CONNECTION_INFO_HTTP1_0:
141 case CONNECTION_INFO_HTTP1_1:
142 return CONNECTION_INFO_COARSE_HTTP1;
143
144 case CONNECTION_INFO_HTTP2:
145 case CONNECTION_INFO_DEPRECATED_SPDY2:
146 case CONNECTION_INFO_DEPRECATED_SPDY3:
147 case CONNECTION_INFO_DEPRECATED_HTTP2_14:
148 case CONNECTION_INFO_DEPRECATED_HTTP2_15:
149 return CONNECTION_INFO_COARSE_HTTP2;
150
151 case CONNECTION_INFO_QUIC_UNKNOWN_VERSION:
152 case CONNECTION_INFO_QUIC_32:
153 case CONNECTION_INFO_QUIC_33:
154 case CONNECTION_INFO_QUIC_34:
155 case CONNECTION_INFO_QUIC_35:
156 case CONNECTION_INFO_QUIC_36:
157 case CONNECTION_INFO_QUIC_37:
158 case CONNECTION_INFO_QUIC_38:
159 case CONNECTION_INFO_QUIC_39:
160 case CONNECTION_INFO_QUIC_40:
161 case CONNECTION_INFO_QUIC_41:
162 case CONNECTION_INFO_QUIC_42:
163 case CONNECTION_INFO_QUIC_43:
164 case CONNECTION_INFO_QUIC_44:
165 case CONNECTION_INFO_QUIC_45:
166 case CONNECTION_INFO_QUIC_46:
167 case CONNECTION_INFO_QUIC_47:
168 case CONNECTION_INFO_QUIC_Q048:
169 case CONNECTION_INFO_QUIC_T048:
170 case CONNECTION_INFO_QUIC_Q049:
171 case CONNECTION_INFO_QUIC_T049:
172 case CONNECTION_INFO_QUIC_Q050:
173 case CONNECTION_INFO_QUIC_T050:
174 case CONNECTION_INFO_QUIC_Q099:
175 case CONNECTION_INFO_QUIC_T099:
176 case CONNECTION_INFO_QUIC_999:
177 case CONNECTION_INFO_QUIC_DRAFT_25:
178 case CONNECTION_INFO_QUIC_DRAFT_27:
179 case CONNECTION_INFO_QUIC_DRAFT_28:
180 case CONNECTION_INFO_QUIC_DRAFT_29:
181 case CONNECTION_INFO_QUIC_T051:
182 case CONNECTION_INFO_QUIC_RFC_V1:
183 case CONNECTION_INFO_DEPRECATED_QUIC_2_DRAFT_1:
184 case CONNECTION_INFO_QUIC_2_DRAFT_8:
185 return CONNECTION_INFO_COARSE_QUIC;
186
187 case CONNECTION_INFO_UNKNOWN:
188 return CONNECTION_INFO_COARSE_OTHER;
189
190 case NUM_OF_CONNECTION_INFOS:
191 NOTREACHED();
192 return CONNECTION_INFO_COARSE_OTHER;
193 }
194
195 NOTREACHED();
196 return CONNECTION_INFO_COARSE_OTHER;
197 }
198
199 HttpResponseInfo::HttpResponseInfo() = default;
200
201 HttpResponseInfo::HttpResponseInfo(const HttpResponseInfo& rhs) = default;
202
203 HttpResponseInfo::~HttpResponseInfo() = default;
204
205 HttpResponseInfo& HttpResponseInfo::operator=(const HttpResponseInfo& rhs) =
206 default;
207
InitFromPickle(const base::Pickle & pickle,bool * response_truncated)208 bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle,
209 bool* response_truncated) {
210 base::PickleIterator iter(pickle);
211
212 // Read flags and verify version
213 int flags;
214 if (!iter.ReadInt(&flags))
215 return false;
216 int version = flags & RESPONSE_INFO_VERSION_MASK;
217 if (version < RESPONSE_INFO_MINIMUM_VERSION ||
218 version > RESPONSE_INFO_VERSION) {
219 DLOG(ERROR) << "unexpected response info version: " << version;
220 return false;
221 }
222
223 // Read request-time
224 int64_t time_val;
225 if (!iter.ReadInt64(&time_val))
226 return false;
227 request_time = Time::FromInternalValue(time_val);
228 was_cached = true; // Set status to show cache resurrection.
229
230 // Read response-time
231 if (!iter.ReadInt64(&time_val))
232 return false;
233 response_time = Time::FromInternalValue(time_val);
234
235 // Read response-headers
236 headers = base::MakeRefCounted<HttpResponseHeaders>(&iter);
237 if (headers->response_code() == -1)
238 return false;
239
240 // Read ssl-info
241 if (flags & RESPONSE_INFO_HAS_CERT) {
242 ssl_info.cert = X509Certificate::CreateFromPickle(&iter);
243 if (!ssl_info.cert.get())
244 return false;
245 }
246 if (flags & RESPONSE_INFO_HAS_CERT_STATUS) {
247 CertStatus cert_status;
248 if (!iter.ReadUInt32(&cert_status))
249 return false;
250 ssl_info.cert_status = cert_status;
251 }
252 if (flags & RESPONSE_INFO_HAS_SECURITY_BITS) {
253 // The security_bits field has been removed from ssl_info. For backwards
254 // compatibility, we should still read the value out of iter.
255 int security_bits;
256 if (!iter.ReadInt(&security_bits))
257 return false;
258 }
259
260 if (flags & RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS) {
261 int connection_status;
262 if (!iter.ReadInt(&connection_status))
263 return false;
264
265 // SSLv3 is gone, so drop cached entries that were loaded over SSLv3.
266 if (SSLConnectionStatusToVersion(connection_status) ==
267 SSL_CONNECTION_VERSION_SSL3) {
268 return false;
269 }
270 ssl_info.connection_status = connection_status;
271 }
272
273 // Signed Certificate Timestamps are no longer persisted to the cache, so
274 // ignore them when reading them out.
275 if (flags & RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS) {
276 int num_scts;
277 if (!iter.ReadInt(&num_scts))
278 return false;
279 for (int i = 0; i < num_scts; ++i) {
280 scoped_refptr<ct::SignedCertificateTimestamp> sct(
281 ct::SignedCertificateTimestamp::CreateFromPickle(&iter));
282 uint16_t status;
283 if (!sct.get() || !iter.ReadUInt16(&status))
284 return false;
285 }
286 }
287
288 // Read vary-data
289 if (flags & RESPONSE_INFO_HAS_VARY_DATA) {
290 if (!vary_data.InitFromPickle(&iter))
291 return false;
292 }
293
294 // Read socket_address.
295 std::string socket_address_host;
296 if (!iter.ReadString(&socket_address_host))
297 return false;
298 // If the host was written, we always expect the port to follow.
299 uint16_t socket_address_port;
300 if (!iter.ReadUInt16(&socket_address_port))
301 return false;
302
303 IPAddress ip_address;
304 if (ip_address.AssignFromIPLiteral(socket_address_host)) {
305 remote_endpoint = IPEndPoint(ip_address, socket_address_port);
306 } else if (ParseURLHostnameToAddress(socket_address_host, &ip_address)) {
307 remote_endpoint = IPEndPoint(ip_address, socket_address_port);
308 }
309
310 // Read protocol-version.
311 if (flags & RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL) {
312 if (!iter.ReadString(&alpn_negotiated_protocol))
313 return false;
314 }
315
316 // Read connection info.
317 if (flags & RESPONSE_INFO_HAS_CONNECTION_INFO) {
318 int value;
319 if (!iter.ReadInt(&value))
320 return false;
321
322 if (value > static_cast<int>(CONNECTION_INFO_UNKNOWN) &&
323 value < static_cast<int>(NUM_OF_CONNECTION_INFOS)) {
324 connection_info = static_cast<ConnectionInfo>(value);
325 }
326 }
327
328 // Read key_exchange_group
329 if (flags & RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP) {
330 int key_exchange_group;
331 if (!iter.ReadInt(&key_exchange_group))
332 return false;
333
334 // Historically, the key_exchange_group field was key_exchange_info which
335 // conflated a number of different values based on the cipher suite, so some
336 // values must be discarded. See https://crbug.com/639421.
337 if (KeyExchangeGroupIsValid(ssl_info.connection_status))
338 ssl_info.key_exchange_group = key_exchange_group;
339 }
340
341 // Read staleness time.
342 if (flags & RESPONSE_INFO_HAS_STALENESS) {
343 if (!iter.ReadInt64(&time_val))
344 return false;
345 stale_revalidate_timeout = base::Time() + base::Microseconds(time_val);
346 }
347
348 was_fetched_via_spdy = (flags & RESPONSE_INFO_WAS_SPDY) != 0;
349
350 was_alpn_negotiated = (flags & RESPONSE_INFO_WAS_ALPN) != 0;
351
352 was_fetched_via_proxy = (flags & RESPONSE_INFO_WAS_PROXY) != 0;
353
354 *response_truncated = (flags & RESPONSE_INFO_TRUNCATED) != 0;
355
356 did_use_http_auth = (flags & RESPONSE_INFO_USE_HTTP_AUTHENTICATION) != 0;
357
358 unused_since_prefetch = (flags & RESPONSE_INFO_UNUSED_SINCE_PREFETCH) != 0;
359
360 restricted_prefetch = (flags & RESPONSE_INFO_RESTRICTED_PREFETCH) != 0;
361
362 single_keyed_cache_entry_unusable =
363 (flags & RESPONSE_INFO_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE) != 0;
364
365 ssl_info.pkp_bypassed = (flags & RESPONSE_INFO_PKP_BYPASSED) != 0;
366
367 // Read peer_signature_algorithm.
368 if (flags & RESPONSE_INFO_HAS_PEER_SIGNATURE_ALGORITHM) {
369 int peer_signature_algorithm;
370 if (!iter.ReadInt(&peer_signature_algorithm) ||
371 !base::IsValueInRangeForNumericType<uint16_t>(
372 peer_signature_algorithm)) {
373 return false;
374 }
375 ssl_info.peer_signature_algorithm =
376 base::checked_cast<uint16_t>(peer_signature_algorithm);
377 }
378
379 // Read DNS aliases.
380 if (flags & RESPONSE_INFO_HAS_DNS_ALIASES) {
381 int num_aliases;
382 if (!iter.ReadInt(&num_aliases))
383 return false;
384
385 std::string alias;
386 for (int i = 0; i < num_aliases; i++) {
387 if (!iter.ReadString(&alias))
388 return false;
389 dns_aliases.insert(alias);
390 }
391 }
392
393 ssl_info.encrypted_client_hello =
394 (flags & RESPONSE_INFO_ENCRYPTED_CLIENT_HELLO) != 0;
395
396 // Read browser_run_id.
397 if (flags & RESPONSE_INFO_BROWSER_RUN_ID) {
398 int64_t id;
399 if (!iter.ReadInt64(&id))
400 return false;
401 browser_run_id = absl::make_optional(id);
402 }
403
404 return true;
405 }
406
Persist(base::Pickle * pickle,bool skip_transient_headers,bool response_truncated) const407 void HttpResponseInfo::Persist(base::Pickle* pickle,
408 bool skip_transient_headers,
409 bool response_truncated) const {
410 int flags = RESPONSE_INFO_VERSION;
411 if (ssl_info.is_valid()) {
412 flags |= RESPONSE_INFO_HAS_CERT;
413 flags |= RESPONSE_INFO_HAS_CERT_STATUS;
414 if (ssl_info.key_exchange_group != 0)
415 flags |= RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP;
416 if (ssl_info.connection_status != 0)
417 flags |= RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS;
418 if (ssl_info.peer_signature_algorithm != 0)
419 flags |= RESPONSE_INFO_HAS_PEER_SIGNATURE_ALGORITHM;
420 }
421 if (vary_data.is_valid())
422 flags |= RESPONSE_INFO_HAS_VARY_DATA;
423 if (response_truncated)
424 flags |= RESPONSE_INFO_TRUNCATED;
425 if (was_fetched_via_spdy)
426 flags |= RESPONSE_INFO_WAS_SPDY;
427 if (was_alpn_negotiated) {
428 flags |= RESPONSE_INFO_WAS_ALPN;
429 flags |= RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL;
430 }
431 if (was_fetched_via_proxy)
432 flags |= RESPONSE_INFO_WAS_PROXY;
433 if (connection_info != CONNECTION_INFO_UNKNOWN)
434 flags |= RESPONSE_INFO_HAS_CONNECTION_INFO;
435 if (did_use_http_auth)
436 flags |= RESPONSE_INFO_USE_HTTP_AUTHENTICATION;
437 if (unused_since_prefetch)
438 flags |= RESPONSE_INFO_UNUSED_SINCE_PREFETCH;
439 if (restricted_prefetch)
440 flags |= RESPONSE_INFO_RESTRICTED_PREFETCH;
441 if (single_keyed_cache_entry_unusable)
442 flags |= RESPONSE_INFO_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE;
443 if (ssl_info.pkp_bypassed)
444 flags |= RESPONSE_INFO_PKP_BYPASSED;
445 if (!stale_revalidate_timeout.is_null())
446 flags |= RESPONSE_INFO_HAS_STALENESS;
447 if (!dns_aliases.empty())
448 flags |= RESPONSE_INFO_HAS_DNS_ALIASES;
449 if (ssl_info.encrypted_client_hello)
450 flags |= RESPONSE_INFO_ENCRYPTED_CLIENT_HELLO;
451 if (browser_run_id.has_value())
452 flags |= RESPONSE_INFO_BROWSER_RUN_ID;
453
454 pickle->WriteInt(flags);
455 pickle->WriteInt64(request_time.ToInternalValue());
456 pickle->WriteInt64(response_time.ToInternalValue());
457
458 HttpResponseHeaders::PersistOptions persist_options =
459 HttpResponseHeaders::PERSIST_RAW;
460
461 if (skip_transient_headers) {
462 persist_options = HttpResponseHeaders::PERSIST_SANS_COOKIES |
463 HttpResponseHeaders::PERSIST_SANS_CHALLENGES |
464 HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP |
465 HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE |
466 HttpResponseHeaders::PERSIST_SANS_RANGES |
467 HttpResponseHeaders::PERSIST_SANS_SECURITY_STATE;
468 }
469
470 headers->Persist(pickle, persist_options);
471
472 if (ssl_info.is_valid()) {
473 ssl_info.cert->Persist(pickle);
474 pickle->WriteUInt32(ssl_info.cert_status);
475 if (ssl_info.connection_status != 0)
476 pickle->WriteInt(ssl_info.connection_status);
477 }
478
479 if (vary_data.is_valid())
480 vary_data.Persist(pickle);
481
482 pickle->WriteString(remote_endpoint.ToStringWithoutPort());
483 pickle->WriteUInt16(remote_endpoint.port());
484
485 if (was_alpn_negotiated)
486 pickle->WriteString(alpn_negotiated_protocol);
487
488 if (connection_info != CONNECTION_INFO_UNKNOWN)
489 pickle->WriteInt(static_cast<int>(connection_info));
490
491 if (ssl_info.is_valid() && ssl_info.key_exchange_group != 0)
492 pickle->WriteInt(ssl_info.key_exchange_group);
493
494 if (flags & RESPONSE_INFO_HAS_STALENESS) {
495 pickle->WriteInt64(
496 (stale_revalidate_timeout - base::Time()).InMicroseconds());
497 }
498
499 if (ssl_info.is_valid() && ssl_info.peer_signature_algorithm != 0)
500 pickle->WriteInt(ssl_info.peer_signature_algorithm);
501
502 if (!dns_aliases.empty()) {
503 pickle->WriteInt(dns_aliases.size());
504 for (const auto& alias : dns_aliases)
505 pickle->WriteString(alias);
506 }
507
508 if (browser_run_id.has_value()) {
509 pickle->WriteInt64(browser_run_id.value());
510 }
511 }
512
DidUseQuic() const513 bool HttpResponseInfo::DidUseQuic() const {
514 switch (connection_info) {
515 case CONNECTION_INFO_UNKNOWN:
516 case CONNECTION_INFO_HTTP1_1:
517 case CONNECTION_INFO_DEPRECATED_SPDY2:
518 case CONNECTION_INFO_DEPRECATED_SPDY3:
519 case CONNECTION_INFO_HTTP2:
520 case CONNECTION_INFO_DEPRECATED_HTTP2_14:
521 case CONNECTION_INFO_DEPRECATED_HTTP2_15:
522 case CONNECTION_INFO_HTTP0_9:
523 case CONNECTION_INFO_HTTP1_0:
524 return false;
525 case CONNECTION_INFO_QUIC_UNKNOWN_VERSION:
526 case CONNECTION_INFO_QUIC_32:
527 case CONNECTION_INFO_QUIC_33:
528 case CONNECTION_INFO_QUIC_34:
529 case CONNECTION_INFO_QUIC_35:
530 case CONNECTION_INFO_QUIC_36:
531 case CONNECTION_INFO_QUIC_37:
532 case CONNECTION_INFO_QUIC_38:
533 case CONNECTION_INFO_QUIC_39:
534 case CONNECTION_INFO_QUIC_40:
535 case CONNECTION_INFO_QUIC_41:
536 case CONNECTION_INFO_QUIC_42:
537 case CONNECTION_INFO_QUIC_43:
538 case CONNECTION_INFO_QUIC_44:
539 case CONNECTION_INFO_QUIC_45:
540 case CONNECTION_INFO_QUIC_46:
541 case CONNECTION_INFO_QUIC_47:
542 case CONNECTION_INFO_QUIC_Q048:
543 case CONNECTION_INFO_QUIC_T048:
544 case CONNECTION_INFO_QUIC_Q049:
545 case CONNECTION_INFO_QUIC_T049:
546 case CONNECTION_INFO_QUIC_Q050:
547 case CONNECTION_INFO_QUIC_T050:
548 case CONNECTION_INFO_QUIC_Q099:
549 case CONNECTION_INFO_QUIC_T099:
550 case CONNECTION_INFO_QUIC_999:
551 case CONNECTION_INFO_QUIC_DRAFT_25:
552 case CONNECTION_INFO_QUIC_DRAFT_27:
553 case CONNECTION_INFO_QUIC_DRAFT_28:
554 case CONNECTION_INFO_QUIC_DRAFT_29:
555 case CONNECTION_INFO_QUIC_T051:
556 case CONNECTION_INFO_QUIC_RFC_V1:
557 case CONNECTION_INFO_DEPRECATED_QUIC_2_DRAFT_1:
558 case CONNECTION_INFO_QUIC_2_DRAFT_8:
559 return true;
560 case NUM_OF_CONNECTION_INFOS:
561 NOTREACHED();
562 return false;
563 }
564 NOTREACHED();
565 return false;
566 }
567
568 // static
ConnectionInfoToString(ConnectionInfo connection_info)569 std::string HttpResponseInfo::ConnectionInfoToString(
570 ConnectionInfo connection_info) {
571 switch (connection_info) {
572 case CONNECTION_INFO_UNKNOWN:
573 return "unknown";
574 case CONNECTION_INFO_HTTP1_1:
575 return "http/1.1";
576 case CONNECTION_INFO_DEPRECATED_SPDY2:
577 NOTREACHED();
578 return "";
579 case CONNECTION_INFO_DEPRECATED_SPDY3:
580 return "spdy/3";
581 // Since ConnectionInfo is persisted to disk, deprecated values have to be
582 // handled. Note that h2-14 and h2-15 are essentially wire compatible with
583 // h2.
584 // Intentional fallthrough.
585 case CONNECTION_INFO_DEPRECATED_HTTP2_14:
586 case CONNECTION_INFO_DEPRECATED_HTTP2_15:
587 case CONNECTION_INFO_HTTP2:
588 return "h2";
589 case CONNECTION_INFO_QUIC_UNKNOWN_VERSION:
590 return "http/2+quic";
591 case CONNECTION_INFO_QUIC_32:
592 return "http/2+quic/32";
593 case CONNECTION_INFO_QUIC_33:
594 return "http/2+quic/33";
595 case CONNECTION_INFO_QUIC_34:
596 return "http/2+quic/34";
597 case CONNECTION_INFO_QUIC_35:
598 return "http/2+quic/35";
599 case CONNECTION_INFO_QUIC_36:
600 return "http/2+quic/36";
601 case CONNECTION_INFO_QUIC_37:
602 return "http/2+quic/37";
603 case CONNECTION_INFO_QUIC_38:
604 return "http/2+quic/38";
605 case CONNECTION_INFO_QUIC_39:
606 return "http/2+quic/39";
607 case CONNECTION_INFO_QUIC_40:
608 return "http/2+quic/40";
609 case CONNECTION_INFO_QUIC_41:
610 return "http/2+quic/41";
611 case CONNECTION_INFO_QUIC_42:
612 return "http/2+quic/42";
613 case CONNECTION_INFO_QUIC_43:
614 return "http/2+quic/43";
615 case CONNECTION_INFO_QUIC_44:
616 return "http/2+quic/44";
617 case CONNECTION_INFO_QUIC_45:
618 return "http/2+quic/45";
619 case CONNECTION_INFO_QUIC_46:
620 return "http/2+quic/46";
621 case CONNECTION_INFO_QUIC_47:
622 return "http/2+quic/47";
623 case CONNECTION_INFO_QUIC_Q048:
624 return "h3-Q048";
625 case CONNECTION_INFO_QUIC_T048:
626 return "h3-T048";
627 case CONNECTION_INFO_QUIC_Q049:
628 return "h3-Q049";
629 case CONNECTION_INFO_QUIC_T049:
630 return "h3-T049";
631 case CONNECTION_INFO_QUIC_Q050:
632 return "h3-Q050";
633 case CONNECTION_INFO_QUIC_T050:
634 return "h3-T050";
635 case CONNECTION_INFO_QUIC_Q099:
636 return "h3-Q099";
637 case CONNECTION_INFO_QUIC_DRAFT_25:
638 return "h3-25";
639 case CONNECTION_INFO_QUIC_DRAFT_27:
640 return "h3-27";
641 case CONNECTION_INFO_QUIC_DRAFT_28:
642 return "h3-28";
643 case CONNECTION_INFO_QUIC_DRAFT_29:
644 return "h3-29";
645 case CONNECTION_INFO_QUIC_T099:
646 return "h3-T099";
647 case CONNECTION_INFO_HTTP0_9:
648 return "http/0.9";
649 case CONNECTION_INFO_HTTP1_0:
650 return "http/1.0";
651 case CONNECTION_INFO_QUIC_999:
652 return "http2+quic/999";
653 case CONNECTION_INFO_QUIC_T051:
654 return "h3-T051";
655 case CONNECTION_INFO_QUIC_RFC_V1:
656 return "h3";
657 case CONNECTION_INFO_DEPRECATED_QUIC_2_DRAFT_1:
658 return "h3/quic2draft01";
659 case CONNECTION_INFO_QUIC_2_DRAFT_8:
660 return "h3/quic2draft08";
661 case NUM_OF_CONNECTION_INFOS:
662 break;
663 }
664 NOTREACHED();
665 return "";
666 }
667
668 } // namespace net
669