summaryrefslogtreecommitdiff
path: root/chromium/net/http/http_stream_factory.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/http/http_stream_factory.cc')
-rw-r--r--chromium/net/http/http_stream_factory.cc243
1 files changed, 243 insertions, 0 deletions
diff --git a/chromium/net/http/http_stream_factory.cc b/chromium/net/http/http_stream_factory.cc
new file mode 100644
index 00000000000..a55ed075bb5
--- /dev/null
+++ b/chromium/net/http/http_stream_factory.cc
@@ -0,0 +1,243 @@
+// 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_stream_factory.h"
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "net/base/host_mapping_rules.h"
+#include "net/base/host_port_pair.h"
+#include "url/gurl.h"
+
+namespace net {
+
+// WARNING: If you modify or add any static flags, you must keep them in sync
+// with |ResetStaticSettingsToInit|. This is critical for unit test isolation.
+
+// static
+std::vector<std::string>* HttpStreamFactory::next_protos_ = NULL;
+// static
+bool HttpStreamFactory::enabled_protocols_[NUM_ALTERNATE_PROTOCOLS];
+// static
+bool HttpStreamFactory::spdy_enabled_ = true;
+// static
+bool HttpStreamFactory::use_alternate_protocols_ = false;
+// static
+bool HttpStreamFactory::force_spdy_over_ssl_ = true;
+// static
+bool HttpStreamFactory::force_spdy_always_ = false;
+// static
+std::list<HostPortPair>* HttpStreamFactory::forced_spdy_exclusions_ = NULL;
+
+HttpStreamFactory::~HttpStreamFactory() {}
+
+// static
+void HttpStreamFactory::ResetStaticSettingsToInit() {
+ // WARNING: These must match the initializers above.
+ delete next_protos_;
+ delete forced_spdy_exclusions_;
+ next_protos_ = NULL;
+ spdy_enabled_ = true;
+ use_alternate_protocols_ = false;
+ force_spdy_over_ssl_ = true;
+ force_spdy_always_ = false;
+ forced_spdy_exclusions_ = NULL;
+ for (int i = 0; i < NUM_ALTERNATE_PROTOCOLS; ++i)
+ enabled_protocols_[i] = false;
+}
+
+void HttpStreamFactory::ProcessAlternateProtocol(
+ const base::WeakPtr<HttpServerProperties>& http_server_properties,
+ const std::string& alternate_protocol_str,
+ const HostPortPair& http_host_port_pair) {
+ std::vector<std::string> port_protocol_vector;
+ base::SplitString(alternate_protocol_str, ':', &port_protocol_vector);
+ if (port_protocol_vector.size() != 2) {
+ DLOG(WARNING) << kAlternateProtocolHeader
+ << " header has too many tokens: "
+ << alternate_protocol_str;
+ return;
+ }
+
+ int port;
+ if (!base::StringToInt(port_protocol_vector[0], &port) ||
+ port <= 0 || port >= 1 << 16) {
+ DLOG(WARNING) << kAlternateProtocolHeader
+ << " header has unrecognizable port: "
+ << port_protocol_vector[0];
+ return;
+ }
+
+ AlternateProtocol protocol =
+ AlternateProtocolFromString(port_protocol_vector[1]);
+ if (protocol < NUM_ALTERNATE_PROTOCOLS && !enabled_protocols_[protocol])
+ protocol = ALTERNATE_PROTOCOL_BROKEN;
+
+ if (protocol == ALTERNATE_PROTOCOL_BROKEN) {
+ // Currently, we only recognize the npn-spdy protocol.
+ DLOG(WARNING) << kAlternateProtocolHeader
+ << " header has unrecognized protocol: "
+ << port_protocol_vector[1];
+ return;
+ }
+
+ HostPortPair host_port(http_host_port_pair);
+ const HostMappingRules* mapping_rules = GetHostMappingRules();
+ if (mapping_rules)
+ mapping_rules->RewriteHost(&host_port);
+
+ if (http_server_properties->HasAlternateProtocol(host_port)) {
+ const PortAlternateProtocolPair existing_alternate =
+ http_server_properties->GetAlternateProtocol(host_port);
+ // If we think the alternate protocol is broken, don't change it.
+ if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN)
+ return;
+ }
+
+ http_server_properties->SetAlternateProtocol(host_port, port, protocol);
+}
+
+GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url,
+ HostPortPair* endpoint) {
+ const HostMappingRules* mapping_rules = GetHostMappingRules();
+ if (mapping_rules && mapping_rules->RewriteHost(endpoint)) {
+ url_canon::Replacements<char> replacements;
+ const std::string port_str = base::IntToString(endpoint->port());
+ replacements.SetPort(port_str.c_str(),
+ url_parse::Component(0, port_str.size()));
+ replacements.SetHost(endpoint->host().c_str(),
+ url_parse::Component(0, endpoint->host().size()));
+ return url.ReplaceComponents(replacements);
+ }
+ return url;
+}
+
+// static
+void HttpStreamFactory::add_forced_spdy_exclusion(const std::string& value) {
+ HostPortPair pair = HostPortPair::FromURL(GURL(value));
+ if (!forced_spdy_exclusions_)
+ forced_spdy_exclusions_ = new std::list<HostPortPair>();
+ forced_spdy_exclusions_->push_back(pair);
+}
+
+// static
+bool HttpStreamFactory::HasSpdyExclusion(const HostPortPair& endpoint) {
+ std::list<HostPortPair>* exclusions = forced_spdy_exclusions_;
+ if (!exclusions)
+ return false;
+
+ std::list<HostPortPair>::const_iterator it;
+ for (it = exclusions->begin(); it != exclusions->end(); ++it)
+ if (it->Equals(endpoint))
+ return true;
+ return false;
+}
+
+// static
+void HttpStreamFactory::EnableNpnSpdy() {
+ set_use_alternate_protocols(true);
+ std::vector<NextProto> next_protos;
+ next_protos.push_back(kProtoHTTP11);
+ next_protos.push_back(kProtoQUIC1SPDY3);
+ next_protos.push_back(kProtoSPDY2);
+ SetNextProtos(next_protos);
+}
+
+// static
+void HttpStreamFactory::EnableNpnHttpOnly() {
+ // Avoid alternate protocol in this case. Otherwise, browser will try SSL
+ // and then fallback to http. This introduces extra load.
+ set_use_alternate_protocols(false);
+ std::vector<NextProto> next_protos;
+ next_protos.push_back(kProtoHTTP11);
+ SetNextProtos(next_protos);
+}
+
+// static
+void HttpStreamFactory::EnableNpnSpdy3() {
+ set_use_alternate_protocols(true);
+ std::vector<NextProto> next_protos;
+ next_protos.push_back(kProtoHTTP11);
+ next_protos.push_back(kProtoQUIC1SPDY3);
+ next_protos.push_back(kProtoSPDY2);
+ next_protos.push_back(kProtoSPDY3);
+ SetNextProtos(next_protos);
+}
+
+// static
+void HttpStreamFactory::EnableNpnSpdy31() {
+ set_use_alternate_protocols(true);
+ std::vector<NextProto> next_protos;
+ next_protos.push_back(kProtoHTTP11);
+ next_protos.push_back(kProtoQUIC1SPDY3);
+ next_protos.push_back(kProtoSPDY2);
+ next_protos.push_back(kProtoSPDY3);
+ next_protos.push_back(kProtoSPDY31);
+ SetNextProtos(next_protos);
+}
+
+// static
+void HttpStreamFactory::EnableNpnSpdy4a2() {
+ set_use_alternate_protocols(true);
+ std::vector<NextProto> next_protos;
+ next_protos.push_back(kProtoHTTP11);
+ next_protos.push_back(kProtoQUIC1SPDY3);
+ next_protos.push_back(kProtoSPDY2);
+ next_protos.push_back(kProtoSPDY3);
+ next_protos.push_back(kProtoSPDY31);
+ next_protos.push_back(kProtoSPDY4a2);
+ SetNextProtos(next_protos);
+}
+
+// static
+void HttpStreamFactory::EnableNpnHttp2Draft04() {
+ set_use_alternate_protocols(true);
+ std::vector<NextProto> next_protos;
+ next_protos.push_back(kProtoHTTP11);
+ next_protos.push_back(kProtoQUIC1SPDY3);
+ next_protos.push_back(kProtoSPDY2);
+ next_protos.push_back(kProtoSPDY3);
+ next_protos.push_back(kProtoSPDY31);
+ next_protos.push_back(kProtoSPDY4a2);
+ next_protos.push_back(kProtoHTTP2Draft04);
+ SetNextProtos(next_protos);
+}
+
+// static
+void HttpStreamFactory::SetNextProtos(const std::vector<NextProto>& value) {
+ if (!next_protos_)
+ next_protos_ = new std::vector<std::string>;
+
+ next_protos_->clear();
+
+ for (uint32 i = 0; i < NUM_ALTERNATE_PROTOCOLS; ++i)
+ enabled_protocols_[i] = false;
+
+ // TODO(rtenneti): bug 116575 - consider combining the NextProto and
+ // AlternateProtocol.
+ for (uint32 i = 0; i < value.size(); ++i) {
+ NextProto proto = value[i];
+ // Add the protocol to the TLS next protocol list, except for QUIC
+ // since it uses UDP.
+ if (proto != kProtoQUIC1SPDY3) {
+ next_protos_->push_back(SSLClientSocket::NextProtoToString(proto));
+ }
+
+ // Enable the corresponding alternate protocol, except for HTTP
+ // which has not corresponding alternative.
+ if (proto != kProtoHTTP11) {
+ AlternateProtocol alternate = AlternateProtocolFromNextProto(proto);
+ if (alternate == UNINITIALIZED_ALTERNATE_PROTOCOL) {
+ NOTREACHED() << "Invalid next proto: " << proto;
+ continue;
+ }
+ enabled_protocols_[alternate] = true;
+ }
+ }
+}
+
+HttpStreamFactory::HttpStreamFactory() {}
+
+} // namespace net