http_stream_factory.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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.
4
5#include "net/http/http_stream_factory.h"
6
7#include "base/stl_util-inl.h"
8#include "base/string_number_conversions.h"
9#include "base/string_split.h"
10#include "base/string_util.h"
11#include "net/base/net_log.h"
12#include "net/base/net_util.h"
13#include "net/http/http_network_session.h"
14#include "net/http/http_stream_request.h"
15
16namespace net {
17
18// static
19const HostMappingRules* HttpStreamFactory::host_mapping_rules_ = NULL;
20// static
21const std::string* HttpStreamFactory::next_protos_ = NULL;
22// static
23bool HttpStreamFactory::use_alternate_protocols_ = false;
24// static
25bool HttpStreamFactory::force_spdy_over_ssl_ = true;
26// static
27bool HttpStreamFactory::force_spdy_always_ = false;
28// static
29bool HttpStreamFactory::ignore_certificate_errors_ = false;
30
31// static
32void HttpStreamFactory::SetHostMappingRules(const std::string& rules) {
33  HostMappingRules* host_mapping_rules = new HostMappingRules();
34  host_mapping_rules->SetRulesFromString(rules);
35  delete host_mapping_rules_;
36  host_mapping_rules_ = host_mapping_rules;
37}
38
39HttpStreamFactory::HttpStreamFactory() {
40}
41
42HttpStreamFactory::~HttpStreamFactory() {
43}
44
45void HttpStreamFactory::RequestStream(
46    const HttpRequestInfo* request_info,
47    SSLConfig* ssl_config,
48    ProxyInfo* proxy_info,
49    StreamFactory::StreamRequestDelegate* delegate,
50    const BoundNetLog& net_log,
51    const scoped_refptr<HttpNetworkSession>& session,
52    scoped_refptr<StreamRequestJob>* stream) {
53  DCHECK(stream != NULL);
54  *stream = new HttpStreamRequest(this, session);
55  (*stream)->Start(request_info, ssl_config, proxy_info, delegate, net_log);
56}
57
58void HttpStreamFactory::AddTLSIntolerantServer(const GURL& url) {
59  tls_intolerant_servers_.insert(GetHostAndPort(url));
60}
61
62bool HttpStreamFactory::IsTLSIntolerantServer(const GURL& url) {
63  return ContainsKey(tls_intolerant_servers_, GetHostAndPort(url));
64}
65
66void HttpStreamFactory::ProcessAlternateProtocol(
67    HttpAlternateProtocols* alternate_protocols,
68    const std::string& alternate_protocol_str,
69    const HostPortPair& http_host_port_pair) {
70  std::vector<std::string> port_protocol_vector;
71  SplitString(alternate_protocol_str, ':', &port_protocol_vector);
72  if (port_protocol_vector.size() != 2) {
73    DLOG(WARNING) << HttpAlternateProtocols::kHeader
74                  << " header has too many tokens: "
75                  << alternate_protocol_str;
76    return;
77  }
78
79  int port;
80  if (!base::StringToInt(port_protocol_vector[0], &port) ||
81      port <= 0 || port >= 1 << 16) {
82    DLOG(WARNING) << HttpAlternateProtocols::kHeader
83                  << " header has unrecognizable port: "
84                  << port_protocol_vector[0];
85    return;
86  }
87
88  HttpAlternateProtocols::Protocol protocol = HttpAlternateProtocols::BROKEN;
89  // We skip NPN_SPDY_1 here, because we've rolled the protocol version to 2.
90  for (int i = HttpAlternateProtocols::NPN_SPDY_2;
91       i < HttpAlternateProtocols::NUM_ALTERNATE_PROTOCOLS; ++i) {
92    if (port_protocol_vector[1] == HttpAlternateProtocols::kProtocolStrings[i])
93      protocol = static_cast<HttpAlternateProtocols::Protocol>(i);
94  }
95
96  if (protocol == HttpAlternateProtocols::BROKEN) {
97    // Currently, we only recognize the npn-spdy protocol.
98    DLOG(WARNING) << HttpAlternateProtocols::kHeader
99                  << " header has unrecognized protocol: "
100                  << port_protocol_vector[1];
101    return;
102  }
103
104  HostPortPair host_port(http_host_port_pair);
105  if (host_mapping_rules_)
106    host_mapping_rules_->RewriteHost(&host_port);
107
108  if (alternate_protocols->HasAlternateProtocolFor(host_port)) {
109    const HttpAlternateProtocols::PortProtocolPair existing_alternate =
110        alternate_protocols->GetAlternateProtocolFor(host_port);
111    // If we think the alternate protocol is broken, don't change it.
112    if (existing_alternate.protocol == HttpAlternateProtocols::BROKEN)
113      return;
114  }
115
116  alternate_protocols->SetAlternateProtocolFor(host_port, port, protocol);
117}
118
119GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url,
120                                              HostPortPair* endpoint) {
121  if (host_mapping_rules_ && host_mapping_rules_->RewriteHost(endpoint)) {
122    url_canon::Replacements<char> replacements;
123    const std::string port_str = base::IntToString(endpoint->port());
124    replacements.SetPort(port_str.c_str(),
125                         url_parse::Component(0, port_str.size()));
126    replacements.SetHost(endpoint->host().c_str(),
127                         url_parse::Component(0, endpoint->host().size()));
128    return url.ReplaceComponents(replacements);
129  }
130  return url;
131}
132
133}  // namespace net
134
135