blob: e979ad07402a5f2cef6a0c519496a7b11f04b161 [file] [log] [blame]
[email protected]fa55e192010-02-15 14:25:501// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
5#include "net/http/http_network_layer.h"
6
[email protected]0dfc81b2008-08-25 03:44:407#include "base/logging.h"
[email protected]d93d8332011-01-08 04:21:088#include "base/string_number_conversions.h"
[email protected]4e5ae20f2010-09-24 04:52:119#include "base/string_split.h"
[email protected]85c0ed82009-12-15 23:14:1410#include "base/string_util.h"
initial.commit586acc5fe2008-07-26 22:42:5211#include "net/http/http_network_session.h"
12#include "net/http/http_network_transaction.h"
[email protected]dab9c7d2010-02-06 21:44:3213#include "net/spdy/spdy_framer.h"
[email protected]dab9c7d2010-02-06 21:44:3214#include "net/spdy/spdy_session.h"
[email protected]ea1cc2cd2011-02-22 16:47:3815#include "net/spdy/spdy_session_pool.h"
initial.commit586acc5fe2008-07-26 22:42:5216
17namespace net {
18
19//-----------------------------------------------------------------------------
[email protected]e7f29642009-03-02 22:53:1820HttpNetworkLayer::HttpNetworkLayer(HttpNetworkSession* session)
[email protected]57cb0f72011-01-28 06:33:5821 : session_(session),
[email protected]c6894572009-06-16 17:10:1022 suspended_(false) {
[email protected]e7f29642009-03-02 22:53:1823 DCHECK(session_.get());
24}
25
initial.commit586acc5fe2008-07-26 22:42:5226HttpNetworkLayer::~HttpNetworkLayer() {
27}
28
[email protected]d100e44f2011-01-26 22:47:1129//-----------------------------------------------------------------------------
initial.commit586acc5fe2008-07-26 22:42:5230
[email protected]d100e44f2011-01-26 22:47:1131// static
32HttpTransactionFactory* HttpNetworkLayer::CreateFactory(
[email protected]d100e44f2011-01-26 22:47:1133 HttpNetworkSession* session) {
34 DCHECK(session);
initial.commit586acc5fe2008-07-26 22:42:5235
[email protected]d100e44f2011-01-26 22:47:1136 return new HttpNetworkLayer(session);
[email protected]e7f29642009-03-02 22:53:1837}
38
[email protected]7adaccb2009-10-13 04:43:2139// static
[email protected]955fc2e72010-02-08 20:37:3040void HttpNetworkLayer::EnableSpdy(const std::string& mode) {
[email protected]1f418ee2010-10-16 19:46:5641 static const char kOff[] = "off";
[email protected]9e9e842e2010-07-23 23:09:1542 static const char kSSL[] = "ssl";
[email protected]85c0ed82009-12-15 23:14:1443 static const char kDisableSSL[] = "no-ssl";
[email protected]d93d8332011-01-08 04:21:0844 static const char kExclude[] = "exclude"; // Hosts to exclude
[email protected]85c0ed82009-12-15 23:14:1445 static const char kDisableCompression[] = "no-compress";
[email protected]0ef23e3a2010-07-10 00:05:5646 static const char kDisableAltProtocols[] = "no-alt-protocols";
[email protected]bace48c2010-08-03 20:52:0247 static const char kEnableVersionOne[] = "v1";
[email protected]de6251d02010-08-22 20:56:4748 static const char kForceAltProtocols[] = "force-alt-protocols";
[email protected]ea1cc2cd2011-02-22 16:47:3849 static const char kSingleDomain[] = "single-domain";
[email protected]65041fa2010-05-21 06:56:5350
[email protected]7349c6b12010-07-22 02:29:1651 // If flow-control is enabled, received WINDOW_UPDATE and SETTINGS
52 // messages are processed and outstanding window size is actually obeyed
53 // when sending data frames, and WINDOW_UPDATE messages are generated
54 // when data is consumed.
55 static const char kEnableFlowControl[] = "flow-control";
56
[email protected]65041fa2010-05-21 06:56:5357 // We want an A/B experiment between SPDY enabled and SPDY disabled,
58 // but only for pages where SPDY *could have been* negotiated. To do
59 // this, we use NPN, but prevent it from negotiating SPDY. If the
60 // server negotiates HTTP, rather than SPDY, today that will only happen
61 // on servers that installed NPN (and could have done SPDY). But this is
62 // a bit of a hack, as this correlation between NPN and SPDY is not
63 // really guaranteed.
[email protected]1f14a912009-12-21 20:32:4464 static const char kEnableNPN[] = "npn";
[email protected]65041fa2010-05-21 06:56:5365 static const char kEnableNpnHttpOnly[] = "npn-http";
66
67 // Except for the first element, the order is irrelevant. First element
68 // specifies the fallback in case nothing matches
69 // (SSLClientSocket::kNextProtoNoOverlap). Otherwise, the SSL library
70 // will choose the first overlapping protocol in the server's list, since
71 // it presumedly has a better understanding of which protocol we should
72 // use, therefore the rest of the ordering here is not important.
[email protected]bace48c2010-08-03 20:52:0273 static const char kNpnProtosFull[] = "\x08http/1.1\x06spdy/2";
74 // This is a temporary hack to pretend we support version 1.
[email protected]f0f569e2010-08-05 17:09:1875 static const char kNpnProtosFullV1[] = "\x08http/1.1\x06spdy/1";
[email protected]65041fa2010-05-21 06:56:5376 // No spdy specified.
77 static const char kNpnProtosHttpOnly[] = "\x08http/1.1\x07http1.1";
[email protected]650e2cae2009-10-21 23:52:0778
[email protected]955fc2e72010-02-08 20:37:3079 std::vector<std::string> spdy_options;
[email protected]76eb0242010-10-14 00:35:3680 base::SplitString(mode, ',', &spdy_options);
[email protected]650e2cae2009-10-21 23:52:0781
[email protected]0ef23e3a2010-07-10 00:05:5682 bool use_alt_protocols = true;
83
[email protected]955fc2e72010-02-08 20:37:3084 for (std::vector<std::string>::iterator it = spdy_options.begin();
85 it != spdy_options.end(); ++it) {
[email protected]d93d8332011-01-08 04:21:0886 const std::string& element = *it;
87 std::vector<std::string> name_value;
88 base::SplitString(element, '=', &name_value);
89 const std::string& option = name_value[0];
90 const std::string value = name_value.size() > 1 ? name_value[1] : "";
91
[email protected]1f418ee2010-10-16 19:46:5692 if (option == kOff) {
93 HttpStreamFactory::set_spdy_enabled(false);
94 } else if (option == kDisableSSL) {
[email protected]65041fa2010-05-21 06:56:5395 SpdySession::SetSSLMode(false); // Disable SSL
[email protected]8e6441ca2010-08-19 05:56:3896 HttpStreamFactory::set_force_spdy_over_ssl(false);
97 HttpStreamFactory::set_force_spdy_always(true);
[email protected]9e9e842e2010-07-23 23:09:1598 } else if (option == kSSL) {
[email protected]8e6441ca2010-08-19 05:56:3899 HttpStreamFactory::set_force_spdy_over_ssl(true);
100 HttpStreamFactory::set_force_spdy_always(true);
[email protected]d93d8332011-01-08 04:21:08101 } else if (option == kExclude) {
102 HttpStreamFactory::add_forced_spdy_exclusion(value);
[email protected]85c0ed82009-12-15 23:14:14103 } else if (option == kDisableCompression) {
[email protected]955fc2e72010-02-08 20:37:30104 spdy::SpdyFramer::set_enable_compression_default(false);
[email protected]1f14a912009-12-21 20:32:44105 } else if (option == kEnableNPN) {
[email protected]8e6441ca2010-08-19 05:56:38106 HttpStreamFactory::set_use_alternate_protocols(use_alt_protocols);
107 HttpStreamFactory::set_next_protos(kNpnProtosFull);
[email protected]65041fa2010-05-21 06:56:53108 } else if (option == kEnableNpnHttpOnly) {
[email protected]789d04a2010-07-15 21:15:13109 // Avoid alternate protocol in this case. Otherwise, browser will try SSL
110 // and then fallback to http. This introduces extra load.
[email protected]8e6441ca2010-08-19 05:56:38111 HttpStreamFactory::set_use_alternate_protocols(false);
112 HttpStreamFactory::set_next_protos(kNpnProtosHttpOnly);
[email protected]bace48c2010-08-03 20:52:02113 } else if (option == kEnableVersionOne) {
114 spdy::SpdyFramer::set_protocol_version(1);
[email protected]8e6441ca2010-08-19 05:56:38115 HttpStreamFactory::set_next_protos(kNpnProtosFullV1);
[email protected]0ef23e3a2010-07-10 00:05:56116 } else if (option == kDisableAltProtocols) {
117 use_alt_protocols = false;
[email protected]8e6441ca2010-08-19 05:56:38118 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]7349c6b12010-07-22 02:29:16119 } else if (option == kEnableFlowControl) {
[email protected]450c5022010-08-26 02:38:28120 SpdySession::set_flow_control(true);
[email protected]de6251d02010-08-22 20:56:47121 } else if (option == kForceAltProtocols) {
122 HttpAlternateProtocols::PortProtocolPair pair;
123 pair.port = 443;
124 pair.protocol = HttpAlternateProtocols::NPN_SPDY_2;
125 HttpAlternateProtocols::ForceAlternateProtocol(pair);
[email protected]ea1cc2cd2011-02-22 16:47:38126 } else if (option == kSingleDomain) {
127 SpdySessionPool::ForceSingleDomain();
128 LOG(ERROR) << "FORCING SINGLE DOMAIN";
[email protected]955fc2e72010-02-08 20:37:30129 } else if (option.empty() && it == spdy_options.begin()) {
[email protected]85c0ed82009-12-15 23:14:14130 continue;
131 } else {
[email protected]955fc2e72010-02-08 20:37:30132 LOG(DFATAL) << "Unrecognized spdy option: " << option;
[email protected]85c0ed82009-12-15 23:14:14133 }
134 }
[email protected]7adaccb2009-10-13 04:43:21135}
[email protected]d100e44f2011-01-26 22:47:11136
137//-----------------------------------------------------------------------------
138
139int HttpNetworkLayer::CreateTransaction(scoped_ptr<HttpTransaction>* trans) {
140 if (suspended_)
141 return ERR_NETWORK_IO_SUSPENDED;
142
143 trans->reset(new HttpNetworkTransaction(GetSession()));
144 return OK;
145}
146
147HttpCache* HttpNetworkLayer::GetCache() {
148 return NULL;
149}
150
151HttpNetworkSession* HttpNetworkLayer::GetSession() {
[email protected]d100e44f2011-01-26 22:47:11152 return session_;
153}
154
155void HttpNetworkLayer::Suspend(bool suspend) {
156 suspended_ = suspend;
157
158 if (suspend && session_)
159 session_->tcp_socket_pool()->CloseIdleSockets();
160}
161
initial.commit586acc5fe2008-07-26 22:42:52162} // namespace net