1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/http/http_stream_factory.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/logging.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/string_number_conversions.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/string_split.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/string_util.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/host_mapping_rules.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/host_port_pair.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/http/http_network_session.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "url/gurl.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace net {
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// WARNING: If you modify or add any static flags, you must keep them in sync
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// with |ResetStaticSettingsToInit|. This is critical for unit test isolation.
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool HttpStreamFactory::spdy_enabled_ = true;
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
24116680a4aac90f2aa7413d9095a592090648e557Ben MurdochHttpStreamFactory::~HttpStreamFactory() {}
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpStreamFactory::ResetStaticSettingsToInit() {
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  spdy_enabled_ = true;
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpStreamFactory::ProcessAlternateProtocol(
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::WeakPtr<HttpServerProperties>& http_server_properties,
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::vector<std::string>& alternate_protocol_values,
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const HostPortPair& http_host_port_pair,
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const HttpNetworkSession& session) {
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AlternateProtocol protocol = UNINITIALIZED_ALTERNATE_PROTOCOL;
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int port = 0;
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  double probability = 1;
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (size_t i = 0; i < alternate_protocol_values.size(); ++i) {
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& alternate_protocol_str = alternate_protocol_values[i];
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (StartsWithASCII(alternate_protocol_str, "p=", true)) {
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (!base::StringToDouble(alternate_protocol_str.substr(2),
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                &probability) ||
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          probability < 0 || probability > 1) {
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        DVLOG(1) << kAlternateProtocolHeader
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 << " header has unrecognizable probability: "
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 << alternate_protocol_values[i];
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        return;
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      continue;
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::vector<std::string> port_protocol_vector;
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::SplitString(alternate_protocol_str, ':', &port_protocol_vector);
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (port_protocol_vector.size() != 2) {
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DVLOG(1) << kAlternateProtocolHeader
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               << " header has too many tokens: "
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               << alternate_protocol_str;
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!base::StringToInt(port_protocol_vector[0], &port) ||
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        port <= 0 || port >= 1 << 16) {
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DVLOG(1) << kAlternateProtocolHeader
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               << " header has unrecognizable port: "
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               << port_protocol_vector[0];
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    protocol =
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        AlternateProtocolFromString(port_protocol_vector[1]);
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (IsAlternateProtocolValid(protocol) &&
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        !session.IsProtocolEnabled(protocol)) {
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      protocol = ALTERNATE_PROTOCOL_BROKEN;
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (protocol == ALTERNATE_PROTOCOL_BROKEN) {
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DVLOG(1) << kAlternateProtocolHeader
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               << " header has unrecognized protocol: "
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               << port_protocol_vector[1];
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (protocol == UNINITIALIZED_ALTERNATE_PROTOCOL)
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  HostPortPair host_port(http_host_port_pair);
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const HostMappingRules* mapping_rules = GetHostMappingRules();
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (mapping_rules)
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    mapping_rules->RewriteHost(&host_port);
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (http_server_properties->HasAlternateProtocol(host_port)) {
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const AlternateProtocolInfo existing_alternate =
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        http_server_properties->GetAlternateProtocol(host_port);
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // If we think the alternate protocol is broken, don't change it.
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN)
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  http_server_properties->SetAlternateProtocol(host_port, port, protocol,
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                               probability);
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
105116680a4aac90f2aa7413d9095a592090648e557Ben MurdochGURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url,
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              HostPortPair* endpoint) {
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const HostMappingRules* mapping_rules = GetHostMappingRules();
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (mapping_rules && mapping_rules->RewriteHost(endpoint)) {
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    url::Replacements<char> replacements;
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string port_str = base::IntToString(endpoint->port());
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size()));
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    replacements.SetHost(endpoint->host().c_str(),
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         url::Component(0, endpoint->host().size()));
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return url.ReplaceComponents(replacements);
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return url;
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
119116680a4aac90f2aa7413d9095a592090648e557Ben MurdochHttpStreamFactory::HttpStreamFactory() {}
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace net
122