OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_stream_factory.h" | 5 #include "net/http/http_stream_factory.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/strings/string_split.h" | 9 #include "base/strings/string_split.h" |
10 #include "net/base/host_mapping_rules.h" | 10 #include "net/base/host_mapping_rules.h" |
11 #include "net/base/host_port_pair.h" | 11 #include "net/base/host_port_pair.h" |
| 12 #include "net/http/http_network_session.h" |
12 #include "url/gurl.h" | 13 #include "url/gurl.h" |
13 | 14 |
14 namespace net { | 15 namespace net { |
15 | 16 |
16 // WARNING: If you modify or add any static flags, you must keep them in sync | 17 // WARNING: If you modify or add any static flags, you must keep them in sync |
17 // with |ResetStaticSettingsToInit|. This is critical for unit test isolation. | 18 // with |ResetStaticSettingsToInit|. This is critical for unit test isolation. |
18 | 19 |
19 // static | 20 // static |
20 std::vector<std::string>* HttpStreamFactory::next_protos_ = NULL; | |
21 // static | |
22 bool HttpStreamFactory::enabled_protocols_[NUM_VALID_ALTERNATE_PROTOCOLS]; | |
23 // static | |
24 bool HttpStreamFactory::spdy_enabled_ = true; | 21 bool HttpStreamFactory::spdy_enabled_ = true; |
25 // static | |
26 bool HttpStreamFactory::use_alternate_protocols_ = false; | |
27 // static | |
28 bool HttpStreamFactory::force_spdy_over_ssl_ = true; | |
29 // static | |
30 bool HttpStreamFactory::force_spdy_always_ = false; | |
31 // static | |
32 std::list<HostPortPair>* HttpStreamFactory::forced_spdy_exclusions_ = NULL; | |
33 | 22 |
34 HttpStreamFactory::~HttpStreamFactory() {} | 23 HttpStreamFactory::~HttpStreamFactory() {} |
35 | 24 |
36 // static | 25 // static |
37 bool HttpStreamFactory::IsProtocolEnabled(AlternateProtocol protocol) { | |
38 DCHECK(IsAlternateProtocolValid(protocol)); | |
39 return enabled_protocols_[ | |
40 protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION]; | |
41 } | |
42 | |
43 // static | |
44 void HttpStreamFactory::SetProtocolEnabled(AlternateProtocol protocol) { | |
45 DCHECK(IsAlternateProtocolValid(protocol)); | |
46 enabled_protocols_[ | |
47 protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION] = true; | |
48 } | |
49 | |
50 // static | |
51 void HttpStreamFactory::ResetEnabledProtocols() { | |
52 for (int i = ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION; | |
53 i <= ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION; ++i) { | |
54 enabled_protocols_[i - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION] = false; | |
55 } | |
56 } | |
57 | |
58 // static | |
59 void HttpStreamFactory::ResetStaticSettingsToInit() { | 26 void HttpStreamFactory::ResetStaticSettingsToInit() { |
60 // WARNING: These must match the initializers above. | |
61 delete next_protos_; | |
62 delete forced_spdy_exclusions_; | |
63 next_protos_ = NULL; | |
64 spdy_enabled_ = true; | 27 spdy_enabled_ = true; |
65 use_alternate_protocols_ = false; | |
66 force_spdy_over_ssl_ = true; | |
67 force_spdy_always_ = false; | |
68 forced_spdy_exclusions_ = NULL; | |
69 ResetEnabledProtocols(); | |
70 } | 28 } |
71 | 29 |
72 void HttpStreamFactory::ProcessAlternateProtocol( | 30 void HttpStreamFactory::ProcessAlternateProtocol( |
73 const base::WeakPtr<HttpServerProperties>& http_server_properties, | 31 const base::WeakPtr<HttpServerProperties>& http_server_properties, |
74 const std::string& alternate_protocol_str, | 32 const std::string& alternate_protocol_str, |
75 const HostPortPair& http_host_port_pair) { | 33 const HostPortPair& http_host_port_pair, |
| 34 const HttpNetworkSession& session) { |
76 std::vector<std::string> port_protocol_vector; | 35 std::vector<std::string> port_protocol_vector; |
77 base::SplitString(alternate_protocol_str, ':', &port_protocol_vector); | 36 base::SplitString(alternate_protocol_str, ':', &port_protocol_vector); |
78 if (port_protocol_vector.size() != 2) { | 37 if (port_protocol_vector.size() != 2) { |
79 DVLOG(1) << kAlternateProtocolHeader | 38 DVLOG(1) << kAlternateProtocolHeader |
80 << " header has too many tokens: " | 39 << " header has too many tokens: " |
81 << alternate_protocol_str; | 40 << alternate_protocol_str; |
82 return; | 41 return; |
83 } | 42 } |
84 | 43 |
85 int port; | 44 int port; |
86 if (!base::StringToInt(port_protocol_vector[0], &port) || | 45 if (!base::StringToInt(port_protocol_vector[0], &port) || |
87 port <= 0 || port >= 1 << 16) { | 46 port <= 0 || port >= 1 << 16) { |
88 DVLOG(1) << kAlternateProtocolHeader | 47 DVLOG(1) << kAlternateProtocolHeader |
89 << " header has unrecognizable port: " | 48 << " header has unrecognizable port: " |
90 << port_protocol_vector[0]; | 49 << port_protocol_vector[0]; |
91 return; | 50 return; |
92 } | 51 } |
93 | 52 |
94 AlternateProtocol protocol = | 53 AlternateProtocol protocol = |
95 AlternateProtocolFromString(port_protocol_vector[1]); | 54 AlternateProtocolFromString(port_protocol_vector[1]); |
96 if (IsAlternateProtocolValid(protocol) && !IsProtocolEnabled(protocol)) { | 55 if (IsAlternateProtocolValid(protocol) && |
| 56 !session.IsProtocolEnabled(protocol)) { |
97 protocol = ALTERNATE_PROTOCOL_BROKEN; | 57 protocol = ALTERNATE_PROTOCOL_BROKEN; |
98 } | 58 } |
99 | 59 |
100 if (protocol == ALTERNATE_PROTOCOL_BROKEN) { | 60 if (protocol == ALTERNATE_PROTOCOL_BROKEN) { |
101 DVLOG(1) << kAlternateProtocolHeader | 61 DVLOG(1) << kAlternateProtocolHeader |
102 << " header has unrecognized protocol: " | 62 << " header has unrecognized protocol: " |
103 << port_protocol_vector[1]; | 63 << port_protocol_vector[1]; |
104 return; | 64 return; |
105 } | 65 } |
106 | 66 |
(...skipping 20 matching lines...) Expand all Loading... |
127 url::Replacements<char> replacements; | 87 url::Replacements<char> replacements; |
128 const std::string port_str = base::IntToString(endpoint->port()); | 88 const std::string port_str = base::IntToString(endpoint->port()); |
129 replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); | 89 replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); |
130 replacements.SetHost(endpoint->host().c_str(), | 90 replacements.SetHost(endpoint->host().c_str(), |
131 url::Component(0, endpoint->host().size())); | 91 url::Component(0, endpoint->host().size())); |
132 return url.ReplaceComponents(replacements); | 92 return url.ReplaceComponents(replacements); |
133 } | 93 } |
134 return url; | 94 return url; |
135 } | 95 } |
136 | 96 |
137 // static | |
138 void HttpStreamFactory::add_forced_spdy_exclusion(const std::string& value) { | |
139 HostPortPair pair = HostPortPair::FromURL(GURL(value)); | |
140 if (!forced_spdy_exclusions_) | |
141 forced_spdy_exclusions_ = new std::list<HostPortPair>(); | |
142 forced_spdy_exclusions_->push_back(pair); | |
143 } | |
144 | |
145 // static | |
146 bool HttpStreamFactory::HasSpdyExclusion(const HostPortPair& endpoint) { | |
147 std::list<HostPortPair>* exclusions = forced_spdy_exclusions_; | |
148 if (!exclusions) | |
149 return false; | |
150 | |
151 std::list<HostPortPair>::const_iterator it; | |
152 for (it = exclusions->begin(); it != exclusions->end(); ++it) | |
153 if (it->Equals(endpoint)) | |
154 return true; | |
155 return false; | |
156 } | |
157 | |
158 // static | |
159 void HttpStreamFactory::EnableNpnHttpOnly() { | |
160 // Avoid alternate protocol in this case. Otherwise, browser will try SSL | |
161 // and then fallback to http. This introduces extra load. | |
162 set_use_alternate_protocols(false); | |
163 std::vector<NextProto> next_protos; | |
164 next_protos.push_back(kProtoHTTP11); | |
165 SetNextProtos(next_protos); | |
166 } | |
167 | |
168 // static | |
169 void HttpStreamFactory::EnableNpnSpdy3() { | |
170 set_use_alternate_protocols(true); | |
171 std::vector<NextProto> next_protos; | |
172 next_protos.push_back(kProtoHTTP11); | |
173 next_protos.push_back(kProtoQUIC1SPDY3); | |
174 next_protos.push_back(kProtoSPDY3); | |
175 SetNextProtos(next_protos); | |
176 } | |
177 | |
178 // static | |
179 void HttpStreamFactory::EnableNpnSpdy31() { | |
180 set_use_alternate_protocols(true); | |
181 std::vector<NextProto> next_protos; | |
182 next_protos.push_back(kProtoHTTP11); | |
183 next_protos.push_back(kProtoQUIC1SPDY3); | |
184 next_protos.push_back(kProtoSPDY3); | |
185 next_protos.push_back(kProtoSPDY31); | |
186 SetNextProtos(next_protos); | |
187 } | |
188 | |
189 // static | |
190 void HttpStreamFactory::EnableNpnSpdy31WithSpdy2() { | |
191 set_use_alternate_protocols(true); | |
192 std::vector<NextProto> next_protos; | |
193 next_protos.push_back(kProtoHTTP11); | |
194 next_protos.push_back(kProtoQUIC1SPDY3); | |
195 next_protos.push_back(kProtoDeprecatedSPDY2); | |
196 next_protos.push_back(kProtoSPDY3); | |
197 next_protos.push_back(kProtoSPDY31); | |
198 SetNextProtos(next_protos); | |
199 } | |
200 | |
201 // static | |
202 void HttpStreamFactory::EnableNpnSpdy4Http2() { | |
203 set_use_alternate_protocols(true); | |
204 std::vector<NextProto> next_protos; | |
205 next_protos.push_back(kProtoHTTP11); | |
206 next_protos.push_back(kProtoQUIC1SPDY3); | |
207 next_protos.push_back(kProtoSPDY3); | |
208 next_protos.push_back(kProtoSPDY31); | |
209 next_protos.push_back(kProtoSPDY4); | |
210 SetNextProtos(next_protos); | |
211 } | |
212 | |
213 // static | |
214 void HttpStreamFactory::SetNextProtos(const std::vector<NextProto>& value) { | |
215 if (!next_protos_) | |
216 next_protos_ = new std::vector<std::string>; | |
217 | |
218 next_protos_->clear(); | |
219 | |
220 ResetEnabledProtocols(); | |
221 | |
222 // TODO(rtenneti): bug 116575 - consider combining the NextProto and | |
223 // AlternateProtocol. | |
224 for (uint32 i = 0; i < value.size(); ++i) { | |
225 NextProto proto = value[i]; | |
226 // Add the protocol to the TLS next protocol list, except for QUIC | |
227 // since it uses UDP. | |
228 if (proto != kProtoQUIC1SPDY3) { | |
229 next_protos_->push_back(SSLClientSocket::NextProtoToString(proto)); | |
230 } | |
231 | |
232 // Enable the corresponding alternate protocol, except for HTTP | |
233 // which has not corresponding alternative. | |
234 if (proto != kProtoHTTP11) { | |
235 AlternateProtocol alternate = AlternateProtocolFromNextProto(proto); | |
236 if (!IsAlternateProtocolValid(alternate)) { | |
237 NOTREACHED() << "Invalid next proto: " << proto; | |
238 continue; | |
239 } | |
240 SetProtocolEnabled(alternate); | |
241 } | |
242 } | |
243 } | |
244 | |
245 HttpStreamFactory::HttpStreamFactory() {} | 97 HttpStreamFactory::HttpStreamFactory() {} |
246 | 98 |
247 } // namespace net | 99 } // namespace net |
OLD | NEW |