Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / net / http / http_stream_factory.cc
blob1b6e66fcceff244d49d8624eee9bf32bd205915b
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
3 // found in the LICENSE file.
5 #include "net/http/http_stream_factory.h"
7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/string_split.h"
10 #include "base/strings/string_util.h"
11 #include "base/time/time.h"
12 #include "net/base/host_mapping_rules.h"
13 #include "net/base/host_port_pair.h"
14 #include "net/base/port_util.h"
15 #include "net/http/http_network_session.h"
16 #include "net/spdy/spdy_alt_svc_wire_format.h"
17 #include "url/gurl.h"
19 namespace net {
21 // WARNING: If you modify or add any static flags, you must keep them in sync
22 // with |ResetStaticSettingsToInit|. This is critical for unit test isolation.
24 // static
25 bool HttpStreamFactory::spdy_enabled_ = true;
27 HttpStreamFactory::~HttpStreamFactory() {}
29 // static
30 void HttpStreamFactory::ResetStaticSettingsToInit() {
31 spdy_enabled_ = true;
34 void HttpStreamFactory::ProcessAlternativeService(
35 const base::WeakPtr<HttpServerProperties>& http_server_properties,
36 base::StringPiece alternative_service_str,
37 const HostPortPair& http_host_port_pair,
38 const HttpNetworkSession& session) {
39 SpdyAltSvcWireFormat::AlternativeServiceVector alternative_service_vector;
40 if (!SpdyAltSvcWireFormat::ParseHeaderFieldValue(
41 alternative_service_str, &alternative_service_vector)) {
42 return;
45 // Convert SpdyAltSvcWireFormat::AlternativeService entries
46 // to net::AlternativeServiceInfo.
47 AlternativeServiceInfoVector alternative_service_info_vector;
48 for (const SpdyAltSvcWireFormat::AlternativeService&
49 alternative_service_entry : alternative_service_vector) {
50 AlternateProtocol protocol =
51 AlternateProtocolFromString(alternative_service_entry.protocol_id);
52 if (!IsAlternateProtocolValid(protocol) ||
53 !session.IsProtocolEnabled(protocol) ||
54 !IsPortValid(alternative_service_entry.port)) {
55 continue;
57 AlternativeService alternative_service(protocol,
58 alternative_service_entry.host,
59 alternative_service_entry.port);
60 base::Time expiration =
61 base::Time::Now() +
62 base::TimeDelta::FromSeconds(alternative_service_entry.max_age);
63 AlternativeServiceInfo alternative_service_info(
64 alternative_service, alternative_service_entry.p, expiration);
65 alternative_service_info_vector.push_back(alternative_service_info);
68 http_server_properties->SetAlternativeServices(
69 RewriteHost(http_host_port_pair), alternative_service_info_vector);
72 void HttpStreamFactory::ProcessAlternateProtocol(
73 const base::WeakPtr<HttpServerProperties>& http_server_properties,
74 const std::vector<std::string>& alternate_protocol_values,
75 const HostPortPair& http_host_port_pair,
76 const HttpNetworkSession& session) {
77 AlternateProtocol protocol = UNINITIALIZED_ALTERNATE_PROTOCOL;
78 int port = 0;
79 double probability = 1;
80 bool is_valid = true;
81 for (size_t i = 0; i < alternate_protocol_values.size(); ++i) {
82 base::StringPiece alternate_protocol_str = alternate_protocol_values[i];
83 if (base::StartsWith(alternate_protocol_str, "p=",
84 base::CompareCase::SENSITIVE)) {
85 if (!base::StringToDouble(alternate_protocol_str.substr(2).as_string(),
86 &probability) ||
87 probability < 0 || probability > 1) {
88 DVLOG(1) << kAlternateProtocolHeader
89 << " header has unrecognizable probability: "
90 << alternate_protocol_values[i];
91 is_valid = false;
92 break;
94 continue;
97 std::vector<base::StringPiece> port_protocol_vector =
98 base::SplitStringPiece(alternate_protocol_str, ":",
99 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
100 if (port_protocol_vector.size() != 2) {
101 DVLOG(1) << kAlternateProtocolHeader
102 << " header has too many tokens: "
103 << alternate_protocol_str;
104 is_valid = false;
105 break;
108 if (!base::StringToInt(port_protocol_vector[0], &port) ||
109 port == 0 || !IsPortValid(port)) {
110 DVLOG(1) << kAlternateProtocolHeader
111 << " header has unrecognizable port: "
112 << port_protocol_vector[0];
113 is_valid = false;
114 break;
117 protocol = AlternateProtocolFromString(port_protocol_vector[1].as_string());
119 if (IsAlternateProtocolValid(protocol) &&
120 !session.IsProtocolEnabled(protocol)) {
121 DVLOG(1) << kAlternateProtocolHeader
122 << " header has unrecognized protocol: "
123 << port_protocol_vector[1];
124 is_valid = false;
125 break;
129 if (!is_valid || protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) {
130 http_server_properties->ClearAlternativeServices(http_host_port_pair);
131 return;
134 http_server_properties->SetAlternativeService(
135 RewriteHost(http_host_port_pair),
136 AlternativeService(protocol, "", static_cast<uint16>(port)), probability,
137 base::Time::Now() + base::TimeDelta::FromDays(1));
140 GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url,
141 HostPortPair* endpoint) {
142 const HostMappingRules* mapping_rules = GetHostMappingRules();
143 if (mapping_rules && mapping_rules->RewriteHost(endpoint)) {
144 url::Replacements<char> replacements;
145 const std::string port_str = base::UintToString(endpoint->port());
146 replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size()));
147 replacements.SetHost(endpoint->host().c_str(),
148 url::Component(0, endpoint->host().size()));
149 return url.ReplaceComponents(replacements);
151 return url;
154 HttpStreamFactory::HttpStreamFactory() {}
156 HostPortPair HttpStreamFactory::RewriteHost(HostPortPair host_port_pair) {
157 const HostMappingRules* mapping_rules = GetHostMappingRules();
158 if (mapping_rules)
159 mapping_rules->RewriteHost(&host_port_pair);
160 return host_port_pair;
163 } // namespace net