1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
// 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,
QuicTransportVersionVector());
}
// static
AlternativeServiceInfo AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
const AlternativeService& alternative_service,
base::Time expiration,
const 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 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
|