15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_info.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h"
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/cert/signed_certificate_timestamp.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_certificate.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)X509Certificate::PickleType GetPickleTypeForVersion(int version) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (version) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 1:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return X509Certificate::PICKLETYPE_SINGLE_CERTIFICATE;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 2:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V2;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 3:
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These values can be bit-wise combined to form the flags field of the
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// serialized HttpResponseInfo.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The version of the response info used when persisting response info.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_VERSION = 3,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The minimum version supported for deserializing response info.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_MINIMUM_VERSION = 1,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We reserve up to 8 bits for the version number.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_VERSION_MASK = 0xFF,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the response info has a cert at the end.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Version 1 serialized only the end-entity certificate, while subsequent
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // versions include the available certificate chain.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_HAS_CERT = 1 << 8,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the response info has a security-bits field (security
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // strength, in bits, of the SSL connection) at the end.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_HAS_SECURITY_BITS = 1 << 9,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the response info has a cert status at the end.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_HAS_CERT_STATUS = 1 << 10,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the response info has vary header data.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_HAS_VARY_DATA = 1 << 11,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the request was cancelled before completion.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_TRUNCATED = 1 << 12,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the response was received via SPDY.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_WAS_SPDY = 1 << 13,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the request has NPN negotiated.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_WAS_NPN = 1 << 14,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the request was fetched via an explicit proxy.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_WAS_PROXY = 1 << 15,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the response info has an SSL connection status field.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This contains the ciphersuite used to fetch the resource as well as the
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol version, compression method and whether SSLv3 fallback was used.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS = 1 << 16,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This bit is set if the response info has protocol version.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RESPONSE_INFO_HAS_NPN_NEGOTIATED_PROTOCOL = 1 << 17,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This bit is set if the response info has connection info.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RESPONSE_INFO_HAS_CONNECTION_INFO = 1 << 18,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This bit is set if the request has http authentication.
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RESPONSE_INFO_USE_HTTP_AUTHENTICATION = 1 << 19,
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This bit is set if ssl_info has SCTs.
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS = 1 << 20,
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): Add other bits to indicate alternate request methods.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For now, we don't support storing those.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfo::HttpResponseInfo()
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : was_cached(false),
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      server_data_unavailable(false),
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      network_accessed(false),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_fetched_via_spdy(false),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_npn_negotiated(false),
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      was_fetched_via_proxy(false),
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      did_use_http_auth(false),
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      connection_info(CONNECTION_INFO_UNKNOWN) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfo::HttpResponseInfo(const HttpResponseInfo& rhs)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : was_cached(rhs.was_cached),
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      server_data_unavailable(rhs.server_data_unavailable),
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      network_accessed(rhs.network_accessed),
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_fetched_via_spdy(rhs.was_fetched_via_spdy),
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_npn_negotiated(rhs.was_npn_negotiated),
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_fetched_via_proxy(rhs.was_fetched_via_proxy),
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      proxy_server(rhs.proxy_server),
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      did_use_http_auth(rhs.did_use_http_auth),
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socket_address(rhs.socket_address),
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      npn_negotiated_protocol(rhs.npn_negotiated_protocol),
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      connection_info(rhs.connection_info),
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_time(rhs.request_time),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_time(rhs.response_time),
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_challenge(rhs.auth_challenge),
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cert_request_info(rhs.cert_request_info),
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_info(rhs.ssl_info),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      headers(rhs.headers),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      vary_data(rhs.vary_data),
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      metadata(rhs.metadata) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfo::~HttpResponseInfo() {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfo& HttpResponseInfo::operator=(const HttpResponseInfo& rhs) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_cached = rhs.was_cached;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  server_data_unavailable = rhs.server_data_unavailable;
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  network_accessed = rhs.network_accessed;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_fetched_via_spdy = rhs.was_fetched_via_spdy;
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  proxy_server = rhs.proxy_server;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_npn_negotiated = rhs.was_npn_negotiated;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_fetched_via_proxy = rhs.was_fetched_via_proxy;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  did_use_http_auth = rhs.did_use_http_auth;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_address = rhs.socket_address;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  npn_negotiated_protocol = rhs.npn_negotiated_protocol;
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  connection_info = rhs.connection_info;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_time = rhs.request_time;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_time = rhs.response_time;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_challenge = rhs.auth_challenge;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cert_request_info = rhs.cert_request_info;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_info = rhs.ssl_info;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers = rhs.headers;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vary_data = rhs.vary_data;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metadata = rhs.metadata;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *this;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpResponseInfo::InitFromPickle(const Pickle& pickle,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      bool* response_truncated) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PickleIterator iter(pickle);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Read flags and verify version
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pickle.ReadInt(&iter, &flags))
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int version = flags & RESPONSE_INFO_VERSION_MASK;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (version < RESPONSE_INFO_MINIMUM_VERSION ||
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      version > RESPONSE_INFO_VERSION) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "unexpected response info version: " << version;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Read request-time
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 time_val;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pickle.ReadInt64(&iter, &time_val))
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_time = Time::FromInternalValue(time_val);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_cached = true;  // Set status to show cache resurrection.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Read response-time
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pickle.ReadInt64(&iter, &time_val))
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_time = Time::FromInternalValue(time_val);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Read response-headers
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers = new HttpResponseHeaders(pickle, &iter);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (headers->response_code() == -1)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Read ssl-info
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & RESPONSE_INFO_HAS_CERT) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    X509Certificate::PickleType type = GetPickleTypeForVersion(version);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_info.cert = X509Certificate::CreateFromPickle(pickle, &iter, type);
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!ssl_info.cert.get())
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & RESPONSE_INFO_HAS_CERT_STATUS) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertStatus cert_status;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pickle.ReadUInt32(&iter, &cert_status))
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_info.cert_status = cert_status;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & RESPONSE_INFO_HAS_SECURITY_BITS) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int security_bits;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pickle.ReadInt(&iter, &security_bits))
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_info.security_bits = security_bits;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int connection_status;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pickle.ReadInt(&iter, &connection_status))
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_info.connection_status = connection_status;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (flags & RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS) {
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int num_scts;
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!pickle.ReadInt(&iter, &num_scts))
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return false;
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    for (int i = 0; i < num_scts; ++i) {
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      scoped_refptr<ct::SignedCertificateTimestamp> sct(
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          ct::SignedCertificateTimestamp::CreateFromPickle(&iter));
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      uint16 status;
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (!sct.get() || !pickle.ReadUInt16(&iter, &status))
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        return false;
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ssl_info.signed_certificate_timestamps.push_back(
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          SignedCertificateTimestampAndStatus(
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              sct, static_cast<ct::SCTVerifyStatus>(status)));
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Read vary-data
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & RESPONSE_INFO_HAS_VARY_DATA) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!vary_data.InitFromPickle(pickle, &iter))
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read socket_address.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string socket_address_host;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pickle.ReadString(&iter, &socket_address_host)) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the host was written, we always expect the port to follow.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint16 socket_address_port;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pickle.ReadUInt16(&iter, &socket_address_port))
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_address = HostPortPair(socket_address_host, socket_address_port);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (version > 1) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // socket_address was not always present in version 1 of the response
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // info, so we don't fail if it can't be read.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Read protocol-version.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & RESPONSE_INFO_HAS_NPN_NEGOTIATED_PROTOCOL) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pickle.ReadString(&iter, &npn_negotiated_protocol))
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Read connection info.
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (flags & RESPONSE_INFO_HAS_CONNECTION_INFO) {
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int value;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!pickle.ReadInt(&iter, &value))
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value > static_cast<int>(CONNECTION_INFO_UNKNOWN) &&
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        value < static_cast<int>(NUM_OF_CONNECTION_INFOS)) {
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      connection_info = static_cast<ConnectionInfo>(value);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_fetched_via_spdy = (flags & RESPONSE_INFO_WAS_SPDY) != 0;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_npn_negotiated = (flags & RESPONSE_INFO_WAS_NPN) != 0;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_fetched_via_proxy = (flags & RESPONSE_INFO_WAS_PROXY) != 0;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *response_truncated = (flags & RESPONSE_INFO_TRUNCATED) != 0;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  did_use_http_auth = (flags & RESPONSE_INFO_USE_HTTP_AUTHENTICATION) != 0;
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpResponseInfo::Persist(Pickle* pickle,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               bool skip_transient_headers,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               bool response_truncated) const {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags = RESPONSE_INFO_VERSION;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ssl_info.is_valid()) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= RESPONSE_INFO_HAS_CERT;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= RESPONSE_INFO_HAS_CERT_STATUS;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_info.security_bits != -1)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      flags |= RESPONSE_INFO_HAS_SECURITY_BITS;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_info.connection_status != 0)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      flags |= RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (vary_data.is_valid())
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= RESPONSE_INFO_HAS_VARY_DATA;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_truncated)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= RESPONSE_INFO_TRUNCATED;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_fetched_via_spdy)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= RESPONSE_INFO_WAS_SPDY;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_npn_negotiated) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= RESPONSE_INFO_WAS_NPN;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= RESPONSE_INFO_HAS_NPN_NEGOTIATED_PROTOCOL;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_fetched_via_proxy)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= RESPONSE_INFO_WAS_PROXY;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (connection_info != CONNECTION_INFO_UNKNOWN)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    flags |= RESPONSE_INFO_HAS_CONNECTION_INFO;
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (did_use_http_auth)
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    flags |= RESPONSE_INFO_USE_HTTP_AUTHENTICATION;
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!ssl_info.signed_certificate_timestamps.empty())
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    flags |= RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pickle->WriteInt(flags);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pickle->WriteInt64(request_time.ToInternalValue());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pickle->WriteInt64(response_time.ToInternalValue());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpResponseHeaders::PersistOptions persist_options =
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpResponseHeaders::PERSIST_RAW;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (skip_transient_headers) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    persist_options =
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::HttpResponseHeaders::PERSIST_SANS_COOKIES |
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::HttpResponseHeaders::PERSIST_SANS_CHALLENGES |
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP |
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE |
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::HttpResponseHeaders::PERSIST_SANS_RANGES |
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::HttpResponseHeaders::PERSIST_SANS_SECURITY_STATE;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers->Persist(pickle, persist_options);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ssl_info.is_valid()) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_info.cert->Persist(pickle);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pickle->WriteUInt32(ssl_info.cert_status);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_info.security_bits != -1)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pickle->WriteInt(ssl_info.security_bits);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_info.connection_status != 0)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pickle->WriteInt(ssl_info.connection_status);
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!ssl_info.signed_certificate_timestamps.empty()) {
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      pickle->WriteInt(ssl_info.signed_certificate_timestamps.size());
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      for (SignedCertificateTimestampAndStatusList::const_iterator it =
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)           ssl_info.signed_certificate_timestamps.begin(); it !=
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)           ssl_info.signed_certificate_timestamps.end(); ++it) {
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        it->sct->Persist(pickle);
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        pickle->WriteUInt16(it->status);
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (vary_data.is_valid())
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vary_data.Persist(pickle);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pickle->WriteString(socket_address.host());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pickle->WriteUInt16(socket_address.port());
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_npn_negotiated)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pickle->WriteString(npn_negotiated_protocol);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (connection_info != CONNECTION_INFO_UNKNOWN)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pickle->WriteInt(static_cast<int>(connection_info));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
364558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochHttpResponseInfo::ConnectionInfo HttpResponseInfo::ConnectionInfoFromNextProto(
365558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    NextProto next_proto) {
366558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  switch (next_proto) {
3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case kProtoDeprecatedSPDY2:
3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return CONNECTION_INFO_DEPRECATED_SPDY2;
369558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    case kProtoSPDY3:
370558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    case kProtoSPDY31:
371558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return CONNECTION_INFO_SPDY3;
372a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    case kProtoSPDY4:
373a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      return CONNECTION_INFO_SPDY4;
374558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    case kProtoQUIC1SPDY3:
375558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return CONNECTION_INFO_QUIC1_SPDY3;
376558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
377558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    case kProtoUnknown:
378558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    case kProtoHTTP11:
379558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      break;
380558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
381558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
382558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  NOTREACHED();
383558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return CONNECTION_INFO_UNKNOWN;
384558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
385558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::string HttpResponseInfo::ConnectionInfoToString(
388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ConnectionInfo connection_info) {
389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (connection_info) {
390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case CONNECTION_INFO_UNKNOWN:
391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return "unknown";
392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case CONNECTION_INFO_HTTP1:
393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return "http/1";
3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case CONNECTION_INFO_DEPRECATED_SPDY2:
395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return "spdy/2";
396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case CONNECTION_INFO_SPDY3:
397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return "spdy/3";
398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    case CONNECTION_INFO_SPDY4:
39903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // This is the HTTP/2 draft 14 identifier. For internal
400a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      // consistency, HTTP/2 is named SPDY4 within Chromium.
40103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return "h2-14";
402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case CONNECTION_INFO_QUIC1_SPDY3:
403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return "quic/1+spdy/3";
404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case NUM_OF_CONNECTION_INFOS:
405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return "";
409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
412