| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/http/http_server_properties.h" |
| |
| #include "base/logging.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "base/strings/stringprintf.h" |
| #include "net/http/http_network_session.h" |
| #include "net/socket/ssl_client_socket.h" |
| #include "net/ssl/ssl_config.h" |
| |
| namespace net { |
| |
| namespace { |
| |
| enum AlternativeProxyUsage { |
| // Alternative Proxy was used without racing a normal connection. |
| ALTERNATIVE_PROXY_USAGE_NO_RACE = 0, |
| // Alternative Proxy was used by winning a race with a normal connection. |
| ALTERNATIVE_PROXY_USAGE_WON_RACE = 1, |
| // Alternative Proxy was not used by losing a race with a normal connection. |
| ALTERNATIVE_PROXY_USAGE_LOST_RACE = 2, |
| // Maximum value for the enum. |
| ALTERNATIVE_PROXY_USAGE_MAX, |
| }; |
| |
| AlternativeProxyUsage ConvertProtocolUsageToProxyUsage( |
| AlternateProtocolUsage usage) { |
| switch (usage) { |
| case ALTERNATE_PROTOCOL_USAGE_NO_RACE: |
| return ALTERNATIVE_PROXY_USAGE_NO_RACE; |
| case ALTERNATE_PROTOCOL_USAGE_WON_RACE: |
| return ALTERNATIVE_PROXY_USAGE_WON_RACE; |
| case ALTERNATE_PROTOCOL_USAGE_LOST_RACE: |
| return ALTERNATIVE_PROXY_USAGE_LOST_RACE; |
| default: |
| NOTREACHED(); |
| return ALTERNATIVE_PROXY_USAGE_MAX; |
| } |
| } |
| |
| } // anonymous namespace |
| |
| const char kAlternativeServiceHeader[] = "Alt-Svc"; |
| |
| void HistogramAlternateProtocolUsage(AlternateProtocolUsage usage, |
| bool proxy_server_used) { |
| if (proxy_server_used) { |
| DCHECK_LE(usage, ALTERNATE_PROTOCOL_USAGE_LOST_RACE); |
| UMA_HISTOGRAM_ENUMERATION("Net.QuicAlternativeProxy.Usage", |
| ConvertProtocolUsageToProxyUsage(usage), |
| ALTERNATIVE_PROXY_USAGE_MAX); |
| } else { |
| UMA_HISTOGRAM_ENUMERATION("Net.AlternateProtocolUsage", usage, |
| ALTERNATE_PROTOCOL_USAGE_MAX); |
| } |
| } |
| |
| void HistogramBrokenAlternateProtocolLocation( |
| BrokenAlternateProtocolLocation location){ |
| UMA_HISTOGRAM_ENUMERATION("Net.AlternateProtocolBrokenLocation", location, |
| BROKEN_ALTERNATE_PROTOCOL_LOCATION_MAX); |
| } |
| |
| bool IsAlternateProtocolValid(NextProto protocol) { |
| switch (protocol) { |
| case kProtoUnknown: |
| return false; |
| case kProtoHTTP11: |
| return false; |
| case kProtoHTTP2: |
| return true; |
| case kProtoQUIC: |
| return true; |
| } |
| NOTREACHED(); |
| return false; |
| } |
| |
| // static |
| AlternativeServiceInfo |
| AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo( |
| const AlternativeService& alternative_service, |
| base::Time expiration) { |
| DCHECK_EQ(alternative_service.protocol, kProtoHTTP2); |
| return AlternativeServiceInfo(alternative_service, expiration, |
| quic::QuicTransportVersionVector()); |
| } |
| |
| // static |
| AlternativeServiceInfo AlternativeServiceInfo::CreateQuicAlternativeServiceInfo( |
| const AlternativeService& alternative_service, |
| base::Time expiration, |
| const quic::QuicTransportVersionVector& advertised_versions) { |
| DCHECK_EQ(alternative_service.protocol, kProtoQUIC); |
| return AlternativeServiceInfo(alternative_service, expiration, |
| advertised_versions); |
| } |
| |
| AlternativeServiceInfo::AlternativeServiceInfo() : alternative_service_() {} |
| |
| AlternativeServiceInfo::~AlternativeServiceInfo() = default; |
| |
| AlternativeServiceInfo::AlternativeServiceInfo( |
| const AlternativeService& alternative_service, |
| base::Time expiration, |
| const quic::QuicTransportVersionVector& advertised_versions) |
| : alternative_service_(alternative_service), expiration_(expiration) { |
| if (alternative_service_.protocol == kProtoQUIC) { |
| advertised_versions_ = advertised_versions; |
| std::sort(advertised_versions_.begin(), advertised_versions_.end()); |
| } |
| } |
| |
| AlternativeServiceInfo::AlternativeServiceInfo( |
| const AlternativeServiceInfo& alternative_service_info) = default; |
| |
| AlternativeServiceInfo& AlternativeServiceInfo::operator=( |
| const AlternativeServiceInfo& alternative_service_info) = default; |
| |
| std::string AlternativeService::ToString() const { |
| return base::StringPrintf("%s %s:%d", NextProtoToString(protocol), |
| host.c_str(), port); |
| } |
| |
| std::string AlternativeServiceInfo::ToString() const { |
| base::Time::Exploded exploded; |
| expiration_.LocalExplode(&exploded); |
| return base::StringPrintf( |
| "%s, expires %04d-%02d-%02d %02d:%02d:%02d", |
| alternative_service_.ToString().c_str(), exploded.year, exploded.month, |
| exploded.day_of_month, exploded.hour, exploded.minute, exploded.second); |
| } |
| |
| std::ostream& operator<<(std::ostream& os, |
| const AlternativeService& alternative_service) { |
| os << alternative_service.ToString(); |
| return os; |
| } |
| |
| // static |
| void HttpServerProperties::ForceHTTP11(SSLConfig* ssl_config) { |
| ssl_config->alpn_protos.clear(); |
| ssl_config->alpn_protos.push_back(kProtoHTTP11); |
| } |
| |
| } // namespace net |