blob: ca0678533d7e90b8657a23fe7a1f01ac0f340d3c [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 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
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
9#include <string>
[email protected]95d88ffe2010-02-04 21:25:3310#include <vector>
[email protected]77848d12008-11-14 00:00:2211
[email protected]2d731a32010-04-29 01:04:0612#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3013#include "base/compiler_specific.h"
[email protected]95d88ffe2010-02-04 21:25:3314#include "base/file_util.h"
[email protected]57999812013-02-24 05:40:5215#include "base/files/file_path.h"
[email protected]f3da152d2012-06-02 01:00:5716#include "base/json/json_writer.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4718#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4919#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4720#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0521#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3322#include "base/test/test_file_util.h"
[email protected]277d5942010-08-11 21:02:3523#include "net/base/auth.h"
[email protected]169d0012010-05-10 23:20:1224#include "net/base/capturing_net_log.h"
[email protected]bacff652009-03-31 17:50:3325#include "net/base/completion_callback.h"
[email protected]58e32bb2013-01-21 18:23:2526#include "net/base/load_timing_info.h"
27#include "net/base/load_timing_info_test_util.h"
[email protected]169d0012010-05-10 23:20:1228#include "net/base/net_log.h"
29#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3130#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5231#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4032#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0633#include "net/base/upload_bytes_element_reader.h"
[email protected]329b68b2012-11-14 17:54:2734#include "net/base/upload_data_stream.h"
[email protected]d98961652012-09-11 20:27:2135#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1136#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1637#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5338#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2439#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1240#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0041#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2942#include "net/http/http_auth_handler_ntlm.h"
[email protected]0877e3d2009-10-17 22:29:5743#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5244#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5645#include "net/http/http_network_session_peer.h"
[email protected]17291a022011-10-10 07:32:5346#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5747#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3848#include "net/http/http_stream_factory.h"
initial.commit586acc5fe2008-07-26 22:42:5249#include "net/http/http_transaction_unittest.h"
[email protected]51fff29d2008-12-19 22:17:5350#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0351#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1152#include "net/proxy/proxy_resolver.h"
53#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4454#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0355#include "net/socket/client_socket_pool_manager.h"
[email protected]a42dbd142011-11-17 16:42:0256#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0757#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4458#include "net/socket/socket_test_util.h"
59#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5460#include "net/spdy/spdy_framer.h"
61#include "net/spdy/spdy_session.h"
62#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0263#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5764#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0365#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5766#include "net/ssl/ssl_config_service_defaults.h"
67#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1168#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4469#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5270#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1571#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2772#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5273
[email protected]ad65a3e2013-12-25 18:18:0174using base::ASCIIToUTF16;
75
initial.commit586acc5fe2008-07-26 22:42:5276//-----------------------------------------------------------------------------
77
[email protected]13c8a092010-07-29 06:15:4478namespace {
79
[email protected]42cba2fb2013-03-29 19:58:5780const base::string16 kBar(ASCIIToUTF16("bar"));
81const base::string16 kBar2(ASCIIToUTF16("bar2"));
82const base::string16 kBar3(ASCIIToUTF16("bar3"));
83const base::string16 kBaz(ASCIIToUTF16("baz"));
84const base::string16 kFirst(ASCIIToUTF16("first"));
85const base::string16 kFoo(ASCIIToUTF16("foo"));
86const base::string16 kFoo2(ASCIIToUTF16("foo2"));
87const base::string16 kFoo3(ASCIIToUTF16("foo3"));
88const base::string16 kFou(ASCIIToUTF16("fou"));
89const base::string16 kSecond(ASCIIToUTF16("second"));
90const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
91const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:4492
[email protected]e5c026642012-03-17 00:14:0293int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
94 return session->GetTransportSocketPool(
95 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
96}
97
98int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
99 return session->GetSSLSocketPool(
100 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
101}
102
[email protected]043b68c82013-08-22 23:41:52103bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
104 return session->GetTransportSocketPool(
105 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
106}
107
[email protected]f3da152d2012-06-02 01:00:57108// Takes in a Value created from a NetLogHttpResponseParameter, and returns
109// a JSONified list of headers as a single string. Uses single quotes instead
110// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27111bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57112 if (!params)
113 return false;
[email protected]ea5ef4c2013-06-13 22:50:27114 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57115 if (!params->GetList("headers", &header_list))
116 return false;
117 std::string double_quote_headers;
118 base::JSONWriter::Write(header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28119 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57120 return true;
121}
122
[email protected]029c83b62013-01-24 05:28:20123// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
124// used.
125void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
126 EXPECT_TRUE(load_timing_info.socket_reused);
[email protected]58e32bb2013-01-21 18:23:25127 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
128
[email protected]029c83b62013-01-24 05:28:20129 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
130 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
131
132 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
133 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25134
135 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25136
[email protected]3b23a222013-05-15 21:33:25137 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25138 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
139 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25140 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25141}
142
[email protected]029c83b62013-01-24 05:28:20143// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
144// used.
[email protected]58e32bb2013-01-21 18:23:25145void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
146 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20147 EXPECT_FALSE(load_timing_info.socket_reused);
148 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
149
150 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
151 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
152
153 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
[email protected]3b23a222013-05-15 21:33:25154 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20155 EXPECT_LE(load_timing_info.connect_timing.connect_end,
156 load_timing_info.send_start);
157
158 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20159
[email protected]3b23a222013-05-15 21:33:25160 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20161 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
162 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25163 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20164}
165
166// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
167// used.
168void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
169 EXPECT_TRUE(load_timing_info.socket_reused);
170 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
171
172 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
173
174 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
175 EXPECT_LE(load_timing_info.proxy_resolve_start,
176 load_timing_info.proxy_resolve_end);
177 EXPECT_LE(load_timing_info.proxy_resolve_end,
178 load_timing_info.send_start);
179 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20180
[email protected]3b23a222013-05-15 21:33:25181 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20182 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
183 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25184 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20185}
186
187// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
188// used.
189void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
190 int connect_timing_flags) {
191 EXPECT_FALSE(load_timing_info.socket_reused);
192 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
193
194 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
195 EXPECT_LE(load_timing_info.proxy_resolve_start,
196 load_timing_info.proxy_resolve_end);
197 EXPECT_LE(load_timing_info.proxy_resolve_end,
198 load_timing_info.connect_timing.connect_start);
199 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
200 connect_timing_flags);
201 EXPECT_LE(load_timing_info.connect_timing.connect_end,
202 load_timing_info.send_start);
203
204 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20205
[email protected]3b23a222013-05-15 21:33:25206 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20207 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
208 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25209 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25210}
211
[email protected]13c8a092010-07-29 06:15:44212} // namespace
213
[email protected]89ceba9a2009-03-21 03:46:06214namespace net {
215
[email protected]448d4ca52012-03-04 04:12:23216namespace {
217
[email protected]c6bf8152012-12-02 07:43:34218HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
219 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14220}
221
[email protected]448d4ca52012-03-04 04:12:23222} // namespace
223
[email protected]23e482282013-06-14 16:08:02224class HttpNetworkTransactionTest
225 : public PlatformTest,
226 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03227 public:
[email protected]23e482282013-06-14 16:08:02228 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03229 // Important to restore the per-pool limit first, since the pool limit must
230 // always be greater than group limit, and the tests reduce both limits.
231 ClientSocketPoolManager::set_max_sockets_per_pool(
232 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
233 ClientSocketPoolManager::set_max_sockets_per_group(
234 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
235 }
236
[email protected]e3ceb682011-06-28 23:55:46237 protected:
[email protected]23e482282013-06-14 16:08:02238 HttpNetworkTransactionTest()
239 : spdy_util_(GetParam()),
240 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03241 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
242 HttpNetworkSession::NORMAL_SOCKET_POOL)),
243 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
244 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
245 }
[email protected]bb88e1d32013-05-03 23:11:07246
[email protected]e3ceb682011-06-28 23:55:46247 struct SimpleGetHelperResult {
248 int rv;
249 std::string status_line;
250 std::string response_data;
[email protected]b8015c42013-12-24 15:18:19251 int64 totalReceivedBytes;
[email protected]58e32bb2013-01-21 18:23:25252 LoadTimingInfo load_timing_info;
[email protected]e3ceb682011-06-28 23:55:46253 };
254
[email protected]2ff8b312010-04-26 22:20:54255 virtual void SetUp() {
[email protected]0b0bf032010-09-21 18:08:50256 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34257 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54258 }
259
[email protected]0e75a732008-10-16 20:36:09260 virtual void TearDown() {
[email protected]0b0bf032010-09-21 18:08:50261 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34262 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09263 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34264 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09265 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50266 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34267 base::MessageLoop::current()->RunUntilIdle();
[email protected]c54c6962013-02-01 04:53:19268 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]0ce3af82013-07-22 16:17:16269 HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
[email protected]0e75a732008-10-16 20:36:09270 }
271
[email protected]8a0fc822013-06-27 20:52:43272 // This is the expected return from a current server advertising SPDY.
273 std::string GetAlternateProtocolHttpHeader() {
274 return
275 std::string("Alternate-Protocol: 443:") +
276 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
277 "\r\n\r\n";
278 }
279
[email protected]202965992011-12-07 23:04:51280 // Either |write_failure| specifies a write failure or |read_failure|
281 // specifies a read failure when using a reused socket. In either case, the
282 // failure should cause the network transaction to resend the request, and the
283 // other argument should be NULL.
284 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
285 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52286
[email protected]a34f61ee2014-03-18 20:59:49287 // Either |write_failure| specifies a write failure or |read_failure|
288 // specifies a read failure when using a reused socket. In either case, the
289 // failure should cause the network transaction to resend the request, and the
290 // other argument should be NULL.
291 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10292 const MockRead* read_failure,
293 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49294
[email protected]5a60c8b2011-10-19 20:14:29295 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
296 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15297 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52298
[email protected]ff007e162009-05-23 09:13:15299 HttpRequestInfo request;
300 request.method = "GET";
301 request.url = GURL("http://www.google.com/");
302 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52303
[email protected]58e32bb2013-01-21 18:23:25304 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07305 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07306 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27307 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07308 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27309
[email protected]5a60c8b2011-10-19 20:14:29310 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07311 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29312 }
initial.commit586acc5fe2008-07-26 22:42:52313
[email protected]49639fa2011-12-20 23:22:41314 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52315
[email protected]c47c0372014-03-12 23:07:02316 EXPECT_TRUE(log.bound().IsLogging());
[email protected]49639fa2011-12-20 23:22:41317 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15318 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52319
[email protected]ff007e162009-05-23 09:13:15320 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25321
322 // Even in the failure cases that use this function, connections are always
323 // successfully established before the error.
324 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
325 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
326
[email protected]ff007e162009-05-23 09:13:15327 if (out.rv != OK)
328 return out;
329
330 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50331 // Can't use ASSERT_* inside helper functions like this, so
332 // return an error.
[email protected]90499482013-06-01 00:39:50333 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50334 out.rv = ERR_UNEXPECTED;
335 return out;
336 }
[email protected]ff007e162009-05-23 09:13:15337 out.status_line = response->headers->GetStatusLine();
338
[email protected]80a09a82012-11-16 17:40:06339 EXPECT_EQ("127.0.0.1", response->socket_address.host());
340 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19341
[email protected]ff007e162009-05-23 09:13:15342 rv = ReadTransaction(trans.get(), &out.response_data);
343 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40344
[email protected]f3da152d2012-06-02 01:00:57345 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40346 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39347 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40348 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12349 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39350 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40351 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39352 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
353 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15354
[email protected]f3da152d2012-06-02 01:00:57355 std::string line;
356 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
357 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
358
[email protected]79e1fd62013-06-20 06:50:04359 HttpRequestHeaders request_headers;
360 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
361 std::string value;
362 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
363 EXPECT_EQ("www.google.com", value);
364 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
365 EXPECT_EQ("keep-alive", value);
366
367 std::string response_headers;
368 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
369 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
370 response_headers);
[email protected]3deb9a52010-11-11 00:24:40371
[email protected]b8015c42013-12-24 15:18:19372 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
[email protected]aecfbf22008-10-16 02:02:47373 return out;
[email protected]ff007e162009-05-23 09:13:15374 }
initial.commit586acc5fe2008-07-26 22:42:52375
[email protected]5a60c8b2011-10-19 20:14:29376 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
377 size_t reads_count) {
378 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
379 StaticSocketDataProvider* data[] = { &reads };
380 return SimpleGetHelperForData(data, 1);
381 }
382
[email protected]b8015c42013-12-24 15:18:19383 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
384 int64 size = 0;
385 for (size_t i = 0; i < reads_count; ++i)
386 size += data_reads[i].data_len;
387 return size;
388 }
389
[email protected]ff007e162009-05-23 09:13:15390 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
391 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52392
[email protected]ff007e162009-05-23 09:13:15393 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07394
395 void BypassHostCacheOnRefreshHelper(int load_flags);
396
397 void CheckErrorIsPassedBack(int error, IoMode mode);
398
[email protected]4bd46222013-05-14 19:32:23399 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07400 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03401
402 // Original socket limits. Some tests set these. Safest to always restore
403 // them once each test has been run.
404 int old_max_group_sockets_;
405 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15406};
[email protected]231d5a32008-09-13 00:45:27407
[email protected]23e482282013-06-14 16:08:02408INSTANTIATE_TEST_CASE_P(
409 NextProto,
410 HttpNetworkTransactionTest,
[email protected]b05bcaa32013-10-06 05:26:02411 testing::Values(kProtoDeprecatedSPDY2,
412 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
[email protected]88a332622013-07-30 07:13:32413 kProtoHTTP2Draft04));
[email protected]23e482282013-06-14 16:08:02414
[email protected]448d4ca52012-03-04 04:12:23415namespace {
416
[email protected]1826a402014-01-08 15:40:48417class BeforeNetworkStartHandler {
418 public:
419 explicit BeforeNetworkStartHandler(bool defer)
420 : defer_on_before_network_start_(defer),
421 observed_before_network_start_(false) {}
422
423 void OnBeforeNetworkStart(bool* defer) {
424 *defer = defer_on_before_network_start_;
425 observed_before_network_start_ = true;
426 }
427
428 bool observed_before_network_start() const {
429 return observed_before_network_start_;
430 }
431
432 private:
433 const bool defer_on_before_network_start_;
434 bool observed_before_network_start_;
435
436 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
437};
438
[email protected]15a5ccf82008-10-23 19:57:43439// Fill |str| with a long header list that consumes >= |size| bytes.
440void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19441 const char* row =
442 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
443 const int sizeof_row = strlen(row);
444 const int num_rows = static_cast<int>(
445 ceil(static_cast<float>(size) / sizeof_row));
446 const int sizeof_data = num_rows * sizeof_row;
447 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43448 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51449
[email protected]4ddaf2502008-10-23 18:26:19450 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43451 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19452}
453
[email protected]385a4672009-03-11 22:21:29454// Alternative functions that eliminate randomness and dependency on the local
455// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20456void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29457 static const uint8 bytes[] = {
458 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
459 };
460 static size_t current_byte = 0;
461 for (size_t i = 0; i < n; ++i) {
462 output[i] = bytes[current_byte++];
463 current_byte %= arraysize(bytes);
464 }
465}
466
[email protected]fe2bc6a2009-03-23 16:52:20467void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29468 static const uint8 bytes[] = {
469 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
470 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
471 };
472 static size_t current_byte = 0;
473 for (size_t i = 0; i < n; ++i) {
474 output[i] = bytes[current_byte++];
475 current_byte %= arraysize(bytes);
476 }
477}
478
[email protected]fe2bc6a2009-03-23 16:52:20479std::string MockGetHostName() {
480 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29481}
482
[email protected]e60e47a2010-07-14 03:37:18483template<typename ParentPool>
484class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31485 public:
[email protected]9e1bdd32011-02-03 21:48:34486 CaptureGroupNameSocketPool(HostResolver* host_resolver,
487 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18488
[email protected]d80a4322009-08-14 07:07:49489 const std::string last_group_name_received() const {
490 return last_group_name_;
491 }
492
[email protected]684970b2009-08-14 04:54:46493 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49494 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31495 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31496 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41497 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53498 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31499 last_group_name_ = group_name;
500 return ERR_IO_PENDING;
501 }
[email protected]04e5be32009-06-26 20:00:31502 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21503 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31504 virtual void ReleaseSocket(const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44505 scoped_ptr<StreamSocket> socket,
[email protected]9f95c692011-02-11 19:20:19506 int id) {}
[email protected]04e5be32009-06-26 20:00:31507 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31508 virtual int IdleSocketCount() const {
509 return 0;
510 }
511 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
512 return 0;
513 }
514 virtual LoadState GetLoadState(const std::string& group_name,
515 const ClientSocketHandle* handle) const {
516 return LOAD_STATE_IDLE;
517 }
[email protected]a796bcec2010-03-22 17:17:26518 virtual base::TimeDelta ConnectionTimeout() const {
519 return base::TimeDelta();
520 }
[email protected]d80a4322009-08-14 07:07:49521
522 private:
[email protected]04e5be32009-06-26 20:00:31523 std::string last_group_name_;
524};
525
[email protected]ab739042011-04-07 15:22:28526typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
527CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13528typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
529CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06530typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11531CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18532typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
533CaptureGroupNameSSLSocketPool;
534
535template<typename ParentPool>
536CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34537 HostResolver* host_resolver,
538 CertVerifier* /* cert_verifier */)
539 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18540
541template<>
[email protected]2df19bb2010-08-25 20:13:46542CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34543 HostResolver* host_resolver,
544 CertVerifier* /* cert_verifier */)
545 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46546
[email protected]007b3f82013-04-09 08:46:45547template <>
[email protected]e60e47a2010-07-14 03:37:18548CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34549 HostResolver* host_resolver,
550 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45551 : SSLClientSocketPool(0,
552 0,
553 NULL,
554 host_resolver,
555 cert_verifier,
556 NULL,
557 NULL,
[email protected]284303b62013-11-28 15:11:54558 NULL,
[email protected]007b3f82013-04-09 08:46:45559 std::string(),
560 NULL,
561 NULL,
562 NULL,
563 NULL,
564 NULL,
565 NULL) {}
[email protected]2227c692010-05-04 15:36:11566
[email protected]231d5a32008-09-13 00:45:27567//-----------------------------------------------------------------------------
568
[email protected]79cb5c12011-09-12 13:12:04569// Helper functions for validating that AuthChallengeInfo's are correctly
570// configured for common cases.
571bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
572 if (!auth_challenge)
573 return false;
574 EXPECT_FALSE(auth_challenge->is_proxy);
575 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
576 EXPECT_EQ("MyRealm1", auth_challenge->realm);
577 EXPECT_EQ("basic", auth_challenge->scheme);
578 return true;
579}
580
581bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
582 if (!auth_challenge)
583 return false;
584 EXPECT_TRUE(auth_challenge->is_proxy);
585 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
586 EXPECT_EQ("MyRealm1", auth_challenge->realm);
587 EXPECT_EQ("basic", auth_challenge->scheme);
588 return true;
589}
590
591bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
592 if (!auth_challenge)
593 return false;
594 EXPECT_FALSE(auth_challenge->is_proxy);
595 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
596 EXPECT_EQ("digestive", auth_challenge->realm);
597 EXPECT_EQ("digest", auth_challenge->scheme);
598 return true;
599}
600
601bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
602 if (!auth_challenge)
603 return false;
604 EXPECT_FALSE(auth_challenge->is_proxy);
605 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
606 EXPECT_EQ(std::string(), auth_challenge->realm);
607 EXPECT_EQ("ntlm", auth_challenge->scheme);
608 return true;
609}
610
[email protected]448d4ca52012-03-04 04:12:23611} // namespace
612
[email protected]23e482282013-06-14 16:08:02613TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07614 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40615 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07616 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]231d5a32008-09-13 00:45:27617}
618
[email protected]23e482282013-06-14 16:08:02619TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27620 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35621 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
622 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06623 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27624 };
[email protected]31a2bfe2010-02-09 08:03:39625 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
626 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42627 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27628 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
629 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19630 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
631 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27632}
633
634// Response with no status line.
[email protected]23e482282013-06-14 16:08:02635TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27636 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35637 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06638 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27639 };
[email protected]31a2bfe2010-02-09 08:03:39640 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
641 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42642 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27643 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
644 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19645 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
646 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27647}
648
649// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02650TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27651 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35652 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06653 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27654 };
[email protected]31a2bfe2010-02-09 08:03:39655 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
656 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42657 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27658 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
659 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19660 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
661 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27662}
663
664// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02665TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27666 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35667 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06668 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27669 };
[email protected]31a2bfe2010-02-09 08:03:39670 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
671 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42672 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27673 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
674 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19675 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
676 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27677}
678
679// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02680TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27681 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35682 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06683 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27684 };
[email protected]31a2bfe2010-02-09 08:03:39685 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
686 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42687 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25688 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
689 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19690 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
691 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27692}
693
694// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02695TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27696 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35697 MockRead("\n"),
698 MockRead("\n"),
699 MockRead("Q"),
700 MockRead("J"),
701 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06702 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27703 };
[email protected]31a2bfe2010-02-09 08:03:39704 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
705 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42706 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27707 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
708 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19709 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
710 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27711}
712
713// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02714TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27715 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35716 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06717 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27718 };
[email protected]31a2bfe2010-02-09 08:03:39719 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
720 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42721 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27722 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
723 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19724 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
725 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52726}
727
[email protected]f9d44aa2008-09-23 23:57:17728// Simulate a 204 response, lacking a Content-Length header, sent over a
729// persistent connection. The response should still terminate since a 204
730// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02731TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19732 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17733 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35734 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19735 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06736 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17737 };
[email protected]31a2bfe2010-02-09 08:03:39738 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
739 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42740 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17741 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
742 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19743 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
744 int64 response_size = reads_size - strlen(junk);
745 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17746}
747
[email protected]0877e3d2009-10-17 22:29:57748// A simple request using chunked encoding with some extra data after.
749// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02750TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19751 std::string final_chunk = "0\r\n\r\n";
752 std::string extra_data = "HTTP/1.1 200 OK\r\n";
753 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57754 MockRead data_reads[] = {
755 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
756 MockRead("5\r\nHello\r\n"),
757 MockRead("1\r\n"),
758 MockRead(" \r\n"),
759 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19760 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06761 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57762 };
[email protected]31a2bfe2010-02-09 08:03:39763 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
764 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57765 EXPECT_EQ(OK, out.rv);
766 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
767 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19768 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
769 int64 response_size = reads_size - extra_data.size();
770 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57771}
772
[email protected]9fe44f52010-09-23 18:36:00773// Next tests deal with http://crbug.com/56344.
774
[email protected]23e482282013-06-14 16:08:02775TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00776 MultipleContentLengthHeadersNoTransferEncoding) {
777 MockRead data_reads[] = {
778 MockRead("HTTP/1.1 200 OK\r\n"),
779 MockRead("Content-Length: 10\r\n"),
780 MockRead("Content-Length: 5\r\n\r\n"),
781 };
782 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
783 arraysize(data_reads));
784 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
785}
786
[email protected]23e482282013-06-14 16:08:02787TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04788 DuplicateContentLengthHeadersNoTransferEncoding) {
789 MockRead data_reads[] = {
790 MockRead("HTTP/1.1 200 OK\r\n"),
791 MockRead("Content-Length: 5\r\n"),
792 MockRead("Content-Length: 5\r\n\r\n"),
793 MockRead("Hello"),
794 };
795 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
796 arraysize(data_reads));
797 EXPECT_EQ(OK, out.rv);
798 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
799 EXPECT_EQ("Hello", out.response_data);
800}
801
[email protected]23e482282013-06-14 16:08:02802TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04803 ComplexContentLengthHeadersNoTransferEncoding) {
804 // More than 2 dupes.
805 {
806 MockRead data_reads[] = {
807 MockRead("HTTP/1.1 200 OK\r\n"),
808 MockRead("Content-Length: 5\r\n"),
809 MockRead("Content-Length: 5\r\n"),
810 MockRead("Content-Length: 5\r\n\r\n"),
811 MockRead("Hello"),
812 };
813 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
814 arraysize(data_reads));
815 EXPECT_EQ(OK, out.rv);
816 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
817 EXPECT_EQ("Hello", out.response_data);
818 }
819 // HTTP/1.0
820 {
821 MockRead data_reads[] = {
822 MockRead("HTTP/1.0 200 OK\r\n"),
823 MockRead("Content-Length: 5\r\n"),
824 MockRead("Content-Length: 5\r\n"),
825 MockRead("Content-Length: 5\r\n\r\n"),
826 MockRead("Hello"),
827 };
828 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
829 arraysize(data_reads));
830 EXPECT_EQ(OK, out.rv);
831 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
832 EXPECT_EQ("Hello", out.response_data);
833 }
834 // 2 dupes and one mismatched.
835 {
836 MockRead data_reads[] = {
837 MockRead("HTTP/1.1 200 OK\r\n"),
838 MockRead("Content-Length: 10\r\n"),
839 MockRead("Content-Length: 10\r\n"),
840 MockRead("Content-Length: 5\r\n\r\n"),
841 };
842 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
843 arraysize(data_reads));
844 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
845 }
846}
847
[email protected]23e482282013-06-14 16:08:02848TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00849 MultipleContentLengthHeadersTransferEncoding) {
850 MockRead data_reads[] = {
851 MockRead("HTTP/1.1 200 OK\r\n"),
852 MockRead("Content-Length: 666\r\n"),
853 MockRead("Content-Length: 1337\r\n"),
854 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
855 MockRead("5\r\nHello\r\n"),
856 MockRead("1\r\n"),
857 MockRead(" \r\n"),
858 MockRead("5\r\nworld\r\n"),
859 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06860 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00861 };
862 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
863 arraysize(data_reads));
864 EXPECT_EQ(OK, out.rv);
865 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
866 EXPECT_EQ("Hello world", out.response_data);
867}
868
[email protected]1628fe92011-10-04 23:04:55869// Next tests deal with http://crbug.com/98895.
870
871// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02872TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55873 MockRead data_reads[] = {
874 MockRead("HTTP/1.1 200 OK\r\n"),
875 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
876 MockRead("Content-Length: 5\r\n\r\n"),
877 MockRead("Hello"),
878 };
879 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
880 arraysize(data_reads));
881 EXPECT_EQ(OK, out.rv);
882 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
883 EXPECT_EQ("Hello", out.response_data);
884}
885
[email protected]54a9c6e52012-03-21 20:10:59886// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02887TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59888 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55889 MockRead data_reads[] = {
890 MockRead("HTTP/1.1 200 OK\r\n"),
891 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
892 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
893 MockRead("Content-Length: 5\r\n\r\n"),
894 MockRead("Hello"),
895 };
896 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
897 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59898 EXPECT_EQ(OK, out.rv);
899 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
900 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55901}
902
903// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02904TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55905 MockRead data_reads[] = {
906 MockRead("HTTP/1.1 200 OK\r\n"),
907 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
908 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
909 MockRead("Content-Length: 5\r\n\r\n"),
910 MockRead("Hello"),
911 };
912 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
913 arraysize(data_reads));
914 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
915}
916
[email protected]54a9c6e52012-03-21 20:10:59917// Checks that two identical Location headers result in no error.
918// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02919TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55920 MockRead data_reads[] = {
921 MockRead("HTTP/1.1 302 Redirect\r\n"),
922 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59923 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55924 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06925 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55926 };
927
928 HttpRequestInfo request;
929 request.method = "GET";
930 request.url = GURL("http://redirect.com/");
931 request.load_flags = 0;
932
[email protected]3fe8d2f82013-10-17 08:56:07933 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55934 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07935 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]1628fe92011-10-04 23:04:55936
937 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07938 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55939
[email protected]49639fa2011-12-20 23:22:41940 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55941
[email protected]49639fa2011-12-20 23:22:41942 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55943 EXPECT_EQ(ERR_IO_PENDING, rv);
944
945 EXPECT_EQ(OK, callback.WaitForResult());
946
947 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50948 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55949 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
950 std::string url;
951 EXPECT_TRUE(response->headers->IsRedirect(&url));
952 EXPECT_EQ("http://good.com/", url);
953}
954
[email protected]1628fe92011-10-04 23:04:55955// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02956TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55957 MockRead data_reads[] = {
958 MockRead("HTTP/1.1 302 Redirect\r\n"),
959 MockRead("Location: http://good.com/\r\n"),
960 MockRead("Location: http://evil.com/\r\n"),
961 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06962 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55963 };
964 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
965 arraysize(data_reads));
966 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
967}
968
[email protected]ef0faf2e72009-03-05 23:27:23969// Do a request using the HEAD method. Verify that we don't try to read the
970// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02971TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42972 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23973 request.method = "HEAD";
974 request.url = GURL("http://www.google.com/");
975 request.load_flags = 0;
976
[email protected]3fe8d2f82013-10-17 08:56:07977 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27978 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27980
[email protected]ef0faf2e72009-03-05 23:27:23981 MockWrite data_writes1[] = {
982 MockWrite("HEAD / HTTP/1.1\r\n"
983 "Host: www.google.com\r\n"
984 "Connection: keep-alive\r\n"
985 "Content-Length: 0\r\n\r\n"),
986 };
987 MockRead data_reads1[] = {
988 MockRead("HTTP/1.1 404 Not Found\r\n"),
989 MockRead("Server: Blah\r\n"),
990 MockRead("Content-Length: 1234\r\n\r\n"),
991
992 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06993 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23994 };
995
[email protected]31a2bfe2010-02-09 08:03:39996 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
997 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07998 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23999
[email protected]49639fa2011-12-20 23:22:411000 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231001
[email protected]49639fa2011-12-20 23:22:411002 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421003 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231004
1005 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421006 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231007
[email protected]1c773ea12009-04-28 19:58:421008 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501009 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231010
1011 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501012 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231013 EXPECT_EQ(1234, response->headers->GetContentLength());
1014 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1015
1016 std::string server_header;
1017 void* iter = NULL;
1018 bool has_server_header = response->headers->EnumerateHeader(
1019 &iter, "Server", &server_header);
1020 EXPECT_TRUE(has_server_header);
1021 EXPECT_EQ("Blah", server_header);
1022
1023 // Reading should give EOF right away, since there is no message body
1024 // (despite non-zero content-length).
1025 std::string response_data;
1026 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421027 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231028 EXPECT_EQ("", response_data);
1029}
1030
[email protected]23e482282013-06-14 16:08:021031TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071032 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521033
1034 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351035 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1036 MockRead("hello"),
1037 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1038 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061039 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521040 };
[email protected]31a2bfe2010-02-09 08:03:391041 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071042 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521043
[email protected]0b0bf032010-09-21 18:08:501044 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521045 "hello", "world"
1046 };
1047
1048 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421049 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521050 request.method = "GET";
1051 request.url = GURL("http://www.google.com/");
1052 request.load_flags = 0;
1053
[email protected]262eec82013-03-19 21:01:361054 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501055 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271056
[email protected]49639fa2011-12-20 23:22:411057 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521058
[email protected]49639fa2011-12-20 23:22:411059 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421060 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521061
1062 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421063 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521064
[email protected]1c773ea12009-04-28 19:58:421065 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501066 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521067
[email protected]90499482013-06-01 00:39:501068 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251069 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521070
1071 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571072 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421073 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251074 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521075 }
1076}
1077
[email protected]23e482282013-06-14 16:08:021078TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061079 ScopedVector<UploadElementReader> element_readers;
1080 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201081 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271082
[email protected]1c773ea12009-04-28 19:58:421083 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521084 request.method = "POST";
1085 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271086 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521087 request.load_flags = 0;
1088
[email protected]3fe8d2f82013-10-17 08:56:071089 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271090 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071091 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271092
initial.commit586acc5fe2008-07-26 22:42:521093 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351094 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1095 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1096 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061097 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521098 };
[email protected]31a2bfe2010-02-09 08:03:391099 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071100 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521101
[email protected]49639fa2011-12-20 23:22:411102 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521103
[email protected]49639fa2011-12-20 23:22:411104 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421105 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521106
1107 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421108 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521109
[email protected]1c773ea12009-04-28 19:58:421110 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501111 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521112
[email protected]90499482013-06-01 00:39:501113 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251114 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521115
1116 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571117 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421118 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251119 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521120}
1121
[email protected]3a2d3662009-03-27 03:49:141122// This test is almost the same as Ignores100 above, but the response contains
1123// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571124// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021125TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421126 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141127 request.method = "GET";
1128 request.url = GURL("http://www.foo.com/");
1129 request.load_flags = 0;
1130
[email protected]3fe8d2f82013-10-17 08:56:071131 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271132 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071133 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271134
[email protected]3a2d3662009-03-27 03:49:141135 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571136 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1137 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141138 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061139 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141140 };
[email protected]31a2bfe2010-02-09 08:03:391141 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071142 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141143
[email protected]49639fa2011-12-20 23:22:411144 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141145
[email protected]49639fa2011-12-20 23:22:411146 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421147 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141148
1149 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421150 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141151
[email protected]1c773ea12009-04-28 19:58:421152 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501153 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141154
[email protected]90499482013-06-01 00:39:501155 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141156 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1157
1158 std::string response_data;
1159 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421160 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141161 EXPECT_EQ("hello world", response_data);
1162}
1163
[email protected]23e482282013-06-14 16:08:021164TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381165 HttpRequestInfo request;
1166 request.method = "POST";
1167 request.url = GURL("http://www.foo.com/");
1168 request.load_flags = 0;
1169
[email protected]3fe8d2f82013-10-17 08:56:071170 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271171 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071172 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271173
[email protected]ee9410e72010-01-07 01:42:381174 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061175 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1176 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381177 };
[email protected]31a2bfe2010-02-09 08:03:391178 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071179 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381180
[email protected]49639fa2011-12-20 23:22:411181 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381182
[email protected]49639fa2011-12-20 23:22:411183 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381184 EXPECT_EQ(ERR_IO_PENDING, rv);
1185
1186 rv = callback.WaitForResult();
1187 EXPECT_EQ(OK, rv);
1188
1189 std::string response_data;
1190 rv = ReadTransaction(trans.get(), &response_data);
1191 EXPECT_EQ(OK, rv);
1192 EXPECT_EQ("", response_data);
1193}
1194
[email protected]23e482282013-06-14 16:08:021195TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381196 HttpRequestInfo request;
1197 request.method = "POST";
1198 request.url = GURL("http://www.foo.com/");
1199 request.load_flags = 0;
1200
[email protected]3fe8d2f82013-10-17 08:56:071201 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271202 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071203 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1204
[email protected]cb9bf6ca2011-01-28 13:15:271205
[email protected]ee9410e72010-01-07 01:42:381206 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061207 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381208 };
[email protected]31a2bfe2010-02-09 08:03:391209 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071210 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381211
[email protected]49639fa2011-12-20 23:22:411212 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381213
[email protected]49639fa2011-12-20 23:22:411214 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381215 EXPECT_EQ(ERR_IO_PENDING, rv);
1216
1217 rv = callback.WaitForResult();
1218 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1219}
1220
[email protected]23e482282013-06-14 16:08:021221void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511222 const MockWrite* write_failure,
1223 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421224 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521225 request.method = "GET";
1226 request.url = GURL("http://www.foo.com/");
1227 request.load_flags = 0;
1228
[email protected]58e32bb2013-01-21 18:23:251229 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071230 session_deps_.net_log = &net_log;
1231 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271232
[email protected]202965992011-12-07 23:04:511233 // Written data for successfully sending both requests.
1234 MockWrite data1_writes[] = {
1235 MockWrite("GET / HTTP/1.1\r\n"
1236 "Host: www.foo.com\r\n"
1237 "Connection: keep-alive\r\n\r\n"),
1238 MockWrite("GET / HTTP/1.1\r\n"
1239 "Host: www.foo.com\r\n"
1240 "Connection: keep-alive\r\n\r\n")
1241 };
1242
1243 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521244 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351245 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1246 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061247 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521248 };
[email protected]202965992011-12-07 23:04:511249
1250 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491251 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511252 data1_writes[1] = *write_failure;
1253 } else {
1254 ASSERT_TRUE(read_failure);
1255 data1_reads[2] = *read_failure;
1256 }
1257
1258 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1259 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071260 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521261
1262 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351263 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1264 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061265 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521266 };
[email protected]31a2bfe2010-02-09 08:03:391267 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071268 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521269
1270 const char* kExpectedResponseData[] = {
1271 "hello", "world"
1272 };
1273
[email protected]58e32bb2013-01-21 18:23:251274 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521275 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411276 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521277
[email protected]262eec82013-03-19 21:01:361278 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501279 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521280
[email protected]49639fa2011-12-20 23:22:411281 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421282 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521283
1284 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421285 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521286
[email protected]58e32bb2013-01-21 18:23:251287 LoadTimingInfo load_timing_info;
1288 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1289 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1290 if (i == 0) {
1291 first_socket_log_id = load_timing_info.socket_log_id;
1292 } else {
1293 // The second request should be using a new socket.
1294 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1295 }
1296
[email protected]1c773ea12009-04-28 19:58:421297 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501298 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521299
[email protected]90499482013-06-01 00:39:501300 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251301 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521302
1303 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571304 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421305 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251306 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521307 }
1308}
[email protected]3d2a59b2008-09-26 19:44:251309
[email protected]a34f61ee2014-03-18 20:59:491310void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1311 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101312 const MockRead* read_failure,
1313 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491314 HttpRequestInfo request;
1315 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101316 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491317 request.load_flags = 0;
1318
1319 CapturingNetLog net_log;
1320 session_deps_.net_log = &net_log;
1321 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1322
[email protected]09356c652014-03-25 15:36:101323 SSLSocketDataProvider ssl1(ASYNC, OK);
1324 SSLSocketDataProvider ssl2(ASYNC, OK);
1325 if (use_spdy) {
1326 ssl1.SetNextProto(GetParam());
1327 ssl2.SetNextProto(GetParam());
1328 }
1329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491331
[email protected]09356c652014-03-25 15:36:101332 // SPDY versions of the request and response.
1333 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1334 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1335 scoped_ptr<SpdyFrame> spdy_response(
1336 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1337 scoped_ptr<SpdyFrame> spdy_data(
1338 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491339
[email protected]09356c652014-03-25 15:36:101340 // HTTP/1.1 versions of the request and response.
1341 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1342 "Host: www.foo.com\r\n"
1343 "Connection: keep-alive\r\n\r\n";
1344 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1345 const char kHttpData[] = "hello";
1346
1347 std::vector<MockRead> data1_reads;
1348 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491349 if (write_failure) {
1350 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101351 data1_writes.push_back(*write_failure);
1352 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491353 } else {
1354 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101355 if (use_spdy) {
1356 data1_writes.push_back(CreateMockWrite(*spdy_request));
1357 } else {
1358 data1_writes.push_back(MockWrite(kHttpRequest));
1359 }
1360 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491361 }
1362
[email protected]09356c652014-03-25 15:36:101363 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1364 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491365 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1366
[email protected]09356c652014-03-25 15:36:101367 std::vector<MockRead> data2_reads;
1368 std::vector<MockWrite> data2_writes;
1369
1370 if (use_spdy) {
1371 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1372
1373 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1374 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1375 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1376 } else {
1377 data2_writes.push_back(
1378 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1379
1380 data2_reads.push_back(
1381 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1382 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1383 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1384 }
1385 OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1386 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491387 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1388
1389 // Preconnect a socket.
1390 net::SSLConfig ssl_config;
1391 session->ssl_config_service()->GetSSLConfig(&ssl_config);
1392 if (session->http_stream_factory()->has_next_protos())
1393 ssl_config.next_protos = session->http_stream_factory()->next_protos();
1394 session->http_stream_factory()->PreconnectStreams(
1395 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1396 // Wait for the preconnect to complete.
1397 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1398 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101399 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491400
1401 // Make the request.
1402 TestCompletionCallback callback;
1403
1404 scoped_ptr<HttpTransaction> trans(
1405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1406
1407 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1408 EXPECT_EQ(ERR_IO_PENDING, rv);
1409
1410 rv = callback.WaitForResult();
1411 EXPECT_EQ(OK, rv);
1412
1413 LoadTimingInfo load_timing_info;
1414 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101415 TestLoadTimingNotReused(
1416 load_timing_info,
1417 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491418
1419 const HttpResponseInfo* response = trans->GetResponseInfo();
1420 ASSERT_TRUE(response != NULL);
1421
1422 EXPECT_TRUE(response->headers.get() != NULL);
1423 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1424
1425 std::string response_data;
1426 rv = ReadTransaction(trans.get(), &response_data);
1427 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101428 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491429}
1430
[email protected]23e482282013-06-14 16:08:021431TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231432 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061433 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511434 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1435}
1436
[email protected]23e482282013-06-14 16:08:021437TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061438 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511439 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251440}
1441
[email protected]23e482282013-06-14 16:08:021442TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061443 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511444 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251445}
1446
[email protected]a34f61ee2014-03-18 20:59:491447TEST_P(HttpNetworkTransactionTest,
1448 PreconnectErrorNotConnectedOnWrite) {
1449 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101450 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491451}
1452
1453TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1454 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101455 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491456}
1457
1458TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1459 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101460 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1461}
1462
1463TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1464 MockRead read_failure(ASYNC, OK); // EOF
1465 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1466}
1467
1468TEST_P(HttpNetworkTransactionTest,
1469 SpdyPreconnectErrorNotConnectedOnWrite) {
1470 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1471 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1472}
1473
1474TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1475 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1476 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1477}
1478
1479TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1480 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1481 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1482}
1483
1484TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1485 MockRead read_failure(ASYNC, OK); // EOF
1486 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491487}
1488
[email protected]23e482282013-06-14 16:08:021489TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421490 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251491 request.method = "GET";
1492 request.url = GURL("http://www.google.com/");
1493 request.load_flags = 0;
1494
[email protected]3fe8d2f82013-10-17 08:56:071495 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271496 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071497 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271498
[email protected]3d2a59b2008-09-26 19:44:251499 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061500 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351501 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1502 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061503 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251504 };
[email protected]31a2bfe2010-02-09 08:03:391505 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071506 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251507
[email protected]49639fa2011-12-20 23:22:411508 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251509
[email protected]49639fa2011-12-20 23:22:411510 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421511 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251512
1513 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421514 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251515
[email protected]1c773ea12009-04-28 19:58:421516 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251517 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251518}
1519
1520// What do various browsers do when the server closes a non-keepalive
1521// connection without sending any response header or body?
1522//
1523// IE7: error page
1524// Safari 3.1.2 (Windows): error page
1525// Firefox 3.0.1: blank page
1526// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421527// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1528// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021529TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251530 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061531 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351532 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1533 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061534 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251535 };
[email protected]31a2bfe2010-02-09 08:03:391536 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1537 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421538 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251539}
[email protected]038e9a32008-10-08 22:40:161540
[email protected]1826a402014-01-08 15:40:481541// Test that network access can be deferred and resumed.
1542TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1543 HttpRequestInfo request;
1544 request.method = "GET";
1545 request.url = GURL("http://www.google.com/");
1546 request.load_flags = 0;
1547
1548 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1549 scoped_ptr<HttpTransaction> trans(
1550 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1551
1552 // Defer on OnBeforeNetworkStart.
1553 BeforeNetworkStartHandler net_start_handler(true); // defer
1554 trans->SetBeforeNetworkStartCallback(
1555 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1556 base::Unretained(&net_start_handler)));
1557
1558 MockRead data_reads[] = {
1559 MockRead("HTTP/1.0 200 OK\r\n"),
1560 MockRead("Content-Length: 5\r\n\r\n"),
1561 MockRead("hello"),
1562 MockRead(SYNCHRONOUS, 0),
1563 };
1564 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1565 session_deps_.socket_factory->AddSocketDataProvider(&data);
1566
1567 TestCompletionCallback callback;
1568
1569 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1570 EXPECT_EQ(ERR_IO_PENDING, rv);
1571 base::MessageLoop::current()->RunUntilIdle();
1572
1573 // Should have deferred for network start.
1574 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1575 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1576 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1577
1578 trans->ResumeNetworkStart();
1579 rv = callback.WaitForResult();
1580 EXPECT_EQ(OK, rv);
1581 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1582
1583 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1584 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1585 if (rv == ERR_IO_PENDING)
1586 rv = callback.WaitForResult();
1587 EXPECT_EQ(5, rv);
1588 trans.reset();
1589}
1590
1591// Test that network use can be deferred and canceled.
1592TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1593 HttpRequestInfo request;
1594 request.method = "GET";
1595 request.url = GURL("http://www.google.com/");
1596 request.load_flags = 0;
1597
1598 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1599 scoped_ptr<HttpTransaction> trans(
1600 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1601
1602 // Defer on OnBeforeNetworkStart.
1603 BeforeNetworkStartHandler net_start_handler(true); // defer
1604 trans->SetBeforeNetworkStartCallback(
1605 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1606 base::Unretained(&net_start_handler)));
1607
1608 TestCompletionCallback callback;
1609
1610 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1611 EXPECT_EQ(ERR_IO_PENDING, rv);
1612 base::MessageLoop::current()->RunUntilIdle();
1613
1614 // Should have deferred for network start.
1615 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1616 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1617 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1618}
1619
[email protected]7a5378b2012-11-04 03:25:171620// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1621// tests. There was a bug causing HttpNetworkTransaction to hang in the
1622// destructor in such situations.
1623// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021624TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171625 HttpRequestInfo request;
1626 request.method = "GET";
1627 request.url = GURL("http://www.google.com/");
1628 request.load_flags = 0;
1629
[email protected]bb88e1d32013-05-03 23:11:071630 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361631 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501632 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171633
1634 MockRead data_reads[] = {
1635 MockRead("HTTP/1.0 200 OK\r\n"),
1636 MockRead("Connection: keep-alive\r\n"),
1637 MockRead("Content-Length: 100\r\n\r\n"),
1638 MockRead("hello"),
1639 MockRead(SYNCHRONOUS, 0),
1640 };
1641 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071642 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171643
1644 TestCompletionCallback callback;
1645
1646 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1647 EXPECT_EQ(ERR_IO_PENDING, rv);
1648
1649 rv = callback.WaitForResult();
1650 EXPECT_EQ(OK, rv);
1651
1652 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501653 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171654 if (rv == ERR_IO_PENDING)
1655 rv = callback.WaitForResult();
1656 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501657 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171658 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1659
1660 trans.reset();
[email protected]2da659e2013-05-23 20:51:341661 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171662 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1663}
1664
[email protected]23e482282013-06-14 16:08:021665TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171666 HttpRequestInfo request;
1667 request.method = "GET";
1668 request.url = GURL("http://www.google.com/");
1669 request.load_flags = 0;
1670
[email protected]bb88e1d32013-05-03 23:11:071671 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361672 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501673 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171674
1675 MockRead data_reads[] = {
1676 MockRead("HTTP/1.0 200 OK\r\n"),
1677 MockRead("Connection: keep-alive\r\n"),
1678 MockRead("Content-Length: 100\r\n\r\n"),
1679 MockRead(SYNCHRONOUS, 0),
1680 };
1681 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071682 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171683
1684 TestCompletionCallback callback;
1685
1686 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1687 EXPECT_EQ(ERR_IO_PENDING, rv);
1688
1689 rv = callback.WaitForResult();
1690 EXPECT_EQ(OK, rv);
1691
1692 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501693 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171694 if (rv == ERR_IO_PENDING)
1695 rv = callback.WaitForResult();
1696 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1697
1698 trans.reset();
[email protected]2da659e2013-05-23 20:51:341699 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171700 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1701}
1702
[email protected]0b0bf032010-09-21 18:08:501703// Test that we correctly reuse a keep-alive connection after not explicitly
1704// reading the body.
[email protected]23e482282013-06-14 16:08:021705TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131706 HttpRequestInfo request;
1707 request.method = "GET";
1708 request.url = GURL("http://www.foo.com/");
1709 request.load_flags = 0;
1710
[email protected]58e32bb2013-01-21 18:23:251711 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071712 session_deps_.net_log = &net_log;
1713 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271714
[email protected]0b0bf032010-09-21 18:08:501715 // Note that because all these reads happen in the same
1716 // StaticSocketDataProvider, it shows that the same socket is being reused for
1717 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131718 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501719 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1720 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131721 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501722 MockRead("HTTP/1.1 302 Found\r\n"
1723 "Content-Length: 0\r\n\r\n"),
1724 MockRead("HTTP/1.1 302 Found\r\n"
1725 "Content-Length: 5\r\n\r\n"
1726 "hello"),
1727 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1728 "Content-Length: 0\r\n\r\n"),
1729 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1730 "Content-Length: 5\r\n\r\n"
1731 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131732 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1733 MockRead("hello"),
1734 };
1735 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131737
1738 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061739 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131740 };
1741 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071742 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131743
[email protected]0b0bf032010-09-21 18:08:501744 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1745 std::string response_lines[kNumUnreadBodies];
1746
[email protected]58e32bb2013-01-21 18:23:251747 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501748 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411749 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131750
[email protected]262eec82013-03-19 21:01:361751 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501752 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131753
[email protected]49639fa2011-12-20 23:22:411754 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131755 EXPECT_EQ(ERR_IO_PENDING, rv);
1756
1757 rv = callback.WaitForResult();
1758 EXPECT_EQ(OK, rv);
1759
[email protected]58e32bb2013-01-21 18:23:251760 LoadTimingInfo load_timing_info;
1761 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1762 if (i == 0) {
1763 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1764 first_socket_log_id = load_timing_info.socket_log_id;
1765 } else {
1766 TestLoadTimingReused(load_timing_info);
1767 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1768 }
1769
[email protected]fc31d6a42010-06-24 18:05:131770 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501771 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131772
[email protected]90499482013-06-01 00:39:501773 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501774 response_lines[i] = response->headers->GetStatusLine();
1775
1776 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131777 }
[email protected]0b0bf032010-09-21 18:08:501778
1779 const char* const kStatusLines[] = {
1780 "HTTP/1.1 204 No Content",
1781 "HTTP/1.1 205 Reset Content",
1782 "HTTP/1.1 304 Not Modified",
1783 "HTTP/1.1 302 Found",
1784 "HTTP/1.1 302 Found",
1785 "HTTP/1.1 301 Moved Permanently",
1786 "HTTP/1.1 301 Moved Permanently",
1787 };
1788
1789 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1790 forgot_to_update_kStatusLines);
1791
1792 for (int i = 0; i < kNumUnreadBodies; ++i)
1793 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1794
[email protected]49639fa2011-12-20 23:22:411795 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361796 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501797 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411798 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501799 EXPECT_EQ(ERR_IO_PENDING, rv);
1800 rv = callback.WaitForResult();
1801 EXPECT_EQ(OK, rv);
1802 const HttpResponseInfo* response = trans->GetResponseInfo();
1803 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501804 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501805 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1806 std::string response_data;
1807 rv = ReadTransaction(trans.get(), &response_data);
1808 EXPECT_EQ(OK, rv);
1809 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131810}
1811
[email protected]038e9a32008-10-08 22:40:161812// Test the request-challenge-retry sequence for basic auth.
1813// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021814TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421815 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161816 request.method = "GET";
1817 request.url = GURL("http://www.google.com/");
1818 request.load_flags = 0;
1819
[email protected]58e32bb2013-01-21 18:23:251820 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071821 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071822 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271823 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071824 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271825
[email protected]f9ee6b52008-11-08 06:46:231826 MockWrite data_writes1[] = {
1827 MockWrite("GET / HTTP/1.1\r\n"
1828 "Host: www.google.com\r\n"
1829 "Connection: keep-alive\r\n\r\n"),
1830 };
1831
[email protected]038e9a32008-10-08 22:40:161832 MockRead data_reads1[] = {
1833 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1834 // Give a couple authenticate options (only the middle one is actually
1835 // supported).
[email protected]22927ad2009-09-21 19:56:191836 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161837 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1838 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1839 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1840 // Large content-length -- won't matter, as connection will be reset.
1841 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061842 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161843 };
1844
1845 // After calling trans->RestartWithAuth(), this is the request we should
1846 // be issuing -- the final header line contains the credentials.
1847 MockWrite data_writes2[] = {
1848 MockWrite("GET / HTTP/1.1\r\n"
1849 "Host: www.google.com\r\n"
1850 "Connection: keep-alive\r\n"
1851 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1852 };
1853
1854 // Lastly, the server responds with the actual content.
1855 MockRead data_reads2[] = {
1856 MockRead("HTTP/1.0 200 OK\r\n"),
1857 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1858 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061859 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161860 };
1861
[email protected]31a2bfe2010-02-09 08:03:391862 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1863 data_writes1, arraysize(data_writes1));
1864 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1865 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071866 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1867 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161868
[email protected]49639fa2011-12-20 23:22:411869 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161870
[email protected]49639fa2011-12-20 23:22:411871 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421872 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161873
1874 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421875 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161876
[email protected]58e32bb2013-01-21 18:23:251877 LoadTimingInfo load_timing_info1;
1878 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1879 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1880
[email protected]b8015c42013-12-24 15:18:191881 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1882 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1883
[email protected]1c773ea12009-04-28 19:58:421884 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501885 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041886 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161887
[email protected]49639fa2011-12-20 23:22:411888 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161889
[email protected]49639fa2011-12-20 23:22:411890 rv = trans->RestartWithAuth(
1891 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421892 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161893
1894 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421895 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161896
[email protected]58e32bb2013-01-21 18:23:251897 LoadTimingInfo load_timing_info2;
1898 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1899 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1900 // The load timing after restart should have a new socket ID, and times after
1901 // those of the first load timing.
1902 EXPECT_LE(load_timing_info1.receive_headers_end,
1903 load_timing_info2.connect_timing.connect_start);
1904 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1905
[email protected]b8015c42013-12-24 15:18:191906 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1907 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1908
[email protected]038e9a32008-10-08 22:40:161909 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501910 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161911 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1912 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161913}
1914
[email protected]23e482282013-06-14 16:08:021915TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461916 HttpRequestInfo request;
1917 request.method = "GET";
1918 request.url = GURL("http://www.google.com/");
1919 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1920
[email protected]3fe8d2f82013-10-17 08:56:071921 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271922 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271924
[email protected]861fcd52009-08-26 02:33:461925 MockWrite data_writes[] = {
1926 MockWrite("GET / HTTP/1.1\r\n"
1927 "Host: www.google.com\r\n"
1928 "Connection: keep-alive\r\n\r\n"),
1929 };
1930
1931 MockRead data_reads[] = {
1932 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1933 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1934 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1935 // Large content-length -- won't matter, as connection will be reset.
1936 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061937 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461938 };
1939
[email protected]31a2bfe2010-02-09 08:03:391940 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1941 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071942 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411943 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461944
[email protected]49639fa2011-12-20 23:22:411945 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461946 EXPECT_EQ(ERR_IO_PENDING, rv);
1947
1948 rv = callback.WaitForResult();
1949 EXPECT_EQ(0, rv);
1950
[email protected]b8015c42013-12-24 15:18:191951 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
1952 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
1953
[email protected]861fcd52009-08-26 02:33:461954 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501955 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461956 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1957}
1958
[email protected]2d2697f92009-02-18 21:00:321959// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1960// connection.
[email protected]23e482282013-06-14 16:08:021961TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421962 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321963 request.method = "GET";
1964 request.url = GURL("http://www.google.com/");
1965 request.load_flags = 0;
1966
[email protected]58e32bb2013-01-21 18:23:251967 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071968 session_deps_.net_log = &log;
1969 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271970
[email protected]2d2697f92009-02-18 21:00:321971 MockWrite data_writes1[] = {
1972 MockWrite("GET / HTTP/1.1\r\n"
1973 "Host: www.google.com\r\n"
1974 "Connection: keep-alive\r\n\r\n"),
1975
1976 // After calling trans->RestartWithAuth(), this is the request we should
1977 // be issuing -- the final header line contains the credentials.
1978 MockWrite("GET / HTTP/1.1\r\n"
1979 "Host: www.google.com\r\n"
1980 "Connection: keep-alive\r\n"
1981 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1982 };
1983
1984 MockRead data_reads1[] = {
1985 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1986 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1987 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1988 MockRead("Content-Length: 14\r\n\r\n"),
1989 MockRead("Unauthorized\r\n"),
1990
1991 // Lastly, the server responds with the actual content.
1992 MockRead("HTTP/1.1 200 OK\r\n"),
1993 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501994 MockRead("Content-Length: 5\r\n\r\n"),
1995 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321996 };
1997
[email protected]2d0a4f92011-05-05 16:38:461998 // If there is a regression where we disconnect a Keep-Alive
1999 // connection during an auth roundtrip, we'll end up reading this.
2000 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062001 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462002 };
2003
[email protected]31a2bfe2010-02-09 08:03:392004 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2005 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462006 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2007 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072008 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2009 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322010
[email protected]49639fa2011-12-20 23:22:412011 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322012
[email protected]262eec82013-03-19 21:01:362013 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412015 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422016 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322017
2018 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422019 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322020
[email protected]58e32bb2013-01-21 18:23:252021 LoadTimingInfo load_timing_info1;
2022 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2023 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2024
[email protected]1c773ea12009-04-28 19:58:422025 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502026 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042027 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322028
[email protected]49639fa2011-12-20 23:22:412029 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322030
[email protected]49639fa2011-12-20 23:22:412031 rv = trans->RestartWithAuth(
2032 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422033 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322034
2035 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422036 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322037
[email protected]58e32bb2013-01-21 18:23:252038 LoadTimingInfo load_timing_info2;
2039 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2040 TestLoadTimingReused(load_timing_info2);
2041 // The load timing after restart should have the same socket ID, and times
2042 // those of the first load timing.
2043 EXPECT_LE(load_timing_info1.receive_headers_end,
2044 load_timing_info2.send_start);
2045 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2046
[email protected]2d2697f92009-02-18 21:00:322047 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502048 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322049 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502050 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192051
2052 std::string response_data;
2053 rv = ReadTransaction(trans.get(), &response_data);
2054 EXPECT_EQ(OK, rv);
2055 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2056 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322057}
2058
2059// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2060// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022061TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422062 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322063 request.method = "GET";
2064 request.url = GURL("http://www.google.com/");
2065 request.load_flags = 0;
2066
[email protected]bb88e1d32013-05-03 23:11:072067 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272068
[email protected]2d2697f92009-02-18 21:00:322069 MockWrite data_writes1[] = {
2070 MockWrite("GET / HTTP/1.1\r\n"
2071 "Host: www.google.com\r\n"
2072 "Connection: keep-alive\r\n\r\n"),
2073
2074 // After calling trans->RestartWithAuth(), this is the request we should
2075 // be issuing -- the final header line contains the credentials.
2076 MockWrite("GET / HTTP/1.1\r\n"
2077 "Host: www.google.com\r\n"
2078 "Connection: keep-alive\r\n"
2079 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2080 };
2081
[email protected]2d2697f92009-02-18 21:00:322082 MockRead data_reads1[] = {
2083 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2084 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312085 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322086
2087 // Lastly, the server responds with the actual content.
2088 MockRead("HTTP/1.1 200 OK\r\n"),
2089 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502090 MockRead("Content-Length: 5\r\n\r\n"),
2091 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322092 };
2093
[email protected]2d0a4f92011-05-05 16:38:462094 // An incorrect reconnect would cause this to be read.
2095 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062096 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462097 };
2098
[email protected]31a2bfe2010-02-09 08:03:392099 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2100 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462101 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2102 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072103 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2104 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322105
[email protected]49639fa2011-12-20 23:22:412106 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322107
[email protected]262eec82013-03-19 21:01:362108 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412110 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422111 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322112
2113 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422114 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322115
[email protected]1c773ea12009-04-28 19:58:422116 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502117 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042118 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322119
[email protected]49639fa2011-12-20 23:22:412120 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322121
[email protected]49639fa2011-12-20 23:22:412122 rv = trans->RestartWithAuth(
2123 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422124 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322125
2126 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422127 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322128
2129 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502130 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322131 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502132 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322133}
2134
2135// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2136// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022137TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422138 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322139 request.method = "GET";
2140 request.url = GURL("http://www.google.com/");
2141 request.load_flags = 0;
2142
[email protected]bb88e1d32013-05-03 23:11:072143 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272144
[email protected]2d2697f92009-02-18 21:00:322145 MockWrite data_writes1[] = {
2146 MockWrite("GET / HTTP/1.1\r\n"
2147 "Host: www.google.com\r\n"
2148 "Connection: keep-alive\r\n\r\n"),
2149
2150 // After calling trans->RestartWithAuth(), this is the request we should
2151 // be issuing -- the final header line contains the credentials.
2152 MockWrite("GET / HTTP/1.1\r\n"
2153 "Host: www.google.com\r\n"
2154 "Connection: keep-alive\r\n"
2155 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2156 };
2157
2158 // Respond with 5 kb of response body.
2159 std::string large_body_string("Unauthorized");
2160 large_body_string.append(5 * 1024, ' ');
2161 large_body_string.append("\r\n");
2162
2163 MockRead data_reads1[] = {
2164 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2165 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2166 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2167 // 5134 = 12 + 5 * 1024 + 2
2168 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062169 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322170
2171 // Lastly, the server responds with the actual content.
2172 MockRead("HTTP/1.1 200 OK\r\n"),
2173 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502174 MockRead("Content-Length: 5\r\n\r\n"),
2175 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322176 };
2177
[email protected]2d0a4f92011-05-05 16:38:462178 // An incorrect reconnect would cause this to be read.
2179 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062180 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462181 };
2182
[email protected]31a2bfe2010-02-09 08:03:392183 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2184 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462185 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2186 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072187 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2188 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322189
[email protected]49639fa2011-12-20 23:22:412190 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322191
[email protected]262eec82013-03-19 21:01:362192 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502193 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412194 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422195 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322196
2197 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422198 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322199
[email protected]1c773ea12009-04-28 19:58:422200 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502201 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042202 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322203
[email protected]49639fa2011-12-20 23:22:412204 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322205
[email protected]49639fa2011-12-20 23:22:412206 rv = trans->RestartWithAuth(
2207 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422208 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322209
2210 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422211 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322212
2213 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502214 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322215 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502216 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322217}
2218
2219// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312220// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022221TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312222 HttpRequestInfo request;
2223 request.method = "GET";
2224 request.url = GURL("http://www.google.com/");
2225 request.load_flags = 0;
2226
[email protected]bb88e1d32013-05-03 23:11:072227 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272228
[email protected]11203f012009-11-12 23:02:312229 MockWrite data_writes1[] = {
2230 MockWrite("GET / HTTP/1.1\r\n"
2231 "Host: www.google.com\r\n"
2232 "Connection: keep-alive\r\n\r\n"),
2233 // This simulates the seemingly successful write to a closed connection
2234 // if the bug is not fixed.
2235 MockWrite("GET / HTTP/1.1\r\n"
2236 "Host: www.google.com\r\n"
2237 "Connection: keep-alive\r\n"
2238 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2239 };
2240
2241 MockRead data_reads1[] = {
2242 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2243 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2244 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2245 MockRead("Content-Length: 14\r\n\r\n"),
2246 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062247 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312248 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062249 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312250 };
2251
2252 // After calling trans->RestartWithAuth(), this is the request we should
2253 // be issuing -- the final header line contains the credentials.
2254 MockWrite data_writes2[] = {
2255 MockWrite("GET / HTTP/1.1\r\n"
2256 "Host: www.google.com\r\n"
2257 "Connection: keep-alive\r\n"
2258 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2259 };
2260
2261 // Lastly, the server responds with the actual content.
2262 MockRead data_reads2[] = {
2263 MockRead("HTTP/1.1 200 OK\r\n"),
2264 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502265 MockRead("Content-Length: 5\r\n\r\n"),
2266 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312267 };
2268
[email protected]31a2bfe2010-02-09 08:03:392269 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2270 data_writes1, arraysize(data_writes1));
2271 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2272 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072273 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2274 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312275
[email protected]49639fa2011-12-20 23:22:412276 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312277
[email protected]262eec82013-03-19 21:01:362278 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502279 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412280 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312281 EXPECT_EQ(ERR_IO_PENDING, rv);
2282
2283 rv = callback1.WaitForResult();
2284 EXPECT_EQ(OK, rv);
2285
2286 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502287 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042288 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312289
[email protected]49639fa2011-12-20 23:22:412290 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312291
[email protected]49639fa2011-12-20 23:22:412292 rv = trans->RestartWithAuth(
2293 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312294 EXPECT_EQ(ERR_IO_PENDING, rv);
2295
2296 rv = callback2.WaitForResult();
2297 EXPECT_EQ(OK, rv);
2298
2299 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502300 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312301 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502302 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312303}
2304
[email protected]394816e92010-08-03 07:38:592305// Test the request-challenge-retry sequence for basic auth, over a connection
2306// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022307TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:592308 HttpRequestInfo request;
2309 request.method = "GET";
2310 request.url = GURL("https://www.google.com/");
2311 // when the no authentication data flag is set.
2312 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2313
[email protected]cb9bf6ca2011-01-28 13:15:272314 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072315 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202316 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292317 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072318 session_deps_.net_log = log.bound().net_log();
2319 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272320
[email protected]394816e92010-08-03 07:38:592321 // Since we have proxy, should try to establish tunnel.
2322 MockWrite data_writes1[] = {
2323 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2324 "Host: www.google.com\r\n"
2325 "Proxy-Connection: keep-alive\r\n\r\n"),
2326
2327 // After calling trans->RestartWithAuth(), this is the request we should
2328 // be issuing -- the final header line contains the credentials.
2329 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2330 "Host: www.google.com\r\n"
2331 "Proxy-Connection: keep-alive\r\n"
2332 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2333
2334 MockWrite("GET / HTTP/1.1\r\n"
2335 "Host: www.google.com\r\n"
2336 "Connection: keep-alive\r\n\r\n"),
2337 };
2338
2339 // The proxy responds to the connect with a 407, using a persistent
2340 // connection.
2341 MockRead data_reads1[] = {
2342 // No credentials.
2343 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2344 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2345 MockRead("Proxy-Connection: close\r\n\r\n"),
2346
2347 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2348
2349 MockRead("HTTP/1.1 200 OK\r\n"),
2350 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502351 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062352 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592353 };
2354
2355 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2356 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072357 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062358 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592360
[email protected]49639fa2011-12-20 23:22:412361 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592362
[email protected]262eec82013-03-19 21:01:362363 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502365
[email protected]49639fa2011-12-20 23:22:412366 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592367 EXPECT_EQ(ERR_IO_PENDING, rv);
2368
2369 rv = callback1.WaitForResult();
2370 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572371 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402372 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592373 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402374 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592375 NetLog::PHASE_NONE);
2376 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402377 entries, pos,
[email protected]394816e92010-08-03 07:38:592378 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2379 NetLog::PHASE_NONE);
2380
2381 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502382 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502383 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592384 EXPECT_EQ(407, response->headers->response_code());
2385 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042386 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592387
[email protected]029c83b62013-01-24 05:28:202388 LoadTimingInfo load_timing_info;
2389 // CONNECT requests and responses are handled at the connect job level, so
2390 // the transaction does not yet have a connection.
2391 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2392
[email protected]49639fa2011-12-20 23:22:412393 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592394
[email protected]49639fa2011-12-20 23:22:412395 rv = trans->RestartWithAuth(
2396 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592397 EXPECT_EQ(ERR_IO_PENDING, rv);
2398
2399 rv = callback2.WaitForResult();
2400 EXPECT_EQ(OK, rv);
2401
2402 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502403 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592404
2405 EXPECT_TRUE(response->headers->IsKeepAlive());
2406 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502407 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592408 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2409
2410 // The password prompt info should not be set.
2411 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502412
[email protected]029c83b62013-01-24 05:28:202413 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2414 TestLoadTimingNotReusedWithPac(load_timing_info,
2415 CONNECT_TIMING_HAS_SSL_TIMES);
2416
[email protected]0b0bf032010-09-21 18:08:502417 trans.reset();
[email protected]102e27c2011-02-23 01:01:312418 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592419}
2420
[email protected]11203f012009-11-12 23:02:312421// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322422// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022423TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272424 HttpRequestInfo request;
2425 request.method = "GET";
2426 request.url = GURL("https://www.google.com/");
2427 // Ensure that proxy authentication is attempted even
2428 // when the no authentication data flag is set.
2429 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2430
[email protected]2d2697f92009-02-18 21:00:322431 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072432 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292433 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072434 session_deps_.net_log = log.bound().net_log();
2435 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322436
[email protected]262eec82013-03-19 21:01:362437 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502438 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322439
[email protected]2d2697f92009-02-18 21:00:322440 // Since we have proxy, should try to establish tunnel.
2441 MockWrite data_writes1[] = {
2442 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452443 "Host: www.google.com\r\n"
2444 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322445
2446 // After calling trans->RestartWithAuth(), this is the request we should
2447 // be issuing -- the final header line contains the credentials.
2448 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2449 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452450 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322451 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2452 };
2453
2454 // The proxy responds to the connect with a 407, using a persistent
2455 // connection.
2456 MockRead data_reads1[] = {
2457 // No credentials.
2458 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2459 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2460 MockRead("Content-Length: 10\r\n\r\n"),
2461 MockRead("0123456789"),
2462
2463 // Wrong credentials (wrong password).
2464 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2465 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2466 MockRead("Content-Length: 10\r\n\r\n"),
2467 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062468 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322469 };
2470
[email protected]31a2bfe2010-02-09 08:03:392471 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2472 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322474
[email protected]49639fa2011-12-20 23:22:412475 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322476
[email protected]49639fa2011-12-20 23:22:412477 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422478 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322479
2480 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422481 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572482 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402483 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392484 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402485 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392486 NetLog::PHASE_NONE);
2487 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402488 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392489 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2490 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322491
[email protected]1c773ea12009-04-28 19:58:422492 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502493 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502494 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322495 EXPECT_TRUE(response->headers->IsKeepAlive());
2496 EXPECT_EQ(407, response->headers->response_code());
2497 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422498 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042499 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322500
[email protected]49639fa2011-12-20 23:22:412501 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322502
2503 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412504 rv = trans->RestartWithAuth(
2505 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422506 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322507
2508 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422509 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322510
2511 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502512 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502513 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322514 EXPECT_TRUE(response->headers->IsKeepAlive());
2515 EXPECT_EQ(407, response->headers->response_code());
2516 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422517 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042518 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132519
[email protected]e60e47a2010-07-14 03:37:182520 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2521 // out of scope.
[email protected]102e27c2011-02-23 01:01:312522 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322523}
2524
[email protected]a8e9b162009-03-12 00:06:442525// Test that we don't read the response body when we fail to establish a tunnel,
2526// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022527TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272528 HttpRequestInfo request;
2529 request.method = "GET";
2530 request.url = GURL("https://www.google.com/");
2531 request.load_flags = 0;
2532
[email protected]a8e9b162009-03-12 00:06:442533 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072534 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442535
[email protected]bb88e1d32013-05-03 23:11:072536 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442537
[email protected]262eec82013-03-19 21:01:362538 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442540
[email protected]a8e9b162009-03-12 00:06:442541 // Since we have proxy, should try to establish tunnel.
2542 MockWrite data_writes[] = {
2543 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452544 "Host: www.google.com\r\n"
2545 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442546 };
2547
2548 // The proxy responds to the connect with a 407.
2549 MockRead data_reads[] = {
2550 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2551 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2552 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062553 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442554 };
2555
[email protected]31a2bfe2010-02-09 08:03:392556 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2557 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072558 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442559
[email protected]49639fa2011-12-20 23:22:412560 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442561
[email protected]49639fa2011-12-20 23:22:412562 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422563 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442564
2565 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422566 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442567
[email protected]1c773ea12009-04-28 19:58:422568 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502569 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442570
2571 EXPECT_TRUE(response->headers->IsKeepAlive());
2572 EXPECT_EQ(407, response->headers->response_code());
2573 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422574 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442575
2576 std::string response_data;
2577 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422578 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182579
2580 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312581 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442582}
2583
[email protected]8fdbcd22010-05-05 02:54:522584// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2585// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022586TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522587 HttpRequestInfo request;
2588 request.method = "GET";
2589 request.url = GURL("http://www.google.com/");
2590 request.load_flags = 0;
2591
[email protected]cb9bf6ca2011-01-28 13:15:272592 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072593 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272594 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:072595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:272596
[email protected]8fdbcd22010-05-05 02:54:522597 MockWrite data_writes1[] = {
2598 MockWrite("GET / HTTP/1.1\r\n"
2599 "Host: www.google.com\r\n"
2600 "Connection: keep-alive\r\n\r\n"),
2601 };
2602
2603 MockRead data_reads1[] = {
2604 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2605 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2606 // Large content-length -- won't matter, as connection will be reset.
2607 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062608 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522609 };
2610
2611 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2612 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072613 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522614
[email protected]49639fa2011-12-20 23:22:412615 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522616
[email protected]49639fa2011-12-20 23:22:412617 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522618 EXPECT_EQ(ERR_IO_PENDING, rv);
2619
2620 rv = callback.WaitForResult();
2621 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2622}
2623
[email protected]7a67a8152010-11-05 18:31:102624// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2625// through a non-authenticating proxy. The request should fail with
2626// ERR_UNEXPECTED_PROXY_AUTH.
2627// Note that it is impossible to detect if an HTTP server returns a 407 through
2628// a non-authenticating proxy - there is nothing to indicate whether the
2629// response came from the proxy or the server, so it is treated as if the proxy
2630// issued the challenge.
[email protected]23e482282013-06-14 16:08:022631TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232632 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272633 HttpRequestInfo request;
2634 request.method = "GET";
2635 request.url = GURL("https://www.google.com/");
2636
[email protected]bb88e1d32013-05-03 23:11:072637 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292638 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072639 session_deps_.net_log = log.bound().net_log();
2640 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102641
[email protected]7a67a8152010-11-05 18:31:102642 // Since we have proxy, should try to establish tunnel.
2643 MockWrite data_writes1[] = {
2644 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2645 "Host: www.google.com\r\n"
2646 "Proxy-Connection: keep-alive\r\n\r\n"),
2647
2648 MockWrite("GET / HTTP/1.1\r\n"
2649 "Host: www.google.com\r\n"
2650 "Connection: keep-alive\r\n\r\n"),
2651 };
2652
2653 MockRead data_reads1[] = {
2654 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2655
2656 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2657 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2658 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062659 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102660 };
2661
2662 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2663 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072664 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062665 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072666 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102667
[email protected]49639fa2011-12-20 23:22:412668 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102669
[email protected]262eec82013-03-19 21:01:362670 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502671 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102672
[email protected]49639fa2011-12-20 23:22:412673 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102674 EXPECT_EQ(ERR_IO_PENDING, rv);
2675
2676 rv = callback1.WaitForResult();
2677 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572678 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402679 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102680 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402681 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102682 NetLog::PHASE_NONE);
2683 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402684 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102685 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2686 NetLog::PHASE_NONE);
2687}
[email protected]2df19bb2010-08-25 20:13:462688
[email protected]029c83b62013-01-24 05:28:202689// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022690TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202691 HttpRequestInfo request1;
2692 request1.method = "GET";
2693 request1.url = GURL("https://www.google.com/1");
2694
2695 HttpRequestInfo request2;
2696 request2.method = "GET";
2697 request2.url = GURL("https://www.google.com/2");
2698
2699 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072700 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202701 ProxyService::CreateFixed("PROXY myproxy:70"));
2702 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072703 session_deps_.net_log = log.bound().net_log();
2704 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202705
2706 // Since we have proxy, should try to establish tunnel.
2707 MockWrite data_writes1[] = {
2708 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2709 "Host: www.google.com\r\n"
2710 "Proxy-Connection: keep-alive\r\n\r\n"),
2711
2712 MockWrite("GET /1 HTTP/1.1\r\n"
2713 "Host: www.google.com\r\n"
2714 "Connection: keep-alive\r\n\r\n"),
2715
2716 MockWrite("GET /2 HTTP/1.1\r\n"
2717 "Host: www.google.com\r\n"
2718 "Connection: keep-alive\r\n\r\n"),
2719 };
2720
2721 // The proxy responds to the connect with a 407, using a persistent
2722 // connection.
2723 MockRead data_reads1[] = {
2724 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2725
2726 MockRead("HTTP/1.1 200 OK\r\n"),
2727 MockRead("Content-Length: 1\r\n\r\n"),
2728 MockRead(SYNCHRONOUS, "1"),
2729
2730 MockRead("HTTP/1.1 200 OK\r\n"),
2731 MockRead("Content-Length: 2\r\n\r\n"),
2732 MockRead(SYNCHRONOUS, "22"),
2733 };
2734
2735 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2736 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072737 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202738 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072739 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202740
2741 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362742 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502743 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202744
2745 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2746 EXPECT_EQ(ERR_IO_PENDING, rv);
2747
2748 rv = callback1.WaitForResult();
2749 EXPECT_EQ(OK, rv);
2750
2751 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2752 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502753 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202754 EXPECT_EQ(1, response1->headers->GetContentLength());
2755
2756 LoadTimingInfo load_timing_info1;
2757 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2758 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2759
2760 trans1.reset();
2761
2762 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362763 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502764 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202765
2766 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2767 EXPECT_EQ(ERR_IO_PENDING, rv);
2768
2769 rv = callback2.WaitForResult();
2770 EXPECT_EQ(OK, rv);
2771
2772 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2773 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502774 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202775 EXPECT_EQ(2, response2->headers->GetContentLength());
2776
2777 LoadTimingInfo load_timing_info2;
2778 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2779 TestLoadTimingReused(load_timing_info2);
2780
2781 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2782
2783 trans2.reset();
2784 session->CloseAllConnections();
2785}
2786
2787// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022788TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202789 HttpRequestInfo request1;
2790 request1.method = "GET";
2791 request1.url = GURL("https://www.google.com/1");
2792
2793 HttpRequestInfo request2;
2794 request2.method = "GET";
2795 request2.url = GURL("https://www.google.com/2");
2796
2797 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072798 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202799 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2800 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072801 session_deps_.net_log = log.bound().net_log();
2802 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202803
2804 // Since we have proxy, should try to establish tunnel.
2805 MockWrite data_writes1[] = {
2806 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2807 "Host: www.google.com\r\n"
2808 "Proxy-Connection: keep-alive\r\n\r\n"),
2809
2810 MockWrite("GET /1 HTTP/1.1\r\n"
2811 "Host: www.google.com\r\n"
2812 "Connection: keep-alive\r\n\r\n"),
2813
2814 MockWrite("GET /2 HTTP/1.1\r\n"
2815 "Host: www.google.com\r\n"
2816 "Connection: keep-alive\r\n\r\n"),
2817 };
2818
2819 // The proxy responds to the connect with a 407, using a persistent
2820 // connection.
2821 MockRead data_reads1[] = {
2822 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2823
2824 MockRead("HTTP/1.1 200 OK\r\n"),
2825 MockRead("Content-Length: 1\r\n\r\n"),
2826 MockRead(SYNCHRONOUS, "1"),
2827
2828 MockRead("HTTP/1.1 200 OK\r\n"),
2829 MockRead("Content-Length: 2\r\n\r\n"),
2830 MockRead(SYNCHRONOUS, "22"),
2831 };
2832
2833 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2834 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072835 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202836 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202838
2839 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362840 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502841 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202842
2843 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2844 EXPECT_EQ(ERR_IO_PENDING, rv);
2845
2846 rv = callback1.WaitForResult();
2847 EXPECT_EQ(OK, rv);
2848
2849 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2850 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502851 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202852 EXPECT_EQ(1, response1->headers->GetContentLength());
2853
2854 LoadTimingInfo load_timing_info1;
2855 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2856 TestLoadTimingNotReusedWithPac(load_timing_info1,
2857 CONNECT_TIMING_HAS_SSL_TIMES);
2858
2859 trans1.reset();
2860
2861 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362862 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502863 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202864
2865 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2866 EXPECT_EQ(ERR_IO_PENDING, rv);
2867
2868 rv = callback2.WaitForResult();
2869 EXPECT_EQ(OK, rv);
2870
2871 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2872 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502873 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202874 EXPECT_EQ(2, response2->headers->GetContentLength());
2875
2876 LoadTimingInfo load_timing_info2;
2877 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2878 TestLoadTimingReusedWithPac(load_timing_info2);
2879
2880 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2881
2882 trans2.reset();
2883 session->CloseAllConnections();
2884}
2885
[email protected]2df19bb2010-08-25 20:13:462886// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022887TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272888 HttpRequestInfo request;
2889 request.method = "GET";
2890 request.url = GURL("http://www.google.com/");
2891
[email protected]2df19bb2010-08-25 20:13:462892 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072893 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112894 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292895 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072896 session_deps_.net_log = log.bound().net_log();
2897 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462898
[email protected]2df19bb2010-08-25 20:13:462899 // Since we have proxy, should use full url
2900 MockWrite data_writes1[] = {
2901 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2902 "Host: www.google.com\r\n"
2903 "Proxy-Connection: keep-alive\r\n\r\n"),
2904 };
2905
2906 MockRead data_reads1[] = {
2907 MockRead("HTTP/1.1 200 OK\r\n"),
2908 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2909 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062910 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462911 };
2912
2913 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2914 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072915 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062916 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072917 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462918
[email protected]49639fa2011-12-20 23:22:412919 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462920
[email protected]262eec82013-03-19 21:01:362921 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502923
[email protected]49639fa2011-12-20 23:22:412924 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462925 EXPECT_EQ(ERR_IO_PENDING, rv);
2926
2927 rv = callback1.WaitForResult();
2928 EXPECT_EQ(OK, rv);
2929
[email protected]58e32bb2013-01-21 18:23:252930 LoadTimingInfo load_timing_info;
2931 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2932 TestLoadTimingNotReused(load_timing_info,
2933 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2934
[email protected]2df19bb2010-08-25 20:13:462935 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502936 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462937
2938 EXPECT_TRUE(response->headers->IsKeepAlive());
2939 EXPECT_EQ(200, response->headers->response_code());
2940 EXPECT_EQ(100, response->headers->GetContentLength());
2941 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2942
2943 // The password prompt info should not be set.
2944 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2945}
2946
[email protected]7642b5ae2010-09-01 20:55:172947// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022948TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272949 HttpRequestInfo request;
2950 request.method = "GET";
2951 request.url = GURL("http://www.google.com/");
2952 request.load_flags = 0;
2953
[email protected]7642b5ae2010-09-01 20:55:172954 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072955 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112956 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292957 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072958 session_deps_.net_log = log.bound().net_log();
2959 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172960
[email protected]7642b5ae2010-09-01 20:55:172961 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462962 scoped_ptr<SpdyFrame> req(
2963 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172964 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2965
[email protected]23e482282013-06-14 16:08:022966 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2967 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172968 MockRead spdy_reads[] = {
2969 CreateMockRead(*resp),
2970 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062971 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172972 };
2973
[email protected]dd54bd82012-07-19 23:44:572974 DelayedSocketData spdy_data(
2975 1, // wait for one write to finish before reading.
2976 spdy_reads, arraysize(spdy_reads),
2977 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072978 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172979
[email protected]8ddf8322012-02-23 18:08:062980 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022981 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072982 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172983
[email protected]49639fa2011-12-20 23:22:412984 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172985
[email protected]262eec82013-03-19 21:01:362986 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502987 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502988
[email protected]49639fa2011-12-20 23:22:412989 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172990 EXPECT_EQ(ERR_IO_PENDING, rv);
2991
2992 rv = callback1.WaitForResult();
2993 EXPECT_EQ(OK, rv);
2994
[email protected]58e32bb2013-01-21 18:23:252995 LoadTimingInfo load_timing_info;
2996 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2997 TestLoadTimingNotReused(load_timing_info,
2998 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2999
[email protected]7642b5ae2010-09-01 20:55:173000 const HttpResponseInfo* response = trans->GetResponseInfo();
3001 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503002 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173003 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3004
3005 std::string response_data;
3006 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233007 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173008}
3009
[email protected]dc7bd1c52010-11-12 00:01:133010// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023011TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273012 HttpRequestInfo request;
3013 request.method = "GET";
3014 request.url = GURL("http://www.google.com/");
3015 request.load_flags = 0;
3016
[email protected]79cb5c12011-09-12 13:12:043017 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073018 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043019 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293020 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073021 session_deps_.net_log = log.bound().net_log();
3022 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133023
[email protected]dc7bd1c52010-11-12 00:01:133024 // The first request will be a bare GET, the second request will be a
3025 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193026 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463027 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133028 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463029 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133030 };
[email protected]ff98d7f02012-03-22 21:44:193031 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463032 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3033 arraysize(kExtraAuthorizationHeaders) / 2,
3034 false,
3035 3,
3036 LOWEST,
3037 false));
[email protected]dc7bd1c52010-11-12 00:01:133038 MockWrite spdy_writes[] = {
3039 CreateMockWrite(*req_get, 1),
3040 CreateMockWrite(*req_get_authorization, 4),
3041 };
3042
3043 // The first response is a 407 proxy authentication challenge, and the second
3044 // response will be a 200 response since the second request includes a valid
3045 // Authorization header.
3046 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463047 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133048 };
[email protected]ff98d7f02012-03-22 21:44:193049 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023050 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133051 "407 Proxy Authentication Required",
3052 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3053 1));
[email protected]ff98d7f02012-03-22 21:44:193054 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023055 spdy_util_.ConstructSpdyBodyFrame(1, true));
3056 scoped_ptr<SpdyFrame> resp_data(
3057 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3058 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133059 MockRead spdy_reads[] = {
3060 CreateMockRead(*resp_authentication, 2),
3061 CreateMockRead(*body_authentication, 3),
3062 CreateMockRead(*resp_data, 5),
3063 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:063064 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:133065 };
3066
[email protected]dd54bd82012-07-19 23:44:573067 OrderedSocketData data(
3068 spdy_reads, arraysize(spdy_reads),
3069 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073070 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133071
[email protected]8ddf8322012-02-23 18:08:063072 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023073 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133075
[email protected]49639fa2011-12-20 23:22:413076 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133077
[email protected]262eec82013-03-19 21:01:363078 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133080
[email protected]49639fa2011-12-20 23:22:413081 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133082 EXPECT_EQ(ERR_IO_PENDING, rv);
3083
3084 rv = callback1.WaitForResult();
3085 EXPECT_EQ(OK, rv);
3086
3087 const HttpResponseInfo* const response = trans->GetResponseInfo();
3088
3089 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503090 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133091 EXPECT_EQ(407, response->headers->response_code());
3092 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043093 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133094
[email protected]49639fa2011-12-20 23:22:413095 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133096
[email protected]49639fa2011-12-20 23:22:413097 rv = trans->RestartWithAuth(
3098 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133099 EXPECT_EQ(ERR_IO_PENDING, rv);
3100
3101 rv = callback2.WaitForResult();
3102 EXPECT_EQ(OK, rv);
3103
3104 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3105
3106 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503107 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133108 EXPECT_EQ(200, response_restart->headers->response_code());
3109 // The password prompt info should not be set.
3110 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3111}
3112
[email protected]d9da5fe2010-10-13 22:37:163113// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023114TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273115 HttpRequestInfo request;
3116 request.method = "GET";
3117 request.url = GURL("https://www.google.com/");
3118 request.load_flags = 0;
3119
[email protected]d9da5fe2010-10-13 22:37:163120 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073121 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113122 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293123 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073124 session_deps_.net_log = log.bound().net_log();
3125 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163126
[email protected]262eec82013-03-19 21:01:363127 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163129
[email protected]d9da5fe2010-10-13 22:37:163130 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543131 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3132 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163133 // fetch https://www.google.com/ via HTTP
3134
3135 const char get[] = "GET / HTTP/1.1\r\n"
3136 "Host: www.google.com\r\n"
3137 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193138 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023139 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3140 scoped_ptr<SpdyFrame> conn_resp(
3141 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163142 const char resp[] = "HTTP/1.1 200 OK\r\n"
3143 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193144 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023145 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193146 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023147 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193148 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203149 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043150
3151 MockWrite spdy_writes[] = {
3152 CreateMockWrite(*connect, 1),
3153 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:463154 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:043155 };
3156
[email protected]d9da5fe2010-10-13 22:37:163157 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063158 CreateMockRead(*conn_resp, 2, ASYNC),
3159 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3160 CreateMockRead(*wrapped_body, 6, ASYNC),
3161 CreateMockRead(*wrapped_body, 7, ASYNC),
3162 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163163 };
3164
[email protected]dd54bd82012-07-19 23:44:573165 OrderedSocketData spdy_data(
3166 spdy_reads, arraysize(spdy_reads),
3167 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073168 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163169
[email protected]8ddf8322012-02-23 18:08:063170 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023171 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073172 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063173 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163174 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463175 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073176 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163177
[email protected]49639fa2011-12-20 23:22:413178 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163179
[email protected]49639fa2011-12-20 23:22:413180 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163181 EXPECT_EQ(ERR_IO_PENDING, rv);
3182
3183 rv = callback1.WaitForResult();
3184 EXPECT_EQ(OK, rv);
3185
[email protected]58e32bb2013-01-21 18:23:253186 LoadTimingInfo load_timing_info;
3187 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3188 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3189
[email protected]d9da5fe2010-10-13 22:37:163190 const HttpResponseInfo* response = trans->GetResponseInfo();
3191 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503192 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163193 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3194
3195 std::string response_data;
3196 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3197 EXPECT_EQ("1234567890", response_data);
3198}
3199
3200// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023201TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273202 HttpRequestInfo request;
3203 request.method = "GET";
3204 request.url = GURL("https://www.google.com/");
3205 request.load_flags = 0;
3206
[email protected]d9da5fe2010-10-13 22:37:163207 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073208 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113209 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293210 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073211 session_deps_.net_log = log.bound().net_log();
3212 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163213
[email protected]262eec82013-03-19 21:01:363214 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163216
[email protected]d9da5fe2010-10-13 22:37:163217 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543218 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3219 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163220 // fetch https://www.google.com/ via SPDY
3221 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463222 scoped_ptr<SpdyFrame> get(
3223 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023224 scoped_ptr<SpdyFrame> wrapped_get(
3225 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3226 scoped_ptr<SpdyFrame> conn_resp(
3227 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3228 scoped_ptr<SpdyFrame> get_resp(
3229 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193230 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023231 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3232 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3233 scoped_ptr<SpdyFrame> wrapped_body(
3234 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193235 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203236 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193237 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203238 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043239
3240 MockWrite spdy_writes[] = {
3241 CreateMockWrite(*connect, 1),
3242 CreateMockWrite(*wrapped_get, 3),
3243 CreateMockWrite(*window_update_get_resp, 5),
3244 CreateMockWrite(*window_update_body, 7),
3245 };
3246
[email protected]d9da5fe2010-10-13 22:37:163247 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063248 CreateMockRead(*conn_resp, 2, ASYNC),
3249 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3250 CreateMockRead(*wrapped_body, 6, ASYNC),
3251 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163252 };
3253
[email protected]dd54bd82012-07-19 23:44:573254 OrderedSocketData spdy_data(
3255 spdy_reads, arraysize(spdy_reads),
3256 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073257 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163258
[email protected]8ddf8322012-02-23 18:08:063259 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023260 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063262 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023263 ssl2.SetNextProto(GetParam());
3264 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073265 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163266
[email protected]49639fa2011-12-20 23:22:413267 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163268
[email protected]49639fa2011-12-20 23:22:413269 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163270 EXPECT_EQ(ERR_IO_PENDING, rv);
3271
3272 rv = callback1.WaitForResult();
3273 EXPECT_EQ(OK, rv);
3274
[email protected]58e32bb2013-01-21 18:23:253275 LoadTimingInfo load_timing_info;
3276 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3277 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3278
[email protected]d9da5fe2010-10-13 22:37:163279 const HttpResponseInfo* response = trans->GetResponseInfo();
3280 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503281 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163282 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3283
3284 std::string response_data;
3285 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233286 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163287}
3288
3289// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023290TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273291 HttpRequestInfo request;
3292 request.method = "GET";
3293 request.url = GURL("https://www.google.com/");
3294 request.load_flags = 0;
3295
[email protected]d9da5fe2010-10-13 22:37:163296 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073297 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113298 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293299 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073300 session_deps_.net_log = log.bound().net_log();
3301 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163302
[email protected]262eec82013-03-19 21:01:363303 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163305
[email protected]d9da5fe2010-10-13 22:37:163306 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543307 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3308 LOWEST));
[email protected]c10b20852013-05-15 21:29:203309 scoped_ptr<SpdyFrame> get(
3310 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163311
3312 MockWrite spdy_writes[] = {
3313 CreateMockWrite(*connect, 1),
3314 CreateMockWrite(*get, 3),
3315 };
3316
[email protected]23e482282013-06-14 16:08:023317 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3318 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163319 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063320 CreateMockRead(*resp, 2, ASYNC),
3321 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163322 };
3323
[email protected]dd54bd82012-07-19 23:44:573324 OrderedSocketData spdy_data(
3325 spdy_reads, arraysize(spdy_reads),
3326 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073327 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163328
[email protected]8ddf8322012-02-23 18:08:063329 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023330 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073331 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063332 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023333 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163335
[email protected]49639fa2011-12-20 23:22:413336 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163337
[email protected]49639fa2011-12-20 23:22:413338 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163339 EXPECT_EQ(ERR_IO_PENDING, rv);
3340
3341 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173342 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163343
[email protected]4eddbc732012-08-09 05:40:173344 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163345}
3346
[email protected]f6c63db52013-02-02 00:35:223347// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3348// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023349TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223350 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3351 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073352 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223353 "https://proxy:70"));
3354 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073355 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223356 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073357 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223358
3359 HttpRequestInfo request1;
3360 request1.method = "GET";
3361 request1.url = GURL("https://www.google.com/");
3362 request1.load_flags = 0;
3363
3364 HttpRequestInfo request2;
3365 request2.method = "GET";
3366 request2.url = GURL("https://news.google.com/");
3367 request2.load_flags = 0;
3368
3369 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543370 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3371 LOWEST));
[email protected]23e482282013-06-14 16:08:023372 scoped_ptr<SpdyFrame> conn_resp1(
3373 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223374
3375 // Fetch https://www.google.com/ via HTTP.
3376 const char get1[] = "GET / HTTP/1.1\r\n"
3377 "Host: www.google.com\r\n"
3378 "Connection: keep-alive\r\n\r\n";
3379 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023380 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223381 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3382 "Content-Length: 1\r\n\r\n";
3383 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023384 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3385 scoped_ptr<SpdyFrame> wrapped_body1(
3386 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223387 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203388 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223389
3390 // CONNECT to news.google.com:443 via SPDY.
3391 const char* const kConnectHeaders2[] = {
[email protected]23e482282013-06-14 16:08:023392 spdy_util_.GetMethodKey(), "CONNECT",
3393 spdy_util_.GetPathKey(), "news.google.com:443",
3394 spdy_util_.GetHostKey(), "news.google.com",
3395 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]f6c63db52013-02-02 00:35:223396 };
3397 scoped_ptr<SpdyFrame> connect2(
[email protected]4bd46222013-05-14 19:32:233398 spdy_util_.ConstructSpdyControlFrame(NULL,
3399 0,
3400 /*compressed*/ false,
3401 3,
3402 LOWEST,
3403 SYN_STREAM,
3404 CONTROL_FLAG_NONE,
3405 kConnectHeaders2,
3406 arraysize(kConnectHeaders2),
3407 0));
[email protected]23e482282013-06-14 16:08:023408 scoped_ptr<SpdyFrame> conn_resp2(
3409 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223410
3411 // Fetch https://news.google.com/ via HTTP.
3412 const char get2[] = "GET / HTTP/1.1\r\n"
3413 "Host: news.google.com\r\n"
3414 "Connection: keep-alive\r\n\r\n";
3415 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023416 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223417 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3418 "Content-Length: 2\r\n\r\n";
3419 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023420 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223421 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023422 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223423
3424 MockWrite spdy_writes[] = {
3425 CreateMockWrite(*connect1, 0),
3426 CreateMockWrite(*wrapped_get1, 2),
3427 CreateMockWrite(*connect2, 5),
3428 CreateMockWrite(*wrapped_get2, 7),
3429 };
3430
3431 MockRead spdy_reads[] = {
3432 CreateMockRead(*conn_resp1, 1, ASYNC),
3433 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3434 CreateMockRead(*wrapped_body1, 4, ASYNC),
3435 CreateMockRead(*conn_resp2, 6, ASYNC),
3436 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3437 CreateMockRead(*wrapped_body2, 9, ASYNC),
3438 MockRead(ASYNC, 0, 10),
3439 };
3440
3441 DeterministicSocketData spdy_data(
3442 spdy_reads, arraysize(spdy_reads),
3443 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073444 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223445
3446 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023447 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073448 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223449 SSLSocketDataProvider ssl2(ASYNC, OK);
3450 ssl2.was_npn_negotiated = false;
3451 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073452 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223453 SSLSocketDataProvider ssl3(ASYNC, OK);
3454 ssl3.was_npn_negotiated = false;
3455 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073456 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223457
3458 TestCompletionCallback callback;
3459
[email protected]262eec82013-03-19 21:01:363460 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503461 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223462 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3463 EXPECT_EQ(ERR_IO_PENDING, rv);
3464 // The first connect and request, each of their responses, and the body.
3465 spdy_data.RunFor(5);
3466
3467 rv = callback.WaitForResult();
3468 EXPECT_EQ(OK, rv);
3469
3470 LoadTimingInfo load_timing_info;
3471 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3472 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3473
3474 const HttpResponseInfo* response = trans->GetResponseInfo();
3475 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503476 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223477 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3478
3479 std::string response_data;
3480 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503481 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223482
[email protected]262eec82013-03-19 21:01:363483 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503484 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223485 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3486 EXPECT_EQ(ERR_IO_PENDING, rv);
3487
3488 // The second connect and request, each of their responses, and the body.
3489 spdy_data.RunFor(5);
3490 rv = callback.WaitForResult();
3491 EXPECT_EQ(OK, rv);
3492
3493 LoadTimingInfo load_timing_info2;
3494 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3495 // Even though the SPDY connection is reused, a new tunnelled connection has
3496 // to be created, so the socket's load timing looks like a fresh connection.
3497 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3498
3499 // The requests should have different IDs, since they each are using their own
3500 // separate stream.
3501 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3502
[email protected]90499482013-06-01 00:39:503503 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223504}
3505
3506// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3507// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023508TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223509 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3510 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073511 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223512 "https://proxy:70"));
3513 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073514 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223515 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073516 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223517
3518 HttpRequestInfo request1;
3519 request1.method = "GET";
3520 request1.url = GURL("https://www.google.com/");
3521 request1.load_flags = 0;
3522
3523 HttpRequestInfo request2;
3524 request2.method = "GET";
3525 request2.url = GURL("https://www.google.com/2");
3526 request2.load_flags = 0;
3527
3528 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543529 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3530 LOWEST));
[email protected]23e482282013-06-14 16:08:023531 scoped_ptr<SpdyFrame> conn_resp1(
3532 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223533
3534 // Fetch https://www.google.com/ via HTTP.
3535 const char get1[] = "GET / HTTP/1.1\r\n"
3536 "Host: www.google.com\r\n"
3537 "Connection: keep-alive\r\n\r\n";
3538 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023539 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223540 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3541 "Content-Length: 1\r\n\r\n";
3542 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023543 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3544 scoped_ptr<SpdyFrame> wrapped_body1(
3545 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223546 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203547 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223548
3549 // Fetch https://www.google.com/2 via HTTP.
3550 const char get2[] = "GET /2 HTTP/1.1\r\n"
3551 "Host: www.google.com\r\n"
3552 "Connection: keep-alive\r\n\r\n";
3553 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023554 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223555 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3556 "Content-Length: 2\r\n\r\n";
3557 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023558 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223559 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023560 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223561
3562 MockWrite spdy_writes[] = {
3563 CreateMockWrite(*connect1, 0),
3564 CreateMockWrite(*wrapped_get1, 2),
3565 CreateMockWrite(*wrapped_get2, 5),
3566 };
3567
3568 MockRead spdy_reads[] = {
3569 CreateMockRead(*conn_resp1, 1, ASYNC),
3570 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3571 CreateMockRead(*wrapped_body1, 4, ASYNC),
3572 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3573 CreateMockRead(*wrapped_body2, 7, ASYNC),
3574 MockRead(ASYNC, 0, 8),
3575 };
3576
3577 DeterministicSocketData spdy_data(
3578 spdy_reads, arraysize(spdy_reads),
3579 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073580 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223581
3582 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023583 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073584 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223585 SSLSocketDataProvider ssl2(ASYNC, OK);
3586 ssl2.was_npn_negotiated = false;
3587 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073588 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223589
3590 TestCompletionCallback callback;
3591
[email protected]262eec82013-03-19 21:01:363592 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223594 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3595 EXPECT_EQ(ERR_IO_PENDING, rv);
3596 // The first connect and request, each of their responses, and the body.
3597 spdy_data.RunFor(5);
3598
3599 rv = callback.WaitForResult();
3600 EXPECT_EQ(OK, rv);
3601
3602 LoadTimingInfo load_timing_info;
3603 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3604 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3605
3606 const HttpResponseInfo* response = trans->GetResponseInfo();
3607 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503608 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223609 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3610
3611 std::string response_data;
3612 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503613 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223614 trans.reset();
3615
[email protected]262eec82013-03-19 21:01:363616 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503617 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223618 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3619 EXPECT_EQ(ERR_IO_PENDING, rv);
3620
3621 // The second request, response, and body. There should not be a second
3622 // connect.
3623 spdy_data.RunFor(3);
3624 rv = callback.WaitForResult();
3625 EXPECT_EQ(OK, rv);
3626
3627 LoadTimingInfo load_timing_info2;
3628 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3629 TestLoadTimingReused(load_timing_info2);
3630
3631 // The requests should have the same ID.
3632 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3633
[email protected]90499482013-06-01 00:39:503634 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223635}
3636
3637// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3638// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023639TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223640 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3641 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073642 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223643 "https://proxy:70"));
3644 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073645 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223646 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073647 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223648
3649 HttpRequestInfo request1;
3650 request1.method = "GET";
3651 request1.url = GURL("http://www.google.com/");
3652 request1.load_flags = 0;
3653
3654 HttpRequestInfo request2;
3655 request2.method = "GET";
3656 request2.url = GURL("http://news.google.com/");
3657 request2.load_flags = 0;
3658
3659 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023660 scoped_ptr<SpdyHeaderBlock> headers(
3661 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233662 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023663 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3664 scoped_ptr<SpdyFrame> get_resp1(
3665 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3666 scoped_ptr<SpdyFrame> body1(
3667 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223668
3669 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023670 scoped_ptr<SpdyHeaderBlock> headers2(
3671 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233672 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023673 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3674 scoped_ptr<SpdyFrame> get_resp2(
3675 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3676 scoped_ptr<SpdyFrame> body2(
3677 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223678
3679 MockWrite spdy_writes[] = {
3680 CreateMockWrite(*get1, 0),
3681 CreateMockWrite(*get2, 3),
3682 };
3683
3684 MockRead spdy_reads[] = {
3685 CreateMockRead(*get_resp1, 1, ASYNC),
3686 CreateMockRead(*body1, 2, ASYNC),
3687 CreateMockRead(*get_resp2, 4, ASYNC),
3688 CreateMockRead(*body2, 5, ASYNC),
3689 MockRead(ASYNC, 0, 6),
3690 };
3691
3692 DeterministicSocketData spdy_data(
3693 spdy_reads, arraysize(spdy_reads),
3694 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073695 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223696
3697 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023698 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073699 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223700
3701 TestCompletionCallback callback;
3702
[email protected]262eec82013-03-19 21:01:363703 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503704 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223705 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3706 EXPECT_EQ(ERR_IO_PENDING, rv);
3707 spdy_data.RunFor(2);
3708
3709 rv = callback.WaitForResult();
3710 EXPECT_EQ(OK, rv);
3711
3712 LoadTimingInfo load_timing_info;
3713 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3714 TestLoadTimingNotReused(load_timing_info,
3715 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3716
3717 const HttpResponseInfo* response = trans->GetResponseInfo();
3718 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503719 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223720 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3721
3722 std::string response_data;
3723 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503724 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223725 spdy_data.RunFor(1);
3726 EXPECT_EQ(1, callback.WaitForResult());
3727 // Delete the first request, so the second one can reuse the socket.
3728 trans.reset();
3729
[email protected]262eec82013-03-19 21:01:363730 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503731 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223732 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3733 EXPECT_EQ(ERR_IO_PENDING, rv);
3734
3735 spdy_data.RunFor(2);
3736 rv = callback.WaitForResult();
3737 EXPECT_EQ(OK, rv);
3738
3739 LoadTimingInfo load_timing_info2;
3740 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3741 TestLoadTimingReused(load_timing_info2);
3742
3743 // The requests should have the same ID.
3744 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3745
[email protected]90499482013-06-01 00:39:503746 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223747 spdy_data.RunFor(1);
3748 EXPECT_EQ(2, callback.WaitForResult());
3749}
3750
[email protected]2df19bb2010-08-25 20:13:463751// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023752TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463753 HttpRequestInfo request;
3754 request.method = "GET";
3755 request.url = GURL("http://www.google.com/");
3756 // when the no authentication data flag is set.
3757 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3758
[email protected]79cb5c12011-09-12 13:12:043759 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073760 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043761 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293762 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073763 session_deps_.net_log = log.bound().net_log();
3764 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273765
[email protected]2df19bb2010-08-25 20:13:463766 // Since we have proxy, should use full url
3767 MockWrite data_writes1[] = {
3768 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3769 "Host: www.google.com\r\n"
3770 "Proxy-Connection: keep-alive\r\n\r\n"),
3771
3772 // After calling trans->RestartWithAuth(), this is the request we should
3773 // be issuing -- the final header line contains the credentials.
3774 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3775 "Host: www.google.com\r\n"
3776 "Proxy-Connection: keep-alive\r\n"
3777 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3778 };
3779
3780 // The proxy responds to the GET with a 407, using a persistent
3781 // connection.
3782 MockRead data_reads1[] = {
3783 // No credentials.
3784 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3785 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3786 MockRead("Proxy-Connection: keep-alive\r\n"),
3787 MockRead("Content-Length: 0\r\n\r\n"),
3788
3789 MockRead("HTTP/1.1 200 OK\r\n"),
3790 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3791 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063792 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463793 };
3794
3795 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3796 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073797 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063798 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073799 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463800
[email protected]49639fa2011-12-20 23:22:413801 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463802
[email protected]262eec82013-03-19 21:01:363803 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503805
[email protected]49639fa2011-12-20 23:22:413806 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463807 EXPECT_EQ(ERR_IO_PENDING, rv);
3808
3809 rv = callback1.WaitForResult();
3810 EXPECT_EQ(OK, rv);
3811
[email protected]58e32bb2013-01-21 18:23:253812 LoadTimingInfo load_timing_info;
3813 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3814 TestLoadTimingNotReused(load_timing_info,
3815 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3816
[email protected]2df19bb2010-08-25 20:13:463817 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503818 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503819 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463820 EXPECT_EQ(407, response->headers->response_code());
3821 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043822 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463823
[email protected]49639fa2011-12-20 23:22:413824 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463825
[email protected]49639fa2011-12-20 23:22:413826 rv = trans->RestartWithAuth(
3827 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463828 EXPECT_EQ(ERR_IO_PENDING, rv);
3829
3830 rv = callback2.WaitForResult();
3831 EXPECT_EQ(OK, rv);
3832
[email protected]58e32bb2013-01-21 18:23:253833 load_timing_info = LoadTimingInfo();
3834 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3835 // Retrying with HTTP AUTH is considered to be reusing a socket.
3836 TestLoadTimingReused(load_timing_info);
3837
[email protected]2df19bb2010-08-25 20:13:463838 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503839 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463840
3841 EXPECT_TRUE(response->headers->IsKeepAlive());
3842 EXPECT_EQ(200, response->headers->response_code());
3843 EXPECT_EQ(100, response->headers->GetContentLength());
3844 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3845
3846 // The password prompt info should not be set.
3847 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3848}
3849
[email protected]23e482282013-06-14 16:08:023850void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083851 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423852 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083853 request.method = "GET";
3854 request.url = GURL("https://www.google.com/");
3855 request.load_flags = 0;
3856
[email protected]cb9bf6ca2011-01-28 13:15:273857 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073858 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073859 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273860
[email protected]c744cf22009-02-27 07:28:083861 // Since we have proxy, should try to establish tunnel.
3862 MockWrite data_writes[] = {
3863 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453864 "Host: www.google.com\r\n"
3865 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083866 };
3867
3868 MockRead data_reads[] = {
3869 status,
3870 MockRead("Content-Length: 10\r\n\r\n"),
3871 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063872 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083873 };
3874
[email protected]31a2bfe2010-02-09 08:03:393875 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3876 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073877 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083878
[email protected]49639fa2011-12-20 23:22:413879 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083880
[email protected]262eec82013-03-19 21:01:363881 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503882 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503883
[email protected]49639fa2011-12-20 23:22:413884 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423885 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083886
3887 rv = callback.WaitForResult();
3888 EXPECT_EQ(expected_status, rv);
3889}
3890
[email protected]23e482282013-06-14 16:08:023891void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233892 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083893 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423894 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083895}
3896
[email protected]23e482282013-06-14 16:08:023897TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083898 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3899}
3900
[email protected]23e482282013-06-14 16:08:023901TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083902 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3903}
3904
[email protected]23e482282013-06-14 16:08:023905TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083906 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3907}
3908
[email protected]23e482282013-06-14 16:08:023909TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083910 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3911}
3912
[email protected]23e482282013-06-14 16:08:023913TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083914 ConnectStatusHelper(
3915 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3916}
3917
[email protected]23e482282013-06-14 16:08:023918TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083919 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3920}
3921
[email protected]23e482282013-06-14 16:08:023922TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083923 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3924}
3925
[email protected]23e482282013-06-14 16:08:023926TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083927 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3928}
3929
[email protected]23e482282013-06-14 16:08:023930TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083931 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3932}
3933
[email protected]23e482282013-06-14 16:08:023934TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083935 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3936}
3937
[email protected]23e482282013-06-14 16:08:023938TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083939 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3940}
3941
[email protected]23e482282013-06-14 16:08:023942TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083943 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3944}
3945
[email protected]23e482282013-06-14 16:08:023946TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083947 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3948}
3949
[email protected]23e482282013-06-14 16:08:023950TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083951 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3952}
3953
[email protected]23e482282013-06-14 16:08:023954TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083955 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3956}
3957
[email protected]23e482282013-06-14 16:08:023958TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083959 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3960}
3961
[email protected]23e482282013-06-14 16:08:023962TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083963 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3964}
3965
[email protected]23e482282013-06-14 16:08:023966TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083967 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3968}
3969
[email protected]23e482282013-06-14 16:08:023970TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083971 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3972}
3973
[email protected]23e482282013-06-14 16:08:023974TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083975 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3976}
3977
[email protected]23e482282013-06-14 16:08:023978TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083979 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3980}
3981
[email protected]23e482282013-06-14 16:08:023982TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083983 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3984}
3985
[email protected]23e482282013-06-14 16:08:023986TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083987 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3988}
3989
[email protected]23e482282013-06-14 16:08:023990TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083991 ConnectStatusHelperWithExpectedStatus(
3992 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543993 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083994}
3995
[email protected]23e482282013-06-14 16:08:023996TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083997 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3998}
3999
[email protected]23e482282013-06-14 16:08:024000TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084001 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4002}
4003
[email protected]23e482282013-06-14 16:08:024004TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084005 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4006}
4007
[email protected]23e482282013-06-14 16:08:024008TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084009 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4010}
4011
[email protected]23e482282013-06-14 16:08:024012TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084013 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4014}
4015
[email protected]23e482282013-06-14 16:08:024016TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084017 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4018}
4019
[email protected]23e482282013-06-14 16:08:024020TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084021 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4022}
4023
[email protected]23e482282013-06-14 16:08:024024TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084025 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4026}
4027
[email protected]23e482282013-06-14 16:08:024028TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084029 ConnectStatusHelper(
4030 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4031}
4032
[email protected]23e482282013-06-14 16:08:024033TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084034 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4035}
4036
[email protected]23e482282013-06-14 16:08:024037TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084038 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4039}
4040
[email protected]23e482282013-06-14 16:08:024041TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084042 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4043}
4044
[email protected]23e482282013-06-14 16:08:024045TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084046 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4047}
4048
[email protected]23e482282013-06-14 16:08:024049TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084050 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4051}
4052
[email protected]23e482282013-06-14 16:08:024053TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084054 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4055}
4056
[email protected]23e482282013-06-14 16:08:024057TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084058 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4059}
4060
[email protected]038e9a32008-10-08 22:40:164061// Test the flow when both the proxy server AND origin server require
4062// authentication. Again, this uses basic auth for both since that is
4063// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024064TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274065 HttpRequestInfo request;
4066 request.method = "GET";
4067 request.url = GURL("http://www.google.com/");
4068 request.load_flags = 0;
4069
[email protected]038e9a32008-10-08 22:40:164070 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074071 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4072 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4073
4074 scoped_ptr<HttpTransaction> trans(
4075 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]038e9a32008-10-08 22:40:164076
[email protected]f9ee6b52008-11-08 06:46:234077 MockWrite data_writes1[] = {
4078 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4079 "Host: www.google.com\r\n"
4080 "Proxy-Connection: keep-alive\r\n\r\n"),
4081 };
4082
[email protected]038e9a32008-10-08 22:40:164083 MockRead data_reads1[] = {
4084 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4085 // Give a couple authenticate options (only the middle one is actually
4086 // supported).
[email protected]22927ad2009-09-21 19:56:194087 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164088 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4089 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4090 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4091 // Large content-length -- won't matter, as connection will be reset.
4092 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064093 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164094 };
4095
4096 // After calling trans->RestartWithAuth() the first time, this is the
4097 // request we should be issuing -- the final header line contains the
4098 // proxy's credentials.
4099 MockWrite data_writes2[] = {
4100 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4101 "Host: www.google.com\r\n"
4102 "Proxy-Connection: keep-alive\r\n"
4103 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4104 };
4105
4106 // Now the proxy server lets the request pass through to origin server.
4107 // The origin server responds with a 401.
4108 MockRead data_reads2[] = {
4109 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4110 // Note: We are using the same realm-name as the proxy server. This is
4111 // completely valid, as realms are unique across hosts.
4112 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4113 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4114 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064115 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164116 };
4117
4118 // After calling trans->RestartWithAuth() the second time, we should send
4119 // the credentials for both the proxy and origin server.
4120 MockWrite data_writes3[] = {
4121 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4122 "Host: www.google.com\r\n"
4123 "Proxy-Connection: keep-alive\r\n"
4124 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4125 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4126 };
4127
4128 // Lastly we get the desired content.
4129 MockRead data_reads3[] = {
4130 MockRead("HTTP/1.0 200 OK\r\n"),
4131 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4132 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064133 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164134 };
4135
[email protected]31a2bfe2010-02-09 08:03:394136 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4137 data_writes1, arraysize(data_writes1));
4138 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4139 data_writes2, arraysize(data_writes2));
4140 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4141 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074142 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4143 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4144 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164145
[email protected]49639fa2011-12-20 23:22:414146 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164147
[email protected]49639fa2011-12-20 23:22:414148 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424149 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164150
4151 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424152 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164153
[email protected]1c773ea12009-04-28 19:58:424154 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504155 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044156 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164157
[email protected]49639fa2011-12-20 23:22:414158 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164159
[email protected]49639fa2011-12-20 23:22:414160 rv = trans->RestartWithAuth(
4161 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424162 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164163
4164 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424165 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164166
4167 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504168 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044169 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164170
[email protected]49639fa2011-12-20 23:22:414171 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164172
[email protected]49639fa2011-12-20 23:22:414173 rv = trans->RestartWithAuth(
4174 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424175 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164176
4177 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424178 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164179
4180 response = trans->GetResponseInfo();
4181 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4182 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164183}
[email protected]4ddaf2502008-10-23 18:26:194184
[email protected]ea9dc9a2009-09-05 00:43:324185// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4186// can't hook into its internals to cause it to generate predictable NTLM
4187// authorization headers.
4188#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294189// The NTLM authentication unit tests were generated by capturing the HTTP
4190// requests and responses using Fiddler 2 and inspecting the generated random
4191// bytes in the debugger.
4192
4193// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024194TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424195 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244196 request.method = "GET";
4197 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544198
4199 // Ensure load is not disrupted by flags which suppress behaviour specific
4200 // to other auth schemes.
4201 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244202
[email protected]cb9bf6ca2011-01-28 13:15:274203 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4204 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074205 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274206
[email protected]3f918782009-02-28 01:29:244207 MockWrite data_writes1[] = {
4208 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4209 "Host: 172.22.68.17\r\n"
4210 "Connection: keep-alive\r\n\r\n"),
4211 };
4212
4213 MockRead data_reads1[] = {
4214 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044215 // Negotiate and NTLM are often requested together. However, we only want
4216 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4217 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244218 MockRead("WWW-Authenticate: NTLM\r\n"),
4219 MockRead("Connection: close\r\n"),
4220 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364221 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244222 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064223 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244224 };
4225
4226 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224227 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244228 // request we should be issuing -- the final header line contains a Type
4229 // 1 message.
4230 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4231 "Host: 172.22.68.17\r\n"
4232 "Connection: keep-alive\r\n"
4233 "Authorization: NTLM "
4234 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4235
4236 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4237 // (the credentials for the origin server). The second request continues
4238 // on the same connection.
4239 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4240 "Host: 172.22.68.17\r\n"
4241 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294242 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4243 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4244 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4245 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4246 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244247 };
4248
4249 MockRead data_reads2[] = {
4250 // The origin server responds with a Type 2 message.
4251 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4252 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294253 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244254 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4255 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4256 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4257 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4258 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4259 "BtAAAAAAA=\r\n"),
4260 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364261 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244262 MockRead("You are not authorized to view this page\r\n"),
4263
4264 // Lastly we get the desired content.
4265 MockRead("HTTP/1.1 200 OK\r\n"),
4266 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4267 MockRead("Content-Length: 13\r\n\r\n"),
4268 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064269 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244270 };
4271
[email protected]31a2bfe2010-02-09 08:03:394272 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4273 data_writes1, arraysize(data_writes1));
4274 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4275 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074276 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4277 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244278
[email protected]49639fa2011-12-20 23:22:414279 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244280
[email protected]262eec82013-03-19 21:01:364281 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504282 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504283
[email protected]49639fa2011-12-20 23:22:414284 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424285 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244286
4287 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424288 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244289
[email protected]0757e7702009-03-27 04:00:224290 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4291
[email protected]1c773ea12009-04-28 19:58:424292 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044293 ASSERT_FALSE(response == NULL);
4294 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244295
[email protected]49639fa2011-12-20 23:22:414296 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254297
[email protected]f3cf9802011-10-28 18:44:584298 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414299 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254300 EXPECT_EQ(ERR_IO_PENDING, rv);
4301
4302 rv = callback2.WaitForResult();
4303 EXPECT_EQ(OK, rv);
4304
4305 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4306
4307 response = trans->GetResponseInfo();
4308 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254309 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4310
[email protected]49639fa2011-12-20 23:22:414311 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244312
[email protected]49639fa2011-12-20 23:22:414313 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424314 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244315
[email protected]0757e7702009-03-27 04:00:224316 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424317 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244318
4319 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504320 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244321 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4322 EXPECT_EQ(13, response->headers->GetContentLength());
4323}
4324
[email protected]385a4672009-03-11 22:21:294325// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024326TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424327 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294328 request.method = "GET";
4329 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4330 request.load_flags = 0;
4331
[email protected]cb9bf6ca2011-01-28 13:15:274332 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4333 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074334 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274335
[email protected]385a4672009-03-11 22:21:294336 MockWrite data_writes1[] = {
4337 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4338 "Host: 172.22.68.17\r\n"
4339 "Connection: keep-alive\r\n\r\n"),
4340 };
4341
4342 MockRead data_reads1[] = {
4343 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044344 // Negotiate and NTLM are often requested together. However, we only want
4345 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4346 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294347 MockRead("WWW-Authenticate: NTLM\r\n"),
4348 MockRead("Connection: close\r\n"),
4349 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364350 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294351 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064352 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294353 };
4354
4355 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224356 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294357 // request we should be issuing -- the final header line contains a Type
4358 // 1 message.
4359 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4360 "Host: 172.22.68.17\r\n"
4361 "Connection: keep-alive\r\n"
4362 "Authorization: NTLM "
4363 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4364
4365 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4366 // (the credentials for the origin server). The second request continues
4367 // on the same connection.
4368 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4369 "Host: 172.22.68.17\r\n"
4370 "Connection: keep-alive\r\n"
4371 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4372 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4373 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4374 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4375 "4Ww7b7E=\r\n\r\n"),
4376 };
4377
4378 MockRead data_reads2[] = {
4379 // The origin server responds with a Type 2 message.
4380 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4381 MockRead("WWW-Authenticate: NTLM "
4382 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4383 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4384 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4385 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4386 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4387 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4388 "BtAAAAAAA=\r\n"),
4389 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364390 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294391 MockRead("You are not authorized to view this page\r\n"),
4392
4393 // Wrong password.
4394 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294395 MockRead("WWW-Authenticate: NTLM\r\n"),
4396 MockRead("Connection: close\r\n"),
4397 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364398 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294399 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064400 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294401 };
4402
4403 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224404 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294405 // request we should be issuing -- the final header line contains a Type
4406 // 1 message.
4407 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4408 "Host: 172.22.68.17\r\n"
4409 "Connection: keep-alive\r\n"
4410 "Authorization: NTLM "
4411 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4412
4413 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4414 // (the credentials for the origin server). The second request continues
4415 // on the same connection.
4416 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4417 "Host: 172.22.68.17\r\n"
4418 "Connection: keep-alive\r\n"
4419 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4420 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4421 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4422 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4423 "+4MUm7c=\r\n\r\n"),
4424 };
4425
4426 MockRead data_reads3[] = {
4427 // The origin server responds with a Type 2 message.
4428 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4429 MockRead("WWW-Authenticate: NTLM "
4430 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4431 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4432 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4433 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4434 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4435 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4436 "BtAAAAAAA=\r\n"),
4437 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364438 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294439 MockRead("You are not authorized to view this page\r\n"),
4440
4441 // Lastly we get the desired content.
4442 MockRead("HTTP/1.1 200 OK\r\n"),
4443 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4444 MockRead("Content-Length: 13\r\n\r\n"),
4445 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064446 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294447 };
4448
[email protected]31a2bfe2010-02-09 08:03:394449 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4450 data_writes1, arraysize(data_writes1));
4451 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4452 data_writes2, arraysize(data_writes2));
4453 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4454 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074455 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4456 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4457 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294458
[email protected]49639fa2011-12-20 23:22:414459 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294460
[email protected]262eec82013-03-19 21:01:364461 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504462 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504463
[email protected]49639fa2011-12-20 23:22:414464 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424465 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294466
4467 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424468 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294469
[email protected]0757e7702009-03-27 04:00:224470 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294471
[email protected]1c773ea12009-04-28 19:58:424472 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504473 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044474 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294475
[email protected]49639fa2011-12-20 23:22:414476 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294477
[email protected]0757e7702009-03-27 04:00:224478 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584479 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414480 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424481 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294482
[email protected]10af5fe72011-01-31 16:17:254483 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424484 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294485
[email protected]0757e7702009-03-27 04:00:224486 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414487 TestCompletionCallback callback3;
4488 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424489 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254490 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424491 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224492 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4493
4494 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044495 ASSERT_FALSE(response == NULL);
4496 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224497
[email protected]49639fa2011-12-20 23:22:414498 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224499
4500 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584501 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414502 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254503 EXPECT_EQ(ERR_IO_PENDING, rv);
4504
4505 rv = callback4.WaitForResult();
4506 EXPECT_EQ(OK, rv);
4507
4508 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4509
[email protected]49639fa2011-12-20 23:22:414510 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254511
4512 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414513 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424514 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224515
4516 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424517 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224518
[email protected]385a4672009-03-11 22:21:294519 response = trans->GetResponseInfo();
4520 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4521 EXPECT_EQ(13, response->headers->GetContentLength());
4522}
[email protected]ea9dc9a2009-09-05 00:43:324523#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294524
[email protected]4ddaf2502008-10-23 18:26:194525// Test reading a server response which has only headers, and no body.
4526// After some maximum number of bytes is consumed, the transaction should
4527// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024528TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424529 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194530 request.method = "GET";
4531 request.url = GURL("http://www.google.com/");
4532 request.load_flags = 0;
4533
[email protected]3fe8d2f82013-10-17 08:56:074534 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274535 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074536 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274537
[email protected]b75b7b2f2009-10-06 00:54:534538 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434539 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534540 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194541
4542 MockRead data_reads[] = {
4543 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064544 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194545 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064546 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194547 };
[email protected]31a2bfe2010-02-09 08:03:394548 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074549 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194550
[email protected]49639fa2011-12-20 23:22:414551 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194552
[email protected]49639fa2011-12-20 23:22:414553 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424554 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194555
4556 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424557 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194558
[email protected]1c773ea12009-04-28 19:58:424559 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194560 EXPECT_TRUE(response == NULL);
4561}
[email protected]f4e426b2008-11-05 00:24:494562
4563// Make sure that we don't try to reuse a TCPClientSocket when failing to
4564// establish tunnel.
4565// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024566TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234567 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274568 HttpRequestInfo request;
4569 request.method = "GET";
4570 request.url = GURL("https://www.google.com/");
4571 request.load_flags = 0;
4572
[email protected]f4e426b2008-11-05 00:24:494573 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074574 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014575
[email protected]bb88e1d32013-05-03 23:11:074576 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494577
[email protected]262eec82013-03-19 21:01:364578 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504579 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494580
[email protected]f4e426b2008-11-05 00:24:494581 // Since we have proxy, should try to establish tunnel.
4582 MockWrite data_writes1[] = {
4583 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454584 "Host: www.google.com\r\n"
4585 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494586 };
4587
[email protected]77848d12008-11-14 00:00:224588 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494589 // connection. Usually a proxy would return 501 (not implemented),
4590 // or 200 (tunnel established).
4591 MockRead data_reads1[] = {
4592 MockRead("HTTP/1.1 404 Not Found\r\n"),
4593 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064594 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494595 };
4596
[email protected]31a2bfe2010-02-09 08:03:394597 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4598 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074599 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494600
[email protected]49639fa2011-12-20 23:22:414601 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494602
[email protected]49639fa2011-12-20 23:22:414603 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424604 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494605
4606 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424607 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494608
[email protected]1c773ea12009-04-28 19:58:424609 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084610 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494611
[email protected]b4404c02009-04-10 16:38:524612 // Empty the current queue. This is necessary because idle sockets are
4613 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344614 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524615
[email protected]f4e426b2008-11-05 00:24:494616 // We now check to make sure the TCPClientSocket was not added back to
4617 // the pool.
[email protected]90499482013-06-01 00:39:504618 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494619 trans.reset();
[email protected]2da659e2013-05-23 20:51:344620 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494621 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504622 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494623}
[email protected]372d34a2008-11-05 21:30:514624
[email protected]1b157c02009-04-21 01:55:404625// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024626TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424627 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404628 request.method = "GET";
4629 request.url = GURL("http://www.google.com/");
4630 request.load_flags = 0;
4631
[email protected]bb88e1d32013-05-03 23:11:074632 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274633
[email protected]262eec82013-03-19 21:01:364634 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504635 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274636
[email protected]1b157c02009-04-21 01:55:404637 MockRead data_reads[] = {
4638 // A part of the response body is received with the response headers.
4639 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4640 // The rest of the response body is received in two parts.
4641 MockRead("lo"),
4642 MockRead(" world"),
4643 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064644 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404645 };
4646
[email protected]31a2bfe2010-02-09 08:03:394647 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074648 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404649
[email protected]49639fa2011-12-20 23:22:414650 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404651
[email protected]49639fa2011-12-20 23:22:414652 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424653 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404654
4655 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424656 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404657
[email protected]1c773ea12009-04-28 19:58:424658 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504659 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404660
[email protected]90499482013-06-01 00:39:504661 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404662 std::string status_line = response->headers->GetStatusLine();
4663 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4664
[email protected]90499482013-06-01 00:39:504665 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404666
4667 std::string response_data;
4668 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424669 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404670 EXPECT_EQ("hello world", response_data);
4671
4672 // Empty the current queue. This is necessary because idle sockets are
4673 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344674 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404675
4676 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504677 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404678}
4679
[email protected]76a505b2010-08-25 06:23:004680// Make sure that we recycle a SSL socket after reading all of the response
4681// body.
[email protected]23e482282013-06-14 16:08:024682TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004683 HttpRequestInfo request;
4684 request.method = "GET";
4685 request.url = GURL("https://www.google.com/");
4686 request.load_flags = 0;
4687
4688 MockWrite data_writes[] = {
4689 MockWrite("GET / HTTP/1.1\r\n"
4690 "Host: www.google.com\r\n"
4691 "Connection: keep-alive\r\n\r\n"),
4692 };
4693
4694 MockRead data_reads[] = {
4695 MockRead("HTTP/1.1 200 OK\r\n"),
4696 MockRead("Content-Length: 11\r\n\r\n"),
4697 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064698 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004699 };
4700
[email protected]8ddf8322012-02-23 18:08:064701 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074702 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004703
4704 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4705 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074706 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004707
[email protected]49639fa2011-12-20 23:22:414708 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004709
[email protected]bb88e1d32013-05-03 23:11:074710 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364711 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504712 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004713
[email protected]49639fa2011-12-20 23:22:414714 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004715
4716 EXPECT_EQ(ERR_IO_PENDING, rv);
4717 EXPECT_EQ(OK, callback.WaitForResult());
4718
4719 const HttpResponseInfo* response = trans->GetResponseInfo();
4720 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504721 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004722 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4723
[email protected]90499482013-06-01 00:39:504724 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004725
4726 std::string response_data;
4727 rv = ReadTransaction(trans.get(), &response_data);
4728 EXPECT_EQ(OK, rv);
4729 EXPECT_EQ("hello world", response_data);
4730
4731 // Empty the current queue. This is necessary because idle sockets are
4732 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344733 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004734
4735 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504736 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004737}
4738
4739// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4740// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024741TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004742 HttpRequestInfo request;
4743 request.method = "GET";
4744 request.url = GURL("https://www.google.com/");
4745 request.load_flags = 0;
4746
4747 MockWrite data_writes[] = {
4748 MockWrite("GET / HTTP/1.1\r\n"
4749 "Host: www.google.com\r\n"
4750 "Connection: keep-alive\r\n\r\n"),
4751 MockWrite("GET / HTTP/1.1\r\n"
4752 "Host: www.google.com\r\n"
4753 "Connection: keep-alive\r\n\r\n"),
4754 };
4755
4756 MockRead data_reads[] = {
4757 MockRead("HTTP/1.1 200 OK\r\n"),
4758 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064759 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004760 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064761 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004762 };
4763
[email protected]8ddf8322012-02-23 18:08:064764 SSLSocketDataProvider ssl(ASYNC, OK);
4765 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074766 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4767 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004768
4769 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4770 data_writes, arraysize(data_writes));
4771 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4772 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074773 session_deps_.socket_factory->AddSocketDataProvider(&data);
4774 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004775
[email protected]49639fa2011-12-20 23:22:414776 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004777
[email protected]bb88e1d32013-05-03 23:11:074778 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364779 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504780 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004781
[email protected]49639fa2011-12-20 23:22:414782 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004783
4784 EXPECT_EQ(ERR_IO_PENDING, rv);
4785 EXPECT_EQ(OK, callback.WaitForResult());
4786
4787 const HttpResponseInfo* response = trans->GetResponseInfo();
4788 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504789 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004790 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4791
[email protected]90499482013-06-01 00:39:504792 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004793
4794 std::string response_data;
4795 rv = ReadTransaction(trans.get(), &response_data);
4796 EXPECT_EQ(OK, rv);
4797 EXPECT_EQ("hello world", response_data);
4798
4799 // Empty the current queue. This is necessary because idle sockets are
4800 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344801 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004802
4803 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504804 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004805
4806 // Now start the second transaction, which should reuse the previous socket.
4807
[email protected]90499482013-06-01 00:39:504808 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004809
[email protected]49639fa2011-12-20 23:22:414810 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004811
4812 EXPECT_EQ(ERR_IO_PENDING, rv);
4813 EXPECT_EQ(OK, callback.WaitForResult());
4814
4815 response = trans->GetResponseInfo();
4816 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504817 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004818 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4819
[email protected]90499482013-06-01 00:39:504820 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004821
4822 rv = ReadTransaction(trans.get(), &response_data);
4823 EXPECT_EQ(OK, rv);
4824 EXPECT_EQ("hello world", response_data);
4825
4826 // Empty the current queue. This is necessary because idle sockets are
4827 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344828 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004829
4830 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504831 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004832}
4833
[email protected]b4404c02009-04-10 16:38:524834// Make sure that we recycle a socket after a zero-length response.
4835// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024836TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424837 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524838 request.method = "GET";
4839 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4840 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4841 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4842 "rt=prt.2642,ol.2649,xjs.2951");
4843 request.load_flags = 0;
4844
[email protected]bb88e1d32013-05-03 23:11:074845 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274846
[email protected]262eec82013-03-19 21:01:364847 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504848 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274849
[email protected]b4404c02009-04-10 16:38:524850 MockRead data_reads[] = {
4851 MockRead("HTTP/1.1 204 No Content\r\n"
4852 "Content-Length: 0\r\n"
4853 "Content-Type: text/html\r\n\r\n"),
4854 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064855 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524856 };
4857
[email protected]31a2bfe2010-02-09 08:03:394858 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074859 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524860
[email protected]49639fa2011-12-20 23:22:414861 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524862
[email protected]49639fa2011-12-20 23:22:414863 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424864 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524865
4866 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424867 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524868
[email protected]1c773ea12009-04-28 19:58:424869 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504870 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524871
[email protected]90499482013-06-01 00:39:504872 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524873 std::string status_line = response->headers->GetStatusLine();
4874 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4875
[email protected]90499482013-06-01 00:39:504876 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524877
4878 std::string response_data;
4879 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424880 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524881 EXPECT_EQ("", response_data);
4882
4883 // Empty the current queue. This is necessary because idle sockets are
4884 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344885 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524886
4887 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504888 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524889}
4890
[email protected]23e482282013-06-14 16:08:024891TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064892 ScopedVector<UploadElementReader> element_readers;
4893 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:204894 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:274895
[email protected]1c773ea12009-04-28 19:58:424896 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514897 // Transaction 1: a GET request that succeeds. The socket is recycled
4898 // after use.
4899 request[0].method = "GET";
4900 request[0].url = GURL("http://www.google.com/");
4901 request[0].load_flags = 0;
4902 // Transaction 2: a POST request. Reuses the socket kept alive from
4903 // transaction 1. The first attempts fails when writing the POST data.
4904 // This causes the transaction to retry with a new socket. The second
4905 // attempt succeeds.
4906 request[1].method = "POST";
4907 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274908 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514909 request[1].load_flags = 0;
4910
[email protected]bb88e1d32013-05-03 23:11:074911 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514912
4913 // The first socket is used for transaction 1 and the first attempt of
4914 // transaction 2.
4915
4916 // The response of transaction 1.
4917 MockRead data_reads1[] = {
4918 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4919 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064920 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514921 };
4922 // The mock write results of transaction 1 and the first attempt of
4923 // transaction 2.
4924 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064925 MockWrite(SYNCHRONOUS, 64), // GET
4926 MockWrite(SYNCHRONOUS, 93), // POST
4927 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514928 };
[email protected]31a2bfe2010-02-09 08:03:394929 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4930 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514931
4932 // The second socket is used for the second attempt of transaction 2.
4933
4934 // The response of transaction 2.
4935 MockRead data_reads2[] = {
4936 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4937 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064938 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514939 };
4940 // The mock write results of the second attempt of transaction 2.
4941 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064942 MockWrite(SYNCHRONOUS, 93), // POST
4943 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514944 };
[email protected]31a2bfe2010-02-09 08:03:394945 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4946 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514947
[email protected]bb88e1d32013-05-03 23:11:074948 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4949 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514950
4951 const char* kExpectedResponseData[] = {
4952 "hello world", "welcome"
4953 };
4954
4955 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424956 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504957 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514958
[email protected]49639fa2011-12-20 23:22:414959 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514960
[email protected]49639fa2011-12-20 23:22:414961 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424962 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514963
4964 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424965 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514966
[email protected]1c773ea12009-04-28 19:58:424967 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504968 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514969
[email protected]90499482013-06-01 00:39:504970 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514971 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4972
4973 std::string response_data;
4974 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424975 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514976 EXPECT_EQ(kExpectedResponseData[i], response_data);
4977 }
4978}
[email protected]f9ee6b52008-11-08 06:46:234979
4980// Test the request-challenge-retry sequence for basic auth when there is
4981// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164982// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024983TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424984 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234985 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294986 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414987 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294988
[email protected]3fe8d2f82013-10-17 08:56:074989 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274990 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074991 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274992
[email protected]a97cca42009-08-14 01:00:294993 // The password contains an escaped character -- for this test to pass it
4994 // will need to be unescaped by HttpNetworkTransaction.
4995 EXPECT_EQ("b%40r", request.url.password());
4996
[email protected]f9ee6b52008-11-08 06:46:234997 MockWrite data_writes1[] = {
4998 MockWrite("GET / HTTP/1.1\r\n"
4999 "Host: www.google.com\r\n"
5000 "Connection: keep-alive\r\n\r\n"),
5001 };
5002
5003 MockRead data_reads1[] = {
5004 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5005 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5006 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065007 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235008 };
5009
[email protected]2262e3a2012-05-22 16:08:165010 // After the challenge above, the transaction will be restarted using the
5011 // identity from the url (foo, b@r) to answer the challenge.
5012 MockWrite data_writes2[] = {
5013 MockWrite("GET / HTTP/1.1\r\n"
5014 "Host: www.google.com\r\n"
5015 "Connection: keep-alive\r\n"
5016 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5017 };
5018
5019 MockRead data_reads2[] = {
5020 MockRead("HTTP/1.0 200 OK\r\n"),
5021 MockRead("Content-Length: 100\r\n\r\n"),
5022 MockRead(SYNCHRONOUS, OK),
5023 };
5024
[email protected]31a2bfe2010-02-09 08:03:395025 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5026 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165027 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5028 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075029 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5030 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235031
[email protected]49639fa2011-12-20 23:22:415032 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415033 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425034 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235035 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425036 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165037 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5038
5039 TestCompletionCallback callback2;
5040 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5041 EXPECT_EQ(ERR_IO_PENDING, rv);
5042 rv = callback2.WaitForResult();
5043 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225044 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5045
[email protected]2262e3a2012-05-22 16:08:165046 const HttpResponseInfo* response = trans->GetResponseInfo();
5047 ASSERT_TRUE(response != NULL);
5048
5049 // There is no challenge info, since the identity in URL worked.
5050 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5051
5052 EXPECT_EQ(100, response->headers->GetContentLength());
5053
5054 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345055 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165056}
5057
5058// Test the request-challenge-retry sequence for basic auth when there is an
5059// incorrect identity in the URL. The identity from the URL should be used only
5060// once.
[email protected]23e482282013-06-14 16:08:025061TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165062 HttpRequestInfo request;
5063 request.method = "GET";
5064 // Note: the URL has a username:password in it. The password "baz" is
5065 // wrong (should be "bar").
5066 request.url = GURL("http://foo:[email protected]/");
5067
5068 request.load_flags = LOAD_NORMAL;
5069
[email protected]3fe8d2f82013-10-17 08:56:075070 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165071 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075072 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2262e3a2012-05-22 16:08:165073
5074 MockWrite data_writes1[] = {
5075 MockWrite("GET / HTTP/1.1\r\n"
5076 "Host: www.google.com\r\n"
5077 "Connection: keep-alive\r\n\r\n"),
5078 };
5079
5080 MockRead data_reads1[] = {
5081 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5082 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5083 MockRead("Content-Length: 10\r\n\r\n"),
5084 MockRead(SYNCHRONOUS, ERR_FAILED),
5085 };
5086
5087 // After the challenge above, the transaction will be restarted using the
5088 // identity from the url (foo, baz) to answer the challenge.
5089 MockWrite data_writes2[] = {
5090 MockWrite("GET / HTTP/1.1\r\n"
5091 "Host: www.google.com\r\n"
5092 "Connection: keep-alive\r\n"
5093 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5094 };
5095
5096 MockRead data_reads2[] = {
5097 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5098 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5099 MockRead("Content-Length: 10\r\n\r\n"),
5100 MockRead(SYNCHRONOUS, ERR_FAILED),
5101 };
5102
5103 // After the challenge above, the transaction will be restarted using the
5104 // identity supplied by the user (foo, bar) to answer the challenge.
5105 MockWrite data_writes3[] = {
5106 MockWrite("GET / HTTP/1.1\r\n"
5107 "Host: www.google.com\r\n"
5108 "Connection: keep-alive\r\n"
5109 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5110 };
5111
5112 MockRead data_reads3[] = {
5113 MockRead("HTTP/1.0 200 OK\r\n"),
5114 MockRead("Content-Length: 100\r\n\r\n"),
5115 MockRead(SYNCHRONOUS, OK),
5116 };
5117
5118 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5119 data_writes1, arraysize(data_writes1));
5120 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5121 data_writes2, arraysize(data_writes2));
5122 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5123 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075124 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5125 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5126 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165127
5128 TestCompletionCallback callback1;
5129
5130 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5131 EXPECT_EQ(ERR_IO_PENDING, rv);
5132
5133 rv = callback1.WaitForResult();
5134 EXPECT_EQ(OK, rv);
5135
5136 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5137 TestCompletionCallback callback2;
5138 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5139 EXPECT_EQ(ERR_IO_PENDING, rv);
5140 rv = callback2.WaitForResult();
5141 EXPECT_EQ(OK, rv);
5142 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5143
5144 const HttpResponseInfo* response = trans->GetResponseInfo();
5145 ASSERT_TRUE(response != NULL);
5146 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5147
5148 TestCompletionCallback callback3;
5149 rv = trans->RestartWithAuth(
5150 AuthCredentials(kFoo, kBar), callback3.callback());
5151 EXPECT_EQ(ERR_IO_PENDING, rv);
5152 rv = callback3.WaitForResult();
5153 EXPECT_EQ(OK, rv);
5154 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5155
5156 response = trans->GetResponseInfo();
5157 ASSERT_TRUE(response != NULL);
5158
5159 // There is no challenge info, since the identity worked.
5160 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5161
5162 EXPECT_EQ(100, response->headers->GetContentLength());
5163
[email protected]ea9dc9a2009-09-05 00:43:325164 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345165 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325166}
5167
[email protected]2217aa22013-10-11 03:03:545168
5169// Test the request-challenge-retry sequence for basic auth when there is a
5170// correct identity in the URL, but its use is being suppressed. The identity
5171// from the URL should never be used.
5172TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5173 HttpRequestInfo request;
5174 request.method = "GET";
5175 request.url = GURL("http://foo:[email protected]/");
5176 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5177
[email protected]3fe8d2f82013-10-17 08:56:075178 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545179 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075180 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2217aa22013-10-11 03:03:545181
5182 MockWrite data_writes1[] = {
5183 MockWrite("GET / HTTP/1.1\r\n"
5184 "Host: www.google.com\r\n"
5185 "Connection: keep-alive\r\n\r\n"),
5186 };
5187
5188 MockRead data_reads1[] = {
5189 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5190 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5191 MockRead("Content-Length: 10\r\n\r\n"),
5192 MockRead(SYNCHRONOUS, ERR_FAILED),
5193 };
5194
5195 // After the challenge above, the transaction will be restarted using the
5196 // identity supplied by the user, not the one in the URL, to answer the
5197 // challenge.
5198 MockWrite data_writes3[] = {
5199 MockWrite("GET / HTTP/1.1\r\n"
5200 "Host: www.google.com\r\n"
5201 "Connection: keep-alive\r\n"
5202 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5203 };
5204
5205 MockRead data_reads3[] = {
5206 MockRead("HTTP/1.0 200 OK\r\n"),
5207 MockRead("Content-Length: 100\r\n\r\n"),
5208 MockRead(SYNCHRONOUS, OK),
5209 };
5210
5211 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5212 data_writes1, arraysize(data_writes1));
5213 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5214 data_writes3, arraysize(data_writes3));
5215 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5216 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5217
5218 TestCompletionCallback callback1;
5219 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5220 EXPECT_EQ(ERR_IO_PENDING, rv);
5221 rv = callback1.WaitForResult();
5222 EXPECT_EQ(OK, rv);
5223 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5224
5225 const HttpResponseInfo* response = trans->GetResponseInfo();
5226 ASSERT_TRUE(response != NULL);
5227 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5228
5229 TestCompletionCallback callback3;
5230 rv = trans->RestartWithAuth(
5231 AuthCredentials(kFoo, kBar), callback3.callback());
5232 EXPECT_EQ(ERR_IO_PENDING, rv);
5233 rv = callback3.WaitForResult();
5234 EXPECT_EQ(OK, rv);
5235 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5236
5237 response = trans->GetResponseInfo();
5238 ASSERT_TRUE(response != NULL);
5239
5240 // There is no challenge info, since the identity worked.
5241 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5242 EXPECT_EQ(100, response->headers->GetContentLength());
5243
5244 // Empty the current queue.
5245 base::MessageLoop::current()->RunUntilIdle();
5246}
5247
[email protected]f9ee6b52008-11-08 06:46:235248// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025249TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075250 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235251
5252 // Transaction 1: authenticate (foo, bar) on MyRealm1
5253 {
[email protected]1c773ea12009-04-28 19:58:425254 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235255 request.method = "GET";
5256 request.url = GURL("http://www.google.com/x/y/z");
5257 request.load_flags = 0;
5258
[email protected]262eec82013-03-19 21:01:365259 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275261
[email protected]f9ee6b52008-11-08 06:46:235262 MockWrite data_writes1[] = {
5263 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5264 "Host: www.google.com\r\n"
5265 "Connection: keep-alive\r\n\r\n"),
5266 };
5267
5268 MockRead data_reads1[] = {
5269 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5270 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5271 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065272 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235273 };
5274
5275 // Resend with authorization (username=foo, password=bar)
5276 MockWrite data_writes2[] = {
5277 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5278 "Host: www.google.com\r\n"
5279 "Connection: keep-alive\r\n"
5280 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5281 };
5282
5283 // Sever accepts the authorization.
5284 MockRead data_reads2[] = {
5285 MockRead("HTTP/1.0 200 OK\r\n"),
5286 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065287 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235288 };
5289
[email protected]31a2bfe2010-02-09 08:03:395290 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5291 data_writes1, arraysize(data_writes1));
5292 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5293 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075294 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5295 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235296
[email protected]49639fa2011-12-20 23:22:415297 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235298
[email protected]49639fa2011-12-20 23:22:415299 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425300 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235301
5302 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425303 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235304
[email protected]1c773ea12009-04-28 19:58:425305 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505306 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045307 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235308
[email protected]49639fa2011-12-20 23:22:415309 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235310
[email protected]49639fa2011-12-20 23:22:415311 rv = trans->RestartWithAuth(
5312 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425313 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235314
5315 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425316 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235317
5318 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505319 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235320 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5321 EXPECT_EQ(100, response->headers->GetContentLength());
5322 }
5323
5324 // ------------------------------------------------------------------------
5325
5326 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5327 {
[email protected]1c773ea12009-04-28 19:58:425328 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235329 request.method = "GET";
5330 // Note that Transaction 1 was at /x/y/z, so this is in the same
5331 // protection space as MyRealm1.
5332 request.url = GURL("http://www.google.com/x/y/a/b");
5333 request.load_flags = 0;
5334
[email protected]262eec82013-03-19 21:01:365335 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505336 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275337
[email protected]f9ee6b52008-11-08 06:46:235338 MockWrite data_writes1[] = {
5339 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5340 "Host: www.google.com\r\n"
5341 "Connection: keep-alive\r\n"
5342 // Send preemptive authorization for MyRealm1
5343 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5344 };
5345
5346 // The server didn't like the preemptive authorization, and
5347 // challenges us for a different realm (MyRealm2).
5348 MockRead data_reads1[] = {
5349 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5350 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5351 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065352 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235353 };
5354
5355 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5356 MockWrite data_writes2[] = {
5357 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5358 "Host: www.google.com\r\n"
5359 "Connection: keep-alive\r\n"
5360 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5361 };
5362
5363 // Sever accepts the authorization.
5364 MockRead data_reads2[] = {
5365 MockRead("HTTP/1.0 200 OK\r\n"),
5366 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065367 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235368 };
5369
[email protected]31a2bfe2010-02-09 08:03:395370 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5371 data_writes1, arraysize(data_writes1));
5372 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5373 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075374 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5375 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235376
[email protected]49639fa2011-12-20 23:22:415377 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235378
[email protected]49639fa2011-12-20 23:22:415379 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425380 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235381
5382 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425383 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235384
[email protected]1c773ea12009-04-28 19:58:425385 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505386 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045387 ASSERT_TRUE(response->auth_challenge.get());
5388 EXPECT_FALSE(response->auth_challenge->is_proxy);
5389 EXPECT_EQ("www.google.com:80",
5390 response->auth_challenge->challenger.ToString());
5391 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5392 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235393
[email protected]49639fa2011-12-20 23:22:415394 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235395
[email protected]49639fa2011-12-20 23:22:415396 rv = trans->RestartWithAuth(
5397 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425398 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235399
5400 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425401 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235402
5403 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505404 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235405 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5406 EXPECT_EQ(100, response->headers->GetContentLength());
5407 }
5408
5409 // ------------------------------------------------------------------------
5410
5411 // Transaction 3: Resend a request in MyRealm's protection space --
5412 // succeed with preemptive authorization.
5413 {
[email protected]1c773ea12009-04-28 19:58:425414 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235415 request.method = "GET";
5416 request.url = GURL("http://www.google.com/x/y/z2");
5417 request.load_flags = 0;
5418
[email protected]262eec82013-03-19 21:01:365419 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275421
[email protected]f9ee6b52008-11-08 06:46:235422 MockWrite data_writes1[] = {
5423 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5424 "Host: www.google.com\r\n"
5425 "Connection: keep-alive\r\n"
5426 // The authorization for MyRealm1 gets sent preemptively
5427 // (since the url is in the same protection space)
5428 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5429 };
5430
5431 // Sever accepts the preemptive authorization
5432 MockRead data_reads1[] = {
5433 MockRead("HTTP/1.0 200 OK\r\n"),
5434 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065435 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235436 };
5437
[email protected]31a2bfe2010-02-09 08:03:395438 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5439 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075440 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235441
[email protected]49639fa2011-12-20 23:22:415442 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235443
[email protected]49639fa2011-12-20 23:22:415444 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425445 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235446
5447 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425448 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235449
[email protected]1c773ea12009-04-28 19:58:425450 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505451 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235452
5453 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5454 EXPECT_EQ(100, response->headers->GetContentLength());
5455 }
5456
5457 // ------------------------------------------------------------------------
5458
5459 // Transaction 4: request another URL in MyRealm (however the
5460 // url is not known to belong to the protection space, so no pre-auth).
5461 {
[email protected]1c773ea12009-04-28 19:58:425462 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235463 request.method = "GET";
5464 request.url = GURL("http://www.google.com/x/1");
5465 request.load_flags = 0;
5466
[email protected]262eec82013-03-19 21:01:365467 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505468 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275469
[email protected]f9ee6b52008-11-08 06:46:235470 MockWrite data_writes1[] = {
5471 MockWrite("GET /x/1 HTTP/1.1\r\n"
5472 "Host: www.google.com\r\n"
5473 "Connection: keep-alive\r\n\r\n"),
5474 };
5475
5476 MockRead data_reads1[] = {
5477 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5478 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5479 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065480 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235481 };
5482
5483 // Resend with authorization from MyRealm's cache.
5484 MockWrite data_writes2[] = {
5485 MockWrite("GET /x/1 HTTP/1.1\r\n"
5486 "Host: www.google.com\r\n"
5487 "Connection: keep-alive\r\n"
5488 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5489 };
5490
5491 // Sever accepts the authorization.
5492 MockRead data_reads2[] = {
5493 MockRead("HTTP/1.0 200 OK\r\n"),
5494 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065495 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235496 };
5497
[email protected]31a2bfe2010-02-09 08:03:395498 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5499 data_writes1, arraysize(data_writes1));
5500 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5501 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075502 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5503 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235504
[email protected]49639fa2011-12-20 23:22:415505 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235506
[email protected]49639fa2011-12-20 23:22:415507 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425508 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235509
5510 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425511 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235512
[email protected]0757e7702009-03-27 04:00:225513 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415514 TestCompletionCallback callback2;
5515 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425516 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225517 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425518 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225519 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5520
[email protected]1c773ea12009-04-28 19:58:425521 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505522 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235523 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5524 EXPECT_EQ(100, response->headers->GetContentLength());
5525 }
5526
5527 // ------------------------------------------------------------------------
5528
5529 // Transaction 5: request a URL in MyRealm, but the server rejects the
5530 // cached identity. Should invalidate and re-prompt.
5531 {
[email protected]1c773ea12009-04-28 19:58:425532 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235533 request.method = "GET";
5534 request.url = GURL("http://www.google.com/p/q/t");
5535 request.load_flags = 0;
5536
[email protected]262eec82013-03-19 21:01:365537 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505538 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275539
[email protected]f9ee6b52008-11-08 06:46:235540 MockWrite data_writes1[] = {
5541 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5542 "Host: www.google.com\r\n"
5543 "Connection: keep-alive\r\n\r\n"),
5544 };
5545
5546 MockRead data_reads1[] = {
5547 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5548 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5549 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065550 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235551 };
5552
5553 // Resend with authorization from cache for MyRealm.
5554 MockWrite data_writes2[] = {
5555 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5556 "Host: www.google.com\r\n"
5557 "Connection: keep-alive\r\n"
5558 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5559 };
5560
5561 // Sever rejects the authorization.
5562 MockRead data_reads2[] = {
5563 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5564 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5565 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065566 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235567 };
5568
5569 // At this point we should prompt for new credentials for MyRealm.
5570 // Restart with username=foo3, password=foo4.
5571 MockWrite data_writes3[] = {
5572 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5573 "Host: www.google.com\r\n"
5574 "Connection: keep-alive\r\n"
5575 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5576 };
5577
5578 // Sever accepts the authorization.
5579 MockRead data_reads3[] = {
5580 MockRead("HTTP/1.0 200 OK\r\n"),
5581 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065582 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235583 };
5584
[email protected]31a2bfe2010-02-09 08:03:395585 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5586 data_writes1, arraysize(data_writes1));
5587 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5588 data_writes2, arraysize(data_writes2));
5589 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5590 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075591 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5592 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5593 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235594
[email protected]49639fa2011-12-20 23:22:415595 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235596
[email protected]49639fa2011-12-20 23:22:415597 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425598 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235599
5600 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425601 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235602
[email protected]0757e7702009-03-27 04:00:225603 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415604 TestCompletionCallback callback2;
5605 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425606 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225607 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425608 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225609 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5610
[email protected]1c773ea12009-04-28 19:58:425611 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505612 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045613 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235614
[email protected]49639fa2011-12-20 23:22:415615 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235616
[email protected]49639fa2011-12-20 23:22:415617 rv = trans->RestartWithAuth(
5618 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425619 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235620
[email protected]0757e7702009-03-27 04:00:225621 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425622 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235623
5624 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505625 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235626 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5627 EXPECT_EQ(100, response->headers->GetContentLength());
5628 }
5629}
[email protected]89ceba9a2009-03-21 03:46:065630
[email protected]3c32c5f2010-05-18 15:18:125631// Tests that nonce count increments when multiple auth attempts
5632// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025633TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445634 HttpAuthHandlerDigest::Factory* digest_factory =
5635 new HttpAuthHandlerDigest::Factory();
5636 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5637 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5638 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075639 session_deps_.http_auth_handler_factory.reset(digest_factory);
5640 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125641
5642 // Transaction 1: authenticate (foo, bar) on MyRealm1
5643 {
[email protected]3c32c5f2010-05-18 15:18:125644 HttpRequestInfo request;
5645 request.method = "GET";
5646 request.url = GURL("http://www.google.com/x/y/z");
5647 request.load_flags = 0;
5648
[email protected]262eec82013-03-19 21:01:365649 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505650 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275651
[email protected]3c32c5f2010-05-18 15:18:125652 MockWrite data_writes1[] = {
5653 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5654 "Host: www.google.com\r\n"
5655 "Connection: keep-alive\r\n\r\n"),
5656 };
5657
5658 MockRead data_reads1[] = {
5659 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5660 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5661 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065662 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125663 };
5664
5665 // Resend with authorization (username=foo, password=bar)
5666 MockWrite data_writes2[] = {
5667 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5668 "Host: www.google.com\r\n"
5669 "Connection: keep-alive\r\n"
5670 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5671 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5672 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5673 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5674 };
5675
5676 // Sever accepts the authorization.
5677 MockRead data_reads2[] = {
5678 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065679 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125680 };
5681
5682 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5683 data_writes1, arraysize(data_writes1));
5684 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5685 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075686 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5687 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125688
[email protected]49639fa2011-12-20 23:22:415689 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125690
[email protected]49639fa2011-12-20 23:22:415691 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125692 EXPECT_EQ(ERR_IO_PENDING, rv);
5693
5694 rv = callback1.WaitForResult();
5695 EXPECT_EQ(OK, rv);
5696
5697 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505698 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045699 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125700
[email protected]49639fa2011-12-20 23:22:415701 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125702
[email protected]49639fa2011-12-20 23:22:415703 rv = trans->RestartWithAuth(
5704 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125705 EXPECT_EQ(ERR_IO_PENDING, rv);
5706
5707 rv = callback2.WaitForResult();
5708 EXPECT_EQ(OK, rv);
5709
5710 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505711 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125712 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5713 }
5714
5715 // ------------------------------------------------------------------------
5716
5717 // Transaction 2: Request another resource in digestive's protection space.
5718 // This will preemptively add an Authorization header which should have an
5719 // "nc" value of 2 (as compared to 1 in the first use.
5720 {
[email protected]3c32c5f2010-05-18 15:18:125721 HttpRequestInfo request;
5722 request.method = "GET";
5723 // Note that Transaction 1 was at /x/y/z, so this is in the same
5724 // protection space as digest.
5725 request.url = GURL("http://www.google.com/x/y/a/b");
5726 request.load_flags = 0;
5727
[email protected]262eec82013-03-19 21:01:365728 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505729 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275730
[email protected]3c32c5f2010-05-18 15:18:125731 MockWrite data_writes1[] = {
5732 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5733 "Host: www.google.com\r\n"
5734 "Connection: keep-alive\r\n"
5735 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5736 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5737 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5738 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5739 };
5740
5741 // Sever accepts the authorization.
5742 MockRead data_reads1[] = {
5743 MockRead("HTTP/1.0 200 OK\r\n"),
5744 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065745 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125746 };
5747
5748 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5749 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075750 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125751
[email protected]49639fa2011-12-20 23:22:415752 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125753
[email protected]49639fa2011-12-20 23:22:415754 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125755 EXPECT_EQ(ERR_IO_PENDING, rv);
5756
5757 rv = callback1.WaitForResult();
5758 EXPECT_EQ(OK, rv);
5759
5760 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505761 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125762 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5763 }
5764}
5765
[email protected]89ceba9a2009-03-21 03:46:065766// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025767TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065768 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075769 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405770 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075771 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]89ceba9a2009-03-21 03:46:065772
5773 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065774 trans->read_buf_ = new IOBuffer(15);
5775 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205776 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065777
5778 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145779 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575780 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085781 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575782 response->response_time = base::Time::Now();
5783 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065784
5785 { // Setup state for response_.vary_data
5786 HttpRequestInfo request;
5787 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5788 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275789 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435790 request.extra_headers.SetHeader("Foo", "1");
5791 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505792 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065793 }
5794
5795 // Cause the above state to be reset.
5796 trans->ResetStateForRestart();
5797
5798 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075799 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065800 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205801 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575802 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5803 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045804 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085805 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575806 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065807}
5808
[email protected]bacff652009-03-31 17:50:335809// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025810TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335811 HttpRequestInfo request;
5812 request.method = "GET";
5813 request.url = GURL("https://www.google.com/");
5814 request.load_flags = 0;
5815
[email protected]3fe8d2f82013-10-17 08:56:075816 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275817 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275819
[email protected]bacff652009-03-31 17:50:335820 MockWrite data_writes[] = {
5821 MockWrite("GET / HTTP/1.1\r\n"
5822 "Host: www.google.com\r\n"
5823 "Connection: keep-alive\r\n\r\n"),
5824 };
5825
5826 MockRead data_reads[] = {
5827 MockRead("HTTP/1.0 200 OK\r\n"),
5828 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5829 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065830 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335831 };
5832
[email protected]5ecc992a42009-11-11 01:41:595833 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395834 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5835 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065836 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5837 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335838
[email protected]bb88e1d32013-05-03 23:11:075839 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5840 session_deps_.socket_factory->AddSocketDataProvider(&data);
5841 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5842 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335843
[email protected]49639fa2011-12-20 23:22:415844 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335845
[email protected]49639fa2011-12-20 23:22:415846 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335847 EXPECT_EQ(ERR_IO_PENDING, rv);
5848
5849 rv = callback.WaitForResult();
5850 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5851
[email protected]49639fa2011-12-20 23:22:415852 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335853 EXPECT_EQ(ERR_IO_PENDING, rv);
5854
5855 rv = callback.WaitForResult();
5856 EXPECT_EQ(OK, rv);
5857
5858 const HttpResponseInfo* response = trans->GetResponseInfo();
5859
[email protected]fe2255a2011-09-20 19:37:505860 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335861 EXPECT_EQ(100, response->headers->GetContentLength());
5862}
5863
5864// Test HTTPS connections to a site with a bad certificate, going through a
5865// proxy
[email protected]23e482282013-06-14 16:08:025866TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075867 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335868
5869 HttpRequestInfo request;
5870 request.method = "GET";
5871 request.url = GURL("https://www.google.com/");
5872 request.load_flags = 0;
5873
5874 MockWrite proxy_writes[] = {
5875 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455876 "Host: www.google.com\r\n"
5877 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335878 };
5879
5880 MockRead proxy_reads[] = {
5881 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065882 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335883 };
5884
5885 MockWrite data_writes[] = {
5886 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455887 "Host: www.google.com\r\n"
5888 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335889 MockWrite("GET / HTTP/1.1\r\n"
5890 "Host: www.google.com\r\n"
5891 "Connection: keep-alive\r\n\r\n"),
5892 };
5893
5894 MockRead data_reads[] = {
5895 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5896 MockRead("HTTP/1.0 200 OK\r\n"),
5897 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5898 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065899 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335900 };
5901
[email protected]31a2bfe2010-02-09 08:03:395902 StaticSocketDataProvider ssl_bad_certificate(
5903 proxy_reads, arraysize(proxy_reads),
5904 proxy_writes, arraysize(proxy_writes));
5905 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5906 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065907 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5908 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335909
[email protected]bb88e1d32013-05-03 23:11:075910 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5911 session_deps_.socket_factory->AddSocketDataProvider(&data);
5912 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5913 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335914
[email protected]49639fa2011-12-20 23:22:415915 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335916
5917 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075918 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335919
[email protected]3fe8d2f82013-10-17 08:56:075920 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405921 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]bacff652009-03-31 17:50:335923
[email protected]49639fa2011-12-20 23:22:415924 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335925 EXPECT_EQ(ERR_IO_PENDING, rv);
5926
5927 rv = callback.WaitForResult();
5928 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5929
[email protected]49639fa2011-12-20 23:22:415930 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335931 EXPECT_EQ(ERR_IO_PENDING, rv);
5932
5933 rv = callback.WaitForResult();
5934 EXPECT_EQ(OK, rv);
5935
5936 const HttpResponseInfo* response = trans->GetResponseInfo();
5937
[email protected]fe2255a2011-09-20 19:37:505938 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335939 EXPECT_EQ(100, response->headers->GetContentLength());
5940 }
5941}
5942
[email protected]2df19bb2010-08-25 20:13:465943
5944// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025945TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075946 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205947 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5948 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075949 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465950
5951 HttpRequestInfo request;
5952 request.method = "GET";
5953 request.url = GURL("https://www.google.com/");
5954 request.load_flags = 0;
5955
5956 MockWrite data_writes[] = {
5957 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5958 "Host: www.google.com\r\n"
5959 "Proxy-Connection: keep-alive\r\n\r\n"),
5960 MockWrite("GET / HTTP/1.1\r\n"
5961 "Host: www.google.com\r\n"
5962 "Connection: keep-alive\r\n\r\n"),
5963 };
5964
5965 MockRead data_reads[] = {
5966 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5967 MockRead("HTTP/1.1 200 OK\r\n"),
5968 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5969 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065970 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465971 };
5972
5973 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5974 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065975 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5976 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465977
[email protected]bb88e1d32013-05-03 23:11:075978 session_deps_.socket_factory->AddSocketDataProvider(&data);
5979 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5980 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465981
[email protected]49639fa2011-12-20 23:22:415982 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465983
[email protected]3fe8d2f82013-10-17 08:56:075984 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465985 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075986 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:465987
[email protected]49639fa2011-12-20 23:22:415988 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465989 EXPECT_EQ(ERR_IO_PENDING, rv);
5990
5991 rv = callback.WaitForResult();
5992 EXPECT_EQ(OK, rv);
5993 const HttpResponseInfo* response = trans->GetResponseInfo();
5994
[email protected]fe2255a2011-09-20 19:37:505995 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465996
5997 EXPECT_TRUE(response->headers->IsKeepAlive());
5998 EXPECT_EQ(200, response->headers->response_code());
5999 EXPECT_EQ(100, response->headers->GetContentLength());
6000 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206001
6002 LoadTimingInfo load_timing_info;
6003 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6004 TestLoadTimingNotReusedWithPac(load_timing_info,
6005 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466006}
6007
[email protected]511f6f52010-12-17 03:58:296008// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026009TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076010 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206011 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6012 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076013 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296014
6015 HttpRequestInfo request;
6016 request.method = "GET";
6017 request.url = GURL("https://www.google.com/");
6018 request.load_flags = 0;
6019
6020 MockWrite data_writes[] = {
6021 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6022 "Host: www.google.com\r\n"
6023 "Proxy-Connection: keep-alive\r\n\r\n"),
6024 };
6025
6026 MockRead data_reads[] = {
6027 MockRead("HTTP/1.1 302 Redirect\r\n"),
6028 MockRead("Location: http://login.example.com/\r\n"),
6029 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066030 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296031 };
6032
6033 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6034 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066035 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296036
[email protected]bb88e1d32013-05-03 23:11:076037 session_deps_.socket_factory->AddSocketDataProvider(&data);
6038 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296039
[email protected]49639fa2011-12-20 23:22:416040 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296041
[email protected]3fe8d2f82013-10-17 08:56:076042 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296043 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296045
[email protected]49639fa2011-12-20 23:22:416046 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296047 EXPECT_EQ(ERR_IO_PENDING, rv);
6048
6049 rv = callback.WaitForResult();
6050 EXPECT_EQ(OK, rv);
6051 const HttpResponseInfo* response = trans->GetResponseInfo();
6052
[email protected]fe2255a2011-09-20 19:37:506053 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296054
6055 EXPECT_EQ(302, response->headers->response_code());
6056 std::string url;
6057 EXPECT_TRUE(response->headers->IsRedirect(&url));
6058 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206059
6060 // In the case of redirects from proxies, HttpNetworkTransaction returns
6061 // timing for the proxy connection instead of the connection to the host,
6062 // and no send / receive times.
6063 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6064 LoadTimingInfo load_timing_info;
6065 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6066
6067 EXPECT_FALSE(load_timing_info.socket_reused);
6068 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6069
6070 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6071 EXPECT_LE(load_timing_info.proxy_resolve_start,
6072 load_timing_info.proxy_resolve_end);
6073 EXPECT_LE(load_timing_info.proxy_resolve_end,
6074 load_timing_info.connect_timing.connect_start);
6075 ExpectConnectTimingHasTimes(
6076 load_timing_info.connect_timing,
6077 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6078
6079 EXPECT_TRUE(load_timing_info.send_start.is_null());
6080 EXPECT_TRUE(load_timing_info.send_end.is_null());
6081 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296082}
6083
6084// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026085TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076086 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296087 ProxyService::CreateFixed("https://proxy:70"));
6088
6089 HttpRequestInfo request;
6090 request.method = "GET";
6091 request.url = GURL("https://www.google.com/");
6092 request.load_flags = 0;
6093
[email protected]9075f51c2013-08-15 17:53:546094 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6095 LOWEST));
[email protected]c10b20852013-05-15 21:29:206096 scoped_ptr<SpdyFrame> goaway(
6097 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296098 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066099 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:126100 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296101 };
6102
6103 static const char* const kExtraHeaders[] = {
6104 "location",
6105 "http://login.example.com/",
6106 };
[email protected]ff98d7f02012-03-22 21:44:196107 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026108 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296109 arraysize(kExtraHeaders)/2, 1));
6110 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066111 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6112 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:296113 };
6114
[email protected]dd54bd82012-07-19 23:44:576115 DelayedSocketData data(
6116 1, // wait for one write to finish before reading.
6117 data_reads, arraysize(data_reads),
6118 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066119 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026120 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296121
[email protected]bb88e1d32013-05-03 23:11:076122 session_deps_.socket_factory->AddSocketDataProvider(&data);
6123 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296124
[email protected]49639fa2011-12-20 23:22:416125 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296126
[email protected]3fe8d2f82013-10-17 08:56:076127 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296128 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076129 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296130
[email protected]49639fa2011-12-20 23:22:416131 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296132 EXPECT_EQ(ERR_IO_PENDING, rv);
6133
6134 rv = callback.WaitForResult();
6135 EXPECT_EQ(OK, rv);
6136 const HttpResponseInfo* response = trans->GetResponseInfo();
6137
[email protected]fe2255a2011-09-20 19:37:506138 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296139
6140 EXPECT_EQ(302, response->headers->response_code());
6141 std::string url;
6142 EXPECT_TRUE(response->headers->IsRedirect(&url));
6143 EXPECT_EQ("http://login.example.com/", url);
6144}
6145
[email protected]4eddbc732012-08-09 05:40:176146// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026147TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176148 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076149 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296150 ProxyService::CreateFixed("https://proxy:70"));
6151
6152 HttpRequestInfo request;
6153 request.method = "GET";
6154 request.url = GURL("https://www.google.com/");
6155 request.load_flags = 0;
6156
6157 MockWrite data_writes[] = {
6158 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6159 "Host: www.google.com\r\n"
6160 "Proxy-Connection: keep-alive\r\n\r\n"),
6161 };
6162
6163 MockRead data_reads[] = {
6164 MockRead("HTTP/1.1 404 Not Found\r\n"),
6165 MockRead("Content-Length: 23\r\n\r\n"),
6166 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066167 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296168 };
6169
6170 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6171 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066172 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296173
[email protected]bb88e1d32013-05-03 23:11:076174 session_deps_.socket_factory->AddSocketDataProvider(&data);
6175 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296176
[email protected]49639fa2011-12-20 23:22:416177 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296178
[email protected]3fe8d2f82013-10-17 08:56:076179 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296180 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296182
[email protected]49639fa2011-12-20 23:22:416183 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296184 EXPECT_EQ(ERR_IO_PENDING, rv);
6185
6186 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176187 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296188
[email protected]4eddbc732012-08-09 05:40:176189 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296190}
6191
[email protected]4eddbc732012-08-09 05:40:176192// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026193TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176194 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076195 session_deps_.proxy_service.reset(
6196 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296197
6198 HttpRequestInfo request;
6199 request.method = "GET";
6200 request.url = GURL("https://www.google.com/");
6201 request.load_flags = 0;
6202
[email protected]9075f51c2013-08-15 17:53:546203 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6204 LOWEST));
[email protected]c10b20852013-05-15 21:29:206205 scoped_ptr<SpdyFrame> rst(
6206 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296207 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066208 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176209 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296210 };
6211
6212 static const char* const kExtraHeaders[] = {
6213 "location",
6214 "http://login.example.com/",
6215 };
[email protected]ff98d7f02012-03-22 21:44:196216 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026217 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296218 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196219 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026220 spdy_util_.ConstructSpdyBodyFrame(
6221 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296222 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066223 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6224 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176225 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296226 };
6227
[email protected]dd54bd82012-07-19 23:44:576228 DelayedSocketData data(
6229 1, // wait for one write to finish before reading.
6230 data_reads, arraysize(data_reads),
6231 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066232 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026233 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296234
[email protected]bb88e1d32013-05-03 23:11:076235 session_deps_.socket_factory->AddSocketDataProvider(&data);
6236 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296237
[email protected]49639fa2011-12-20 23:22:416238 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296239
[email protected]3fe8d2f82013-10-17 08:56:076240 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296241 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076242 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296243
[email protected]49639fa2011-12-20 23:22:416244 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296245 EXPECT_EQ(ERR_IO_PENDING, rv);
6246
6247 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176248 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296249
[email protected]4eddbc732012-08-09 05:40:176250 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296251}
6252
[email protected]0c5fb722012-02-28 11:50:356253// Test the request-challenge-retry sequence for basic auth, through
6254// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026255TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356256 HttpRequestInfo request;
6257 request.method = "GET";
6258 request.url = GURL("https://www.google.com/");
6259 // when the no authentication data flag is set.
6260 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6261
6262 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076263 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206264 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296265 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076266 session_deps_.net_log = log.bound().net_log();
6267 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356268
6269 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:546270 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6271 LOWEST));
[email protected]c10b20852013-05-15 21:29:206272 scoped_ptr<SpdyFrame> rst(
6273 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356274
6275 // After calling trans->RestartWithAuth(), this is the request we should
6276 // be issuing -- the final header line contains the credentials.
6277 const char* const kAuthCredentials[] = {
6278 "proxy-authorization", "Basic Zm9vOmJhcg==",
6279 };
[email protected]fba2dbde2013-05-24 16:09:016280 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:546281 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:356282 // fetch https://www.google.com/ via HTTP
6283 const char get[] = "GET / HTTP/1.1\r\n"
6284 "Host: www.google.com\r\n"
6285 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196286 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026287 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356288
6289 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206290 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216291 CreateMockWrite(*rst, 4, ASYNC),
6292 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206293 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356294 };
6295
6296 // The proxy responds to the connect with a 407, using a persistent
6297 // connection.
6298 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:026299 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
6300 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:356301 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6302 };
6303
[email protected]ff98d7f02012-03-22 21:44:196304 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:236305 spdy_util_.ConstructSpdyControlFrame(NULL,
6306 0,
6307 false,
6308 1,
6309 LOWEST,
6310 SYN_REPLY,
6311 CONTROL_FLAG_NONE,
6312 kAuthChallenge,
6313 arraysize(kAuthChallenge),
6314 0));
[email protected]0c5fb722012-02-28 11:50:356315
[email protected]23e482282013-06-14 16:08:026316 scoped_ptr<SpdyFrame> conn_resp(
6317 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356318 const char resp[] = "HTTP/1.1 200 OK\r\n"
6319 "Content-Length: 5\r\n\r\n";
6320
[email protected]ff98d7f02012-03-22 21:44:196321 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026322 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196323 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026324 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356325 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206326 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6327 CreateMockRead(*conn_resp, 6, ASYNC),
6328 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6329 CreateMockRead(*wrapped_body, 10, ASYNC),
6330 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356331 };
6332
[email protected]dd54bd82012-07-19 23:44:576333 OrderedSocketData spdy_data(
6334 spdy_reads, arraysize(spdy_reads),
6335 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076336 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356337 // Negotiate SPDY to the proxy
6338 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026339 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076340 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356341 // Vanilla SSL to the server
6342 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076343 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356344
6345 TestCompletionCallback callback1;
6346
[email protected]262eec82013-03-19 21:01:366347 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356349
6350 int rv = trans->Start(&request, callback1.callback(), log.bound());
6351 EXPECT_EQ(ERR_IO_PENDING, rv);
6352
6353 rv = callback1.WaitForResult();
6354 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576355 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356356 log.GetEntries(&entries);
6357 size_t pos = ExpectLogContainsSomewhere(
6358 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6359 NetLog::PHASE_NONE);
6360 ExpectLogContainsSomewhere(
6361 entries, pos,
6362 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6363 NetLog::PHASE_NONE);
6364
6365 const HttpResponseInfo* response = trans->GetResponseInfo();
6366 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506367 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356368 EXPECT_EQ(407, response->headers->response_code());
6369 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6370 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6371 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6372
6373 TestCompletionCallback callback2;
6374
6375 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6376 callback2.callback());
6377 EXPECT_EQ(ERR_IO_PENDING, rv);
6378
6379 rv = callback2.WaitForResult();
6380 EXPECT_EQ(OK, rv);
6381
6382 response = trans->GetResponseInfo();
6383 ASSERT_TRUE(response != NULL);
6384
6385 EXPECT_TRUE(response->headers->IsKeepAlive());
6386 EXPECT_EQ(200, response->headers->response_code());
6387 EXPECT_EQ(5, response->headers->GetContentLength());
6388 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6389
6390 // The password prompt info should not be set.
6391 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6392
[email protected]029c83b62013-01-24 05:28:206393 LoadTimingInfo load_timing_info;
6394 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6395 TestLoadTimingNotReusedWithPac(load_timing_info,
6396 CONNECT_TIMING_HAS_SSL_TIMES);
6397
[email protected]0c5fb722012-02-28 11:50:356398 trans.reset();
6399 session->CloseAllConnections();
6400}
6401
[email protected]7c6f7ba2012-04-03 04:09:296402// Test that an explicitly trusted SPDY proxy can push a resource from an
6403// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026404TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296405 HttpRequestInfo request;
6406 HttpRequestInfo push_request;
6407
[email protected]7c6f7ba2012-04-03 04:09:296408 request.method = "GET";
6409 request.url = GURL("http://www.google.com/");
6410 push_request.method = "GET";
6411 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6412
[email protected]7c6f7ba2012-04-03 04:09:296413 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076414 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206415 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296416 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076417 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506418
6419 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076420 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506421
[email protected]bb88e1d32013-05-03 23:11:076422 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296423
[email protected]cdf8f7e72013-05-23 10:56:466424 scoped_ptr<SpdyFrame> stream1_syn(
6425 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296426
6427 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466428 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296429 };
6430
6431 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026432 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296433
6434 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026435 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296436
6437 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026438 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296439 0,
6440 2,
6441 1,
6442 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436443 const char kPushedData[] = "pushed";
6444 scoped_ptr<SpdyFrame> stream2_body(
6445 spdy_util_.ConstructSpdyBodyFrame(
6446 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296447
6448 MockRead spdy_reads[] = {
6449 CreateMockRead(*stream1_reply, 2, ASYNC),
6450 CreateMockRead(*stream2_syn, 3, ASYNC),
6451 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436452 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296453 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6454 };
6455
[email protected]dd54bd82012-07-19 23:44:576456 OrderedSocketData spdy_data(
6457 spdy_reads, arraysize(spdy_reads),
6458 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076459 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296460 // Negotiate SPDY to the proxy
6461 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026462 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076463 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296464
[email protected]262eec82013-03-19 21:01:366465 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506466 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296467 TestCompletionCallback callback;
6468 int rv = trans->Start(&request, callback.callback(), log.bound());
6469 EXPECT_EQ(ERR_IO_PENDING, rv);
6470
6471 rv = callback.WaitForResult();
6472 EXPECT_EQ(OK, rv);
6473 const HttpResponseInfo* response = trans->GetResponseInfo();
6474
[email protected]262eec82013-03-19 21:01:366475 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506476 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6477 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296478 EXPECT_EQ(ERR_IO_PENDING, rv);
6479
6480 rv = callback.WaitForResult();
6481 EXPECT_EQ(OK, rv);
6482 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6483
6484 ASSERT_TRUE(response != NULL);
6485 EXPECT_TRUE(response->headers->IsKeepAlive());
6486
6487 EXPECT_EQ(200, response->headers->response_code());
6488 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6489
6490 std::string response_data;
6491 rv = ReadTransaction(trans.get(), &response_data);
6492 EXPECT_EQ(OK, rv);
6493 EXPECT_EQ("hello!", response_data);
6494
[email protected]029c83b62013-01-24 05:28:206495 LoadTimingInfo load_timing_info;
6496 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6497 TestLoadTimingNotReusedWithPac(load_timing_info,
6498 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6499
[email protected]7c6f7ba2012-04-03 04:09:296500 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506501 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296502 EXPECT_EQ(200, push_response->headers->response_code());
6503
6504 rv = ReadTransaction(push_trans.get(), &response_data);
6505 EXPECT_EQ(OK, rv);
6506 EXPECT_EQ("pushed", response_data);
6507
[email protected]029c83b62013-01-24 05:28:206508 LoadTimingInfo push_load_timing_info;
6509 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6510 TestLoadTimingReusedWithPac(push_load_timing_info);
6511 // The transactions should share a socket ID, despite being for different
6512 // origins.
6513 EXPECT_EQ(load_timing_info.socket_log_id,
6514 push_load_timing_info.socket_log_id);
6515
[email protected]7c6f7ba2012-04-03 04:09:296516 trans.reset();
6517 push_trans.reset();
6518 session->CloseAllConnections();
6519}
6520
[email protected]8c843192012-04-05 07:15:006521// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026522TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006523 HttpRequestInfo request;
6524
6525 request.method = "GET";
6526 request.url = GURL("http://www.google.com/");
6527
[email protected]8c843192012-04-05 07:15:006528 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076529 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006530 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296531 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076532 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506533
6534 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076535 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506536
[email protected]bb88e1d32013-05-03 23:11:076537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006538
[email protected]cdf8f7e72013-05-23 10:56:466539 scoped_ptr<SpdyFrame> stream1_syn(
6540 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006541
6542 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206543 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006544
6545 MockWrite spdy_writes[] = {
6546 CreateMockWrite(*stream1_syn, 1, ASYNC),
6547 CreateMockWrite(*push_rst, 4),
6548 };
6549
6550 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026551 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006552
6553 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026554 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006555
6556 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026557 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006558 0,
6559 2,
6560 1,
6561 "https://www.another-origin.com/foo.dat"));
6562
6563 MockRead spdy_reads[] = {
6564 CreateMockRead(*stream1_reply, 2, ASYNC),
6565 CreateMockRead(*stream2_syn, 3, ASYNC),
6566 CreateMockRead(*stream1_body, 5, ASYNC),
6567 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6568 };
6569
[email protected]dd54bd82012-07-19 23:44:576570 OrderedSocketData spdy_data(
6571 spdy_reads, arraysize(spdy_reads),
6572 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076573 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006574 // Negotiate SPDY to the proxy
6575 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026576 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076577 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006578
[email protected]262eec82013-03-19 21:01:366579 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506580 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006581 TestCompletionCallback callback;
6582 int rv = trans->Start(&request, callback.callback(), log.bound());
6583 EXPECT_EQ(ERR_IO_PENDING, rv);
6584
6585 rv = callback.WaitForResult();
6586 EXPECT_EQ(OK, rv);
6587 const HttpResponseInfo* response = trans->GetResponseInfo();
6588
6589 ASSERT_TRUE(response != NULL);
6590 EXPECT_TRUE(response->headers->IsKeepAlive());
6591
6592 EXPECT_EQ(200, response->headers->response_code());
6593 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6594
6595 std::string response_data;
6596 rv = ReadTransaction(trans.get(), &response_data);
6597 EXPECT_EQ(OK, rv);
6598 EXPECT_EQ("hello!", response_data);
6599
6600 trans.reset();
6601 session->CloseAllConnections();
6602}
6603
[email protected]2df19bb2010-08-25 20:13:466604// Test HTTPS connections to a site with a bad certificate, going through an
6605// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026606TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076607 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116608 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466609
6610 HttpRequestInfo request;
6611 request.method = "GET";
6612 request.url = GURL("https://www.google.com/");
6613 request.load_flags = 0;
6614
6615 // Attempt to fetch the URL from a server with a bad cert
6616 MockWrite bad_cert_writes[] = {
6617 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6618 "Host: www.google.com\r\n"
6619 "Proxy-Connection: keep-alive\r\n\r\n"),
6620 };
6621
6622 MockRead bad_cert_reads[] = {
6623 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066624 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466625 };
6626
6627 // Attempt to fetch the URL with a good cert
6628 MockWrite good_data_writes[] = {
6629 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6630 "Host: www.google.com\r\n"
6631 "Proxy-Connection: keep-alive\r\n\r\n"),
6632 MockWrite("GET / HTTP/1.1\r\n"
6633 "Host: www.google.com\r\n"
6634 "Connection: keep-alive\r\n\r\n"),
6635 };
6636
6637 MockRead good_cert_reads[] = {
6638 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6639 MockRead("HTTP/1.0 200 OK\r\n"),
6640 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6641 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066642 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466643 };
6644
6645 StaticSocketDataProvider ssl_bad_certificate(
6646 bad_cert_reads, arraysize(bad_cert_reads),
6647 bad_cert_writes, arraysize(bad_cert_writes));
6648 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6649 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066650 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6651 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466652
6653 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076654 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6655 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6656 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466657
6658 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6660 session_deps_.socket_factory->AddSocketDataProvider(&data);
6661 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466662
[email protected]49639fa2011-12-20 23:22:416663 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466664
[email protected]3fe8d2f82013-10-17 08:56:076665 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466666 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076667 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466668
[email protected]49639fa2011-12-20 23:22:416669 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466670 EXPECT_EQ(ERR_IO_PENDING, rv);
6671
6672 rv = callback.WaitForResult();
6673 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6674
[email protected]49639fa2011-12-20 23:22:416675 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466676 EXPECT_EQ(ERR_IO_PENDING, rv);
6677
6678 rv = callback.WaitForResult();
6679 EXPECT_EQ(OK, rv);
6680
6681 const HttpResponseInfo* response = trans->GetResponseInfo();
6682
[email protected]fe2255a2011-09-20 19:37:506683 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466684 EXPECT_EQ(100, response->headers->GetContentLength());
6685}
6686
[email protected]23e482282013-06-14 16:08:026687TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426688 HttpRequestInfo request;
6689 request.method = "GET";
6690 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436691 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6692 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426693
[email protected]3fe8d2f82013-10-17 08:56:076694 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276695 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076696 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276697
[email protected]1c773ea12009-04-28 19:58:426698 MockWrite data_writes[] = {
6699 MockWrite("GET / HTTP/1.1\r\n"
6700 "Host: www.google.com\r\n"
6701 "Connection: keep-alive\r\n"
6702 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6703 };
6704
6705 // Lastly, the server responds with the actual content.
6706 MockRead data_reads[] = {
6707 MockRead("HTTP/1.0 200 OK\r\n"),
6708 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6709 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066710 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426711 };
6712
[email protected]31a2bfe2010-02-09 08:03:396713 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6714 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076715 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426716
[email protected]49639fa2011-12-20 23:22:416717 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426718
[email protected]49639fa2011-12-20 23:22:416719 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426720 EXPECT_EQ(ERR_IO_PENDING, rv);
6721
6722 rv = callback.WaitForResult();
6723 EXPECT_EQ(OK, rv);
6724}
6725
[email protected]23e482282013-06-14 16:08:026726TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296727 HttpRequestInfo request;
6728 request.method = "GET";
6729 request.url = GURL("https://www.google.com/");
6730 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6731 "Chromium Ultra Awesome X Edition");
6732
[email protected]bb88e1d32013-05-03 23:11:076733 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076734 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276735 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076736 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276737
[email protected]da81f132010-08-18 23:39:296738 MockWrite data_writes[] = {
6739 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6740 "Host: www.google.com\r\n"
6741 "Proxy-Connection: keep-alive\r\n"
6742 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6743 };
6744 MockRead data_reads[] = {
6745 // Return an error, so the transaction stops here (this test isn't
6746 // interested in the rest).
6747 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6748 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6749 MockRead("Proxy-Connection: close\r\n\r\n"),
6750 };
6751
6752 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6753 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076754 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296755
[email protected]49639fa2011-12-20 23:22:416756 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296757
[email protected]49639fa2011-12-20 23:22:416758 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296759 EXPECT_EQ(ERR_IO_PENDING, rv);
6760
6761 rv = callback.WaitForResult();
6762 EXPECT_EQ(OK, rv);
6763}
6764
[email protected]23e482282013-06-14 16:08:026765TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426766 HttpRequestInfo request;
6767 request.method = "GET";
6768 request.url = GURL("http://www.google.com/");
6769 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166770 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6771 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426772
[email protected]3fe8d2f82013-10-17 08:56:076773 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276774 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076775 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276776
[email protected]1c773ea12009-04-28 19:58:426777 MockWrite data_writes[] = {
6778 MockWrite("GET / HTTP/1.1\r\n"
6779 "Host: www.google.com\r\n"
6780 "Connection: keep-alive\r\n"
6781 "Referer: http://the.previous.site.com/\r\n\r\n"),
6782 };
6783
6784 // Lastly, the server responds with the actual content.
6785 MockRead data_reads[] = {
6786 MockRead("HTTP/1.0 200 OK\r\n"),
6787 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6788 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066789 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426790 };
6791
[email protected]31a2bfe2010-02-09 08:03:396792 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6793 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076794 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426795
[email protected]49639fa2011-12-20 23:22:416796 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426797
[email protected]49639fa2011-12-20 23:22:416798 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426799 EXPECT_EQ(ERR_IO_PENDING, rv);
6800
6801 rv = callback.WaitForResult();
6802 EXPECT_EQ(OK, rv);
6803}
6804
[email protected]23e482282013-06-14 16:08:026805TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426806 HttpRequestInfo request;
6807 request.method = "POST";
6808 request.url = GURL("http://www.google.com/");
6809
[email protected]3fe8d2f82013-10-17 08:56:076810 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276811 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076812 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276813
[email protected]1c773ea12009-04-28 19:58:426814 MockWrite data_writes[] = {
6815 MockWrite("POST / HTTP/1.1\r\n"
6816 "Host: www.google.com\r\n"
6817 "Connection: keep-alive\r\n"
6818 "Content-Length: 0\r\n\r\n"),
6819 };
6820
6821 // Lastly, the server responds with the actual content.
6822 MockRead data_reads[] = {
6823 MockRead("HTTP/1.0 200 OK\r\n"),
6824 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6825 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066826 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426827 };
6828
[email protected]31a2bfe2010-02-09 08:03:396829 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6830 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076831 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426832
[email protected]49639fa2011-12-20 23:22:416833 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426834
[email protected]49639fa2011-12-20 23:22:416835 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426836 EXPECT_EQ(ERR_IO_PENDING, rv);
6837
6838 rv = callback.WaitForResult();
6839 EXPECT_EQ(OK, rv);
6840}
6841
[email protected]23e482282013-06-14 16:08:026842TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426843 HttpRequestInfo request;
6844 request.method = "PUT";
6845 request.url = GURL("http://www.google.com/");
6846
[email protected]3fe8d2f82013-10-17 08:56:076847 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276848 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276850
[email protected]1c773ea12009-04-28 19:58:426851 MockWrite data_writes[] = {
6852 MockWrite("PUT / HTTP/1.1\r\n"
6853 "Host: www.google.com\r\n"
6854 "Connection: keep-alive\r\n"
6855 "Content-Length: 0\r\n\r\n"),
6856 };
6857
6858 // Lastly, the server responds with the actual content.
6859 MockRead data_reads[] = {
6860 MockRead("HTTP/1.0 200 OK\r\n"),
6861 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6862 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066863 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426864 };
6865
[email protected]31a2bfe2010-02-09 08:03:396866 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6867 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076868 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426869
[email protected]49639fa2011-12-20 23:22:416870 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426871
[email protected]49639fa2011-12-20 23:22:416872 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426873 EXPECT_EQ(ERR_IO_PENDING, rv);
6874
6875 rv = callback.WaitForResult();
6876 EXPECT_EQ(OK, rv);
6877}
6878
[email protected]23e482282013-06-14 16:08:026879TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426880 HttpRequestInfo request;
6881 request.method = "HEAD";
6882 request.url = GURL("http://www.google.com/");
6883
[email protected]3fe8d2f82013-10-17 08:56:076884 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276885 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076886 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276887
[email protected]1c773ea12009-04-28 19:58:426888 MockWrite data_writes[] = {
6889 MockWrite("HEAD / HTTP/1.1\r\n"
6890 "Host: www.google.com\r\n"
6891 "Connection: keep-alive\r\n"
6892 "Content-Length: 0\r\n\r\n"),
6893 };
6894
6895 // Lastly, the server responds with the actual content.
6896 MockRead data_reads[] = {
6897 MockRead("HTTP/1.0 200 OK\r\n"),
6898 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6899 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066900 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426901 };
6902
[email protected]31a2bfe2010-02-09 08:03:396903 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6904 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076905 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426906
[email protected]49639fa2011-12-20 23:22:416907 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426908
[email protected]49639fa2011-12-20 23:22:416909 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426910 EXPECT_EQ(ERR_IO_PENDING, rv);
6911
6912 rv = callback.WaitForResult();
6913 EXPECT_EQ(OK, rv);
6914}
6915
[email protected]23e482282013-06-14 16:08:026916TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426917 HttpRequestInfo request;
6918 request.method = "GET";
6919 request.url = GURL("http://www.google.com/");
6920 request.load_flags = LOAD_BYPASS_CACHE;
6921
[email protected]3fe8d2f82013-10-17 08:56:076922 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276923 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076924 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276925
[email protected]1c773ea12009-04-28 19:58:426926 MockWrite data_writes[] = {
6927 MockWrite("GET / HTTP/1.1\r\n"
6928 "Host: www.google.com\r\n"
6929 "Connection: keep-alive\r\n"
6930 "Pragma: no-cache\r\n"
6931 "Cache-Control: no-cache\r\n\r\n"),
6932 };
6933
6934 // Lastly, the server responds with the actual content.
6935 MockRead data_reads[] = {
6936 MockRead("HTTP/1.0 200 OK\r\n"),
6937 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6938 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066939 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426940 };
6941
[email protected]31a2bfe2010-02-09 08:03:396942 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6943 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076944 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426945
[email protected]49639fa2011-12-20 23:22:416946 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426947
[email protected]49639fa2011-12-20 23:22:416948 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426949 EXPECT_EQ(ERR_IO_PENDING, rv);
6950
6951 rv = callback.WaitForResult();
6952 EXPECT_EQ(OK, rv);
6953}
6954
[email protected]23e482282013-06-14 16:08:026955TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426956 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426957 HttpRequestInfo request;
6958 request.method = "GET";
6959 request.url = GURL("http://www.google.com/");
6960 request.load_flags = LOAD_VALIDATE_CACHE;
6961
[email protected]3fe8d2f82013-10-17 08:56:076962 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276963 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076964 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276965
[email protected]1c773ea12009-04-28 19:58:426966 MockWrite data_writes[] = {
6967 MockWrite("GET / HTTP/1.1\r\n"
6968 "Host: www.google.com\r\n"
6969 "Connection: keep-alive\r\n"
6970 "Cache-Control: max-age=0\r\n\r\n"),
6971 };
6972
6973 // Lastly, the server responds with the actual content.
6974 MockRead data_reads[] = {
6975 MockRead("HTTP/1.0 200 OK\r\n"),
6976 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6977 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066978 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426979 };
6980
[email protected]31a2bfe2010-02-09 08:03:396981 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6982 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076983 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426984
[email protected]49639fa2011-12-20 23:22:416985 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426986
[email protected]49639fa2011-12-20 23:22:416987 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426988 EXPECT_EQ(ERR_IO_PENDING, rv);
6989
6990 rv = callback.WaitForResult();
6991 EXPECT_EQ(OK, rv);
6992}
6993
[email protected]23e482282013-06-14 16:08:026994TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426995 HttpRequestInfo request;
6996 request.method = "GET";
6997 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436998 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426999
[email protected]3fe8d2f82013-10-17 08:56:077000 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277001 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077002 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277003
[email protected]1c773ea12009-04-28 19:58:427004 MockWrite data_writes[] = {
7005 MockWrite("GET / HTTP/1.1\r\n"
7006 "Host: www.google.com\r\n"
7007 "Connection: keep-alive\r\n"
7008 "FooHeader: Bar\r\n\r\n"),
7009 };
7010
7011 // Lastly, the server responds with the actual content.
7012 MockRead data_reads[] = {
7013 MockRead("HTTP/1.0 200 OK\r\n"),
7014 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7015 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067016 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427017 };
7018
[email protected]31a2bfe2010-02-09 08:03:397019 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7020 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077021 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427022
[email protected]49639fa2011-12-20 23:22:417023 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427024
[email protected]49639fa2011-12-20 23:22:417025 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427026 EXPECT_EQ(ERR_IO_PENDING, rv);
7027
7028 rv = callback.WaitForResult();
7029 EXPECT_EQ(OK, rv);
7030}
7031
[email protected]23e482282013-06-14 16:08:027032TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477033 HttpRequestInfo request;
7034 request.method = "GET";
7035 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437036 request.extra_headers.SetHeader("referer", "www.foo.com");
7037 request.extra_headers.SetHeader("hEllo", "Kitty");
7038 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477039
[email protected]3fe8d2f82013-10-17 08:56:077040 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277041 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277043
[email protected]270c6412010-03-29 22:02:477044 MockWrite data_writes[] = {
7045 MockWrite("GET / HTTP/1.1\r\n"
7046 "Host: www.google.com\r\n"
7047 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:167048 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:477049 "hEllo: Kitty\r\n"
7050 "FoO: bar\r\n\r\n"),
7051 };
7052
7053 // Lastly, the server responds with the actual content.
7054 MockRead data_reads[] = {
7055 MockRead("HTTP/1.0 200 OK\r\n"),
7056 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7057 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067058 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477059 };
7060
7061 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7062 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077063 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477064
[email protected]49639fa2011-12-20 23:22:417065 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477066
[email protected]49639fa2011-12-20 23:22:417067 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477068 EXPECT_EQ(ERR_IO_PENDING, rv);
7069
7070 rv = callback.WaitForResult();
7071 EXPECT_EQ(OK, rv);
7072}
7073
[email protected]23e482282013-06-14 16:08:027074TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277075 HttpRequestInfo request;
7076 request.method = "GET";
7077 request.url = GURL("http://www.google.com/");
7078 request.load_flags = 0;
7079
[email protected]bb88e1d32013-05-03 23:11:077080 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207081 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7082 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077083 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027084
[email protected]3fe8d2f82013-10-17 08:56:077085 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027086 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027088
[email protected]3cd17242009-06-23 02:59:027089 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7090 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7091
7092 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067093 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027094 MockWrite("GET / HTTP/1.1\r\n"
7095 "Host: www.google.com\r\n"
7096 "Connection: keep-alive\r\n\r\n")
7097 };
7098
7099 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067100 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027101 MockRead("HTTP/1.0 200 OK\r\n"),
7102 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7103 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067104 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027105 };
7106
[email protected]31a2bfe2010-02-09 08:03:397107 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7108 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077109 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027110
[email protected]49639fa2011-12-20 23:22:417111 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027112
[email protected]49639fa2011-12-20 23:22:417113 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027114 EXPECT_EQ(ERR_IO_PENDING, rv);
7115
7116 rv = callback.WaitForResult();
7117 EXPECT_EQ(OK, rv);
7118
7119 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507120 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027121
[email protected]029c83b62013-01-24 05:28:207122 LoadTimingInfo load_timing_info;
7123 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7124 TestLoadTimingNotReusedWithPac(load_timing_info,
7125 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7126
[email protected]3cd17242009-06-23 02:59:027127 std::string response_text;
7128 rv = ReadTransaction(trans.get(), &response_text);
7129 EXPECT_EQ(OK, rv);
7130 EXPECT_EQ("Payload", response_text);
7131}
7132
[email protected]23e482282013-06-14 16:08:027133TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277134 HttpRequestInfo request;
7135 request.method = "GET";
7136 request.url = GURL("https://www.google.com/");
7137 request.load_flags = 0;
7138
[email protected]bb88e1d32013-05-03 23:11:077139 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207140 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7141 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077142 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027143
[email protected]3fe8d2f82013-10-17 08:56:077144 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027145 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077146 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027147
[email protected]3cd17242009-06-23 02:59:027148 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7149 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7150
7151 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067152 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:357153 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027154 MockWrite("GET / HTTP/1.1\r\n"
7155 "Host: www.google.com\r\n"
7156 "Connection: keep-alive\r\n\r\n")
7157 };
7158
7159 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017160 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7161 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357162 MockRead("HTTP/1.0 200 OK\r\n"),
7163 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7164 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067165 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357166 };
7167
[email protected]31a2bfe2010-02-09 08:03:397168 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7169 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077170 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357171
[email protected]8ddf8322012-02-23 18:08:067172 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077173 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357174
[email protected]49639fa2011-12-20 23:22:417175 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357176
[email protected]49639fa2011-12-20 23:22:417177 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357178 EXPECT_EQ(ERR_IO_PENDING, rv);
7179
7180 rv = callback.WaitForResult();
7181 EXPECT_EQ(OK, rv);
7182
[email protected]029c83b62013-01-24 05:28:207183 LoadTimingInfo load_timing_info;
7184 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7185 TestLoadTimingNotReusedWithPac(load_timing_info,
7186 CONNECT_TIMING_HAS_SSL_TIMES);
7187
[email protected]e0c27be2009-07-15 13:09:357188 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507189 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357190
7191 std::string response_text;
7192 rv = ReadTransaction(trans.get(), &response_text);
7193 EXPECT_EQ(OK, rv);
7194 EXPECT_EQ("Payload", response_text);
7195}
7196
[email protected]23e482282013-06-14 16:08:027197TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207198 HttpRequestInfo request;
7199 request.method = "GET";
7200 request.url = GURL("http://www.google.com/");
7201 request.load_flags = 0;
7202
[email protected]bb88e1d32013-05-03 23:11:077203 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207204 ProxyService::CreateFixed("socks4://myproxy:1080"));
7205 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077206 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207207
[email protected]3fe8d2f82013-10-17 08:56:077208 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207209 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077210 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]029c83b62013-01-24 05:28:207211
7212 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7213 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7214
7215 MockWrite data_writes[] = {
7216 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7217 MockWrite("GET / HTTP/1.1\r\n"
7218 "Host: www.google.com\r\n"
7219 "Connection: keep-alive\r\n\r\n")
7220 };
7221
7222 MockRead data_reads[] = {
7223 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7224 MockRead("HTTP/1.0 200 OK\r\n"),
7225 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7226 MockRead("Payload"),
7227 MockRead(SYNCHRONOUS, OK)
7228 };
7229
7230 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7231 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077232 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207233
7234 TestCompletionCallback callback;
7235
7236 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7237 EXPECT_EQ(ERR_IO_PENDING, rv);
7238
7239 rv = callback.WaitForResult();
7240 EXPECT_EQ(OK, rv);
7241
7242 const HttpResponseInfo* response = trans->GetResponseInfo();
7243 ASSERT_TRUE(response != NULL);
7244
7245 LoadTimingInfo load_timing_info;
7246 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7247 TestLoadTimingNotReused(load_timing_info,
7248 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7249
7250 std::string response_text;
7251 rv = ReadTransaction(trans.get(), &response_text);
7252 EXPECT_EQ(OK, rv);
7253 EXPECT_EQ("Payload", response_text);
7254}
7255
[email protected]23e482282013-06-14 16:08:027256TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277257 HttpRequestInfo request;
7258 request.method = "GET";
7259 request.url = GURL("http://www.google.com/");
7260 request.load_flags = 0;
7261
[email protected]bb88e1d32013-05-03 23:11:077262 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207263 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7264 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077265 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357266
[email protected]3fe8d2f82013-10-17 08:56:077267 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357268 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357270
[email protected]e0c27be2009-07-15 13:09:357271 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7272 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377273 const char kSOCKS5OkRequest[] = {
7274 0x05, // Version
7275 0x01, // Command (CONNECT)
7276 0x00, // Reserved.
7277 0x03, // Address type (DOMAINNAME).
7278 0x0E, // Length of domain (14)
7279 // Domain string:
7280 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7281 0x00, 0x50, // 16-bit port (80)
7282 };
[email protected]e0c27be2009-07-15 13:09:357283 const char kSOCKS5OkResponse[] =
7284 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7285
7286 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067287 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7288 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357289 MockWrite("GET / HTTP/1.1\r\n"
7290 "Host: www.google.com\r\n"
7291 "Connection: keep-alive\r\n\r\n")
7292 };
7293
7294 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017295 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7296 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357297 MockRead("HTTP/1.0 200 OK\r\n"),
7298 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7299 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067300 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357301 };
7302
[email protected]31a2bfe2010-02-09 08:03:397303 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7304 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077305 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357306
[email protected]49639fa2011-12-20 23:22:417307 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357308
[email protected]49639fa2011-12-20 23:22:417309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357310 EXPECT_EQ(ERR_IO_PENDING, rv);
7311
7312 rv = callback.WaitForResult();
7313 EXPECT_EQ(OK, rv);
7314
7315 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507316 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357317
[email protected]029c83b62013-01-24 05:28:207318 LoadTimingInfo load_timing_info;
7319 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7320 TestLoadTimingNotReusedWithPac(load_timing_info,
7321 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7322
[email protected]e0c27be2009-07-15 13:09:357323 std::string response_text;
7324 rv = ReadTransaction(trans.get(), &response_text);
7325 EXPECT_EQ(OK, rv);
7326 EXPECT_EQ("Payload", response_text);
7327}
7328
[email protected]23e482282013-06-14 16:08:027329TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277330 HttpRequestInfo request;
7331 request.method = "GET";
7332 request.url = GURL("https://www.google.com/");
7333 request.load_flags = 0;
7334
[email protected]bb88e1d32013-05-03 23:11:077335 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207336 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7337 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077338 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357339
[email protected]3fe8d2f82013-10-17 08:56:077340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357341 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077342 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357343
[email protected]e0c27be2009-07-15 13:09:357344 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7345 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377346 const unsigned char kSOCKS5OkRequest[] = {
7347 0x05, // Version
7348 0x01, // Command (CONNECT)
7349 0x00, // Reserved.
7350 0x03, // Address type (DOMAINNAME).
7351 0x0E, // Length of domain (14)
7352 // Domain string:
7353 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7354 0x01, 0xBB, // 16-bit port (443)
7355 };
7356
[email protected]e0c27be2009-07-15 13:09:357357 const char kSOCKS5OkResponse[] =
7358 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7359
7360 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067361 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7362 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357363 arraysize(kSOCKS5OkRequest)),
7364 MockWrite("GET / HTTP/1.1\r\n"
7365 "Host: www.google.com\r\n"
7366 "Connection: keep-alive\r\n\r\n")
7367 };
7368
7369 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017370 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7371 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027372 MockRead("HTTP/1.0 200 OK\r\n"),
7373 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7374 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067375 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027376 };
7377
[email protected]31a2bfe2010-02-09 08:03:397378 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7379 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077380 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027381
[email protected]8ddf8322012-02-23 18:08:067382 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077383 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027384
[email protected]49639fa2011-12-20 23:22:417385 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027386
[email protected]49639fa2011-12-20 23:22:417387 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027388 EXPECT_EQ(ERR_IO_PENDING, rv);
7389
7390 rv = callback.WaitForResult();
7391 EXPECT_EQ(OK, rv);
7392
7393 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507394 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027395
[email protected]029c83b62013-01-24 05:28:207396 LoadTimingInfo load_timing_info;
7397 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7398 TestLoadTimingNotReusedWithPac(load_timing_info,
7399 CONNECT_TIMING_HAS_SSL_TIMES);
7400
[email protected]3cd17242009-06-23 02:59:027401 std::string response_text;
7402 rv = ReadTransaction(trans.get(), &response_text);
7403 EXPECT_EQ(OK, rv);
7404 EXPECT_EQ("Payload", response_text);
7405}
7406
[email protected]448d4ca52012-03-04 04:12:237407namespace {
7408
[email protected]04e5be32009-06-26 20:00:317409// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067410
7411struct GroupNameTest {
7412 std::string proxy_server;
7413 std::string url;
7414 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187415 bool ssl;
[email protected]2d731a32010-04-29 01:04:067416};
7417
7418scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437419 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077420 SpdySessionDependencies* session_deps_) {
7421 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067422
[email protected]30d4c022013-07-18 22:58:167423 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537424 session->http_server_properties();
7425 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067426 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437427 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067428
7429 return session;
7430}
7431
7432int GroupNameTransactionHelper(
7433 const std::string& url,
7434 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067435 HttpRequestInfo request;
7436 request.method = "GET";
7437 request.url = GURL(url);
7438 request.load_flags = 0;
7439
[email protected]262eec82013-03-19 21:01:367440 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507441 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277442
[email protected]49639fa2011-12-20 23:22:417443 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067444
7445 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417446 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067447}
7448
[email protected]448d4ca52012-03-04 04:12:237449} // namespace
7450
[email protected]23e482282013-06-14 16:08:027451TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067452 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317453 {
[email protected]2d731a32010-04-29 01:04:067454 "", // unused
[email protected]04e5be32009-06-26 20:00:317455 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547456 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187457 false,
[email protected]2ff8b312010-04-26 22:20:547458 },
7459 {
[email protected]2d731a32010-04-29 01:04:067460 "", // unused
[email protected]2ff8b312010-04-26 22:20:547461 "http://[2001:1418:13:1::25]/direct",
7462 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187463 false,
[email protected]04e5be32009-06-26 20:00:317464 },
[email protected]04e5be32009-06-26 20:00:317465
7466 // SSL Tests
7467 {
[email protected]2d731a32010-04-29 01:04:067468 "", // unused
[email protected]04e5be32009-06-26 20:00:317469 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027470 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187471 true,
[email protected]04e5be32009-06-26 20:00:317472 },
7473 {
[email protected]2d731a32010-04-29 01:04:067474 "", // unused
7475 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027476 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187477 true,
[email protected]04e5be32009-06-26 20:00:317478 },
7479 {
[email protected]2d731a32010-04-29 01:04:067480 "", // unused
[email protected]2ff8b312010-04-26 22:20:547481 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027482 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187483 true,
[email protected]2ff8b312010-04-26 22:20:547484 },
[email protected]2d731a32010-04-29 01:04:067485 };
[email protected]2ff8b312010-04-26 22:20:547486
[email protected]8e6441ca2010-08-19 05:56:387487 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067488
7489 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077490 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027491 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067492 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437493 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067494
7495 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287496 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7497 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137498 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347499 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447500 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7501 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027502 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7503 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447504 peer.SetClientSocketPoolManager(
7505 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067506
7507 EXPECT_EQ(ERR_IO_PENDING,
7508 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187509 if (tests[i].ssl)
7510 EXPECT_EQ(tests[i].expected_group_name,
7511 ssl_conn_pool->last_group_name_received());
7512 else
7513 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287514 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067515 }
7516
[email protected]2d731a32010-04-29 01:04:067517}
7518
[email protected]23e482282013-06-14 16:08:027519TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067520 const GroupNameTest tests[] = {
7521 {
7522 "http_proxy",
7523 "http://www.google.com/http_proxy_normal",
7524 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187525 false,
[email protected]2d731a32010-04-29 01:04:067526 },
7527
7528 // SSL Tests
7529 {
7530 "http_proxy",
7531 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027532 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187533 true,
[email protected]2d731a32010-04-29 01:04:067534 },
[email protected]af3490e2010-10-16 21:02:297535
[email protected]9faeded92010-04-29 20:03:057536 {
7537 "http_proxy",
7538 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027539 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187540 true,
[email protected]9faeded92010-04-29 20:03:057541 },
[email protected]45499252013-01-23 17:12:567542
7543 {
7544 "http_proxy",
7545 "ftp://ftp.google.com/http_proxy_normal",
7546 "ftp/ftp.google.com:21",
7547 false,
7548 },
[email protected]2d731a32010-04-29 01:04:067549 };
7550
[email protected]8e6441ca2010-08-19 05:56:387551 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067552
7553 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077554 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027555 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067556 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437557 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067558
7559 HttpNetworkSessionPeer peer(session);
7560
[email protected]e60e47a2010-07-14 03:37:187561 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137562 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347563 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137564 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347565 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027566
[email protected]831e4a32013-11-14 02:14:447567 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7568 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027569 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7570 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447571 peer.SetClientSocketPoolManager(
7572 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067573
7574 EXPECT_EQ(ERR_IO_PENDING,
7575 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187576 if (tests[i].ssl)
7577 EXPECT_EQ(tests[i].expected_group_name,
7578 ssl_conn_pool->last_group_name_received());
7579 else
7580 EXPECT_EQ(tests[i].expected_group_name,
7581 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067582 }
[email protected]2d731a32010-04-29 01:04:067583}
7584
[email protected]23e482282013-06-14 16:08:027585TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067586 const GroupNameTest tests[] = {
7587 {
7588 "socks4://socks_proxy:1080",
7589 "http://www.google.com/socks4_direct",
7590 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187591 false,
[email protected]2d731a32010-04-29 01:04:067592 },
7593 {
7594 "socks5://socks_proxy:1080",
7595 "http://www.google.com/socks5_direct",
7596 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187597 false,
[email protected]2d731a32010-04-29 01:04:067598 },
7599
7600 // SSL Tests
7601 {
7602 "socks4://socks_proxy:1080",
7603 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027604 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187605 true,
[email protected]2d731a32010-04-29 01:04:067606 },
7607 {
7608 "socks5://socks_proxy:1080",
7609 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027610 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187611 true,
[email protected]2d731a32010-04-29 01:04:067612 },
[email protected]af3490e2010-10-16 21:02:297613
[email protected]9faeded92010-04-29 20:03:057614 {
7615 "socks4://socks_proxy:1080",
7616 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027617 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187618 true,
[email protected]9faeded92010-04-29 20:03:057619 },
[email protected]04e5be32009-06-26 20:00:317620 };
7621
[email protected]8e6441ca2010-08-19 05:56:387622 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547623
[email protected]04e5be32009-06-26 20:00:317624 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077625 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027626 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067627 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437628 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027629
[email protected]2d731a32010-04-29 01:04:067630 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317631
[email protected]e60e47a2010-07-14 03:37:187632 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137633 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347634 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137635 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347636 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027637
[email protected]831e4a32013-11-14 02:14:447638 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7639 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027640 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7641 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447642 peer.SetClientSocketPoolManager(
7643 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]04e5be32009-06-26 20:00:317644
[email protected]262eec82013-03-19 21:01:367645 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317647
[email protected]2d731a32010-04-29 01:04:067648 EXPECT_EQ(ERR_IO_PENDING,
7649 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187650 if (tests[i].ssl)
7651 EXPECT_EQ(tests[i].expected_group_name,
7652 ssl_conn_pool->last_group_name_received());
7653 else
7654 EXPECT_EQ(tests[i].expected_group_name,
7655 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317656 }
7657}
7658
[email protected]23e482282013-06-14 16:08:027659TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277660 HttpRequestInfo request;
7661 request.method = "GET";
7662 request.url = GURL("http://www.google.com/");
7663
[email protected]bb88e1d32013-05-03 23:11:077664 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007665 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327666
[email protected]69719062010-01-05 20:09:217667 // This simulates failure resolving all hostnames; that means we will fail
7668 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077669 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327670
[email protected]3fe8d2f82013-10-17 08:56:077671 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257672 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077673 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]9172a982009-06-06 00:30:257674
[email protected]49639fa2011-12-20 23:22:417675 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257676
[email protected]49639fa2011-12-20 23:22:417677 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257678 EXPECT_EQ(ERR_IO_PENDING, rv);
7679
[email protected]9172a982009-06-06 00:30:257680 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017681 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257682}
7683
[email protected]685af592010-05-11 19:31:247684// Base test to make sure that when the load flags for a request specify to
7685// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027686void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077687 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277688 // Issue a request, asking to bypass the cache(s).
7689 HttpRequestInfo request;
7690 request.method = "GET";
7691 request.load_flags = load_flags;
7692 request.url = GURL("http://www.google.com/");
7693
[email protected]a2c2fb92009-07-18 07:31:047694 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077695 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327696
[email protected]3fe8d2f82013-10-17 08:56:077697 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7698 scoped_ptr<HttpTransaction> trans(
7699 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3b9cca42009-06-16 01:08:287700
[email protected]6e78dfb2011-07-28 21:34:477701 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287702 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297703 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077704 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107705 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7706 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417707 &addrlist,
7708 callback.callback(),
7709 NULL,
7710 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477711 EXPECT_EQ(ERR_IO_PENDING, rv);
7712 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287713 EXPECT_EQ(OK, rv);
7714
7715 // Verify that it was added to host cache, by doing a subsequent async lookup
7716 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077717 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107718 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7719 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417720 &addrlist,
7721 callback.callback(),
7722 NULL,
7723 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327724 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287725
7726 // Inject a failure the next time that "www.google.com" is resolved. This way
7727 // we can tell if the next lookup hit the cache, or the "network".
7728 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077729 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287730
7731 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7732 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067733 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397734 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077735 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287736
[email protected]3b9cca42009-06-16 01:08:287737 // Run the request.
[email protected]49639fa2011-12-20 23:22:417738 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287739 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417740 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287741
7742 // If we bypassed the cache, we would have gotten a failure while resolving
7743 // "www.google.com".
7744 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7745}
7746
[email protected]685af592010-05-11 19:31:247747// There are multiple load flags that should trigger the host cache bypass.
7748// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027749TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247750 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7751}
7752
[email protected]23e482282013-06-14 16:08:027753TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247754 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7755}
7756
[email protected]23e482282013-06-14 16:08:027757TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247758 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7759}
7760
[email protected]0877e3d2009-10-17 22:29:577761// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027762TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577763 HttpRequestInfo request;
7764 request.method = "GET";
7765 request.url = GURL("http://www.foo.com/");
7766 request.load_flags = 0;
7767
7768 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067769 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577770 };
[email protected]31a2bfe2010-02-09 08:03:397771 StaticSocketDataProvider data(NULL, 0,
7772 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077773 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077774 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577775
[email protected]49639fa2011-12-20 23:22:417776 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577777
7778 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077779 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577780
[email protected]49639fa2011-12-20 23:22:417781 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577782 EXPECT_EQ(ERR_IO_PENDING, rv);
7783
7784 rv = callback.WaitForResult();
7785 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7786}
7787
7788// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027789TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577790 HttpRequestInfo request;
7791 request.method = "GET";
7792 request.url = GURL("http://www.foo.com/");
7793 request.load_flags = 0;
7794
7795 MockRead data_reads[] = {
7796 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067797 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577798 };
7799
[email protected]31a2bfe2010-02-09 08:03:397800 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077801 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077802 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577803
[email protected]49639fa2011-12-20 23:22:417804 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577805
7806 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077807 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577808
[email protected]49639fa2011-12-20 23:22:417809 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577810 EXPECT_EQ(ERR_IO_PENDING, rv);
7811
7812 rv = callback.WaitForResult();
7813 EXPECT_EQ(OK, rv);
7814
7815 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507816 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577817
[email protected]90499482013-06-01 00:39:507818 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577819 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7820
7821 std::string response_data;
7822 rv = ReadTransaction(trans.get(), &response_data);
7823 EXPECT_EQ(OK, rv);
7824 EXPECT_EQ("", response_data);
7825}
7826
7827// Make sure that a dropped connection while draining the body for auth
7828// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027829TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577830 HttpRequestInfo request;
7831 request.method = "GET";
7832 request.url = GURL("http://www.google.com/");
7833 request.load_flags = 0;
7834
7835 MockWrite data_writes1[] = {
7836 MockWrite("GET / HTTP/1.1\r\n"
7837 "Host: www.google.com\r\n"
7838 "Connection: keep-alive\r\n\r\n"),
7839 };
7840
7841 MockRead data_reads1[] = {
7842 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7843 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7844 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7845 MockRead("Content-Length: 14\r\n\r\n"),
7846 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067847 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577848 };
7849
[email protected]31a2bfe2010-02-09 08:03:397850 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7851 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077852 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577853
7854 // After calling trans->RestartWithAuth(), this is the request we should
7855 // be issuing -- the final header line contains the credentials.
7856 MockWrite data_writes2[] = {
7857 MockWrite("GET / HTTP/1.1\r\n"
7858 "Host: www.google.com\r\n"
7859 "Connection: keep-alive\r\n"
7860 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7861 };
7862
7863 // Lastly, the server responds with the actual content.
7864 MockRead data_reads2[] = {
7865 MockRead("HTTP/1.1 200 OK\r\n"),
7866 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7867 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067868 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577869 };
7870
[email protected]31a2bfe2010-02-09 08:03:397871 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7872 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077873 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077874 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577875
[email protected]49639fa2011-12-20 23:22:417876 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577877
[email protected]262eec82013-03-19 21:01:367878 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507879 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507880
[email protected]49639fa2011-12-20 23:22:417881 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577882 EXPECT_EQ(ERR_IO_PENDING, rv);
7883
7884 rv = callback1.WaitForResult();
7885 EXPECT_EQ(OK, rv);
7886
7887 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507888 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047889 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577890
[email protected]49639fa2011-12-20 23:22:417891 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577892
[email protected]49639fa2011-12-20 23:22:417893 rv = trans->RestartWithAuth(
7894 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577895 EXPECT_EQ(ERR_IO_PENDING, rv);
7896
7897 rv = callback2.WaitForResult();
7898 EXPECT_EQ(OK, rv);
7899
7900 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507901 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577902 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7903 EXPECT_EQ(100, response->headers->GetContentLength());
7904}
7905
7906// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027907TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077908 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577909
7910 HttpRequestInfo request;
7911 request.method = "GET";
7912 request.url = GURL("https://www.google.com/");
7913 request.load_flags = 0;
7914
7915 MockRead proxy_reads[] = {
7916 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067917 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577918 };
7919
[email protected]31a2bfe2010-02-09 08:03:397920 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067921 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577922
[email protected]bb88e1d32013-05-03 23:11:077923 session_deps_.socket_factory->AddSocketDataProvider(&data);
7924 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:577925
[email protected]49639fa2011-12-20 23:22:417926 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577927
[email protected]bb88e1d32013-05-03 23:11:077928 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577929
[email protected]3fe8d2f82013-10-17 08:56:077930 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577931 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077932 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577933
[email protected]49639fa2011-12-20 23:22:417934 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577935 EXPECT_EQ(ERR_IO_PENDING, rv);
7936
7937 rv = callback.WaitForResult();
7938 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7939}
7940
[email protected]23e482282013-06-14 16:08:027941TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467942 HttpRequestInfo request;
7943 request.method = "GET";
7944 request.url = GURL("http://www.google.com/");
7945 request.load_flags = 0;
7946
[email protected]3fe8d2f82013-10-17 08:56:077947 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277948 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077949 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277950
[email protected]e22e1362009-11-23 21:31:127951 MockRead data_reads[] = {
7952 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067953 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127954 };
[email protected]9492e4a2010-02-24 00:58:467955
7956 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077957 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467958
[email protected]49639fa2011-12-20 23:22:417959 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467960
[email protected]49639fa2011-12-20 23:22:417961 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467962 EXPECT_EQ(ERR_IO_PENDING, rv);
7963
7964 EXPECT_EQ(OK, callback.WaitForResult());
7965
7966 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507967 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467968
[email protected]90499482013-06-01 00:39:507969 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467970 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7971
7972 std::string response_data;
7973 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237974 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127975}
7976
[email protected]23e482282013-06-14 16:08:027977TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157978 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:527979 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:337980 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217981 UploadFileElementReader::ScopedOverridingContentLengthForTests
7982 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337983
[email protected]b2d26cfd2012-12-11 10:36:067984 ScopedVector<UploadElementReader> element_readers;
7985 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367986 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7987 temp_file_path,
7988 0,
7989 kuint64max,
7990 base::Time()));
[email protected]96c77a72013-09-24 09:49:207991 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277992
7993 HttpRequestInfo request;
7994 request.method = "POST";
7995 request.url = GURL("http://www.google.com/upload");
7996 request.upload_data_stream = &upload_data_stream;
7997 request.load_flags = 0;
7998
[email protected]3fe8d2f82013-10-17 08:56:077999 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278000 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]95d88ffe2010-02-04 21:25:338002
8003 MockRead data_reads[] = {
8004 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8005 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068006 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338007 };
[email protected]31a2bfe2010-02-09 08:03:398008 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078009 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338010
[email protected]49639fa2011-12-20 23:22:418011 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338012
[email protected]49639fa2011-12-20 23:22:418013 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338014 EXPECT_EQ(ERR_IO_PENDING, rv);
8015
8016 rv = callback.WaitForResult();
8017 EXPECT_EQ(OK, rv);
8018
8019 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508020 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338021
[email protected]90499482013-06-01 00:39:508022 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338023 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8024
8025 std::string response_data;
8026 rv = ReadTransaction(trans.get(), &response_data);
8027 EXPECT_EQ(OK, rv);
8028 EXPECT_EQ("hello world", response_data);
8029
[email protected]dd3aa792013-07-16 19:10:238030 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338031}
8032
[email protected]23e482282013-06-14 16:08:028033TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158034 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528035 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368036 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308037 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368038 temp_file_content.length()));
8039 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
8040
[email protected]b2d26cfd2012-12-11 10:36:068041 ScopedVector<UploadElementReader> element_readers;
8042 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368043 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8044 temp_file,
8045 0,
8046 kuint64max,
8047 base::Time()));
[email protected]96c77a72013-09-24 09:49:208048 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278049
8050 HttpRequestInfo request;
8051 request.method = "POST";
8052 request.url = GURL("http://www.google.com/upload");
8053 request.upload_data_stream = &upload_data_stream;
8054 request.load_flags = 0;
8055
[email protected]999dd8c2013-11-12 06:45:548056 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078057 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278058 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078059 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]6624b4622010-03-29 19:58:368060
[email protected]999dd8c2013-11-12 06:45:548061 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078062 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368063
[email protected]49639fa2011-12-20 23:22:418064 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368065
[email protected]49639fa2011-12-20 23:22:418066 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368067 EXPECT_EQ(ERR_IO_PENDING, rv);
8068
8069 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548070 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368071
8072 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548073 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368074
[email protected]dd3aa792013-07-16 19:10:238075 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368076}
8077
[email protected]02cad5d2013-10-02 08:14:038078TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8079 class FakeUploadElementReader : public UploadElementReader {
8080 public:
8081 FakeUploadElementReader() {}
8082 virtual ~FakeUploadElementReader() {}
8083
8084 const CompletionCallback& callback() const { return callback_; }
8085
8086 // UploadElementReader overrides:
8087 virtual int Init(const CompletionCallback& callback) OVERRIDE {
8088 callback_ = callback;
8089 return ERR_IO_PENDING;
8090 }
8091 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
8092 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
8093 virtual int Read(IOBuffer* buf,
8094 int buf_length,
8095 const CompletionCallback& callback) OVERRIDE {
8096 return ERR_FAILED;
8097 }
8098
8099 private:
8100 CompletionCallback callback_;
8101 };
8102
8103 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8104 ScopedVector<UploadElementReader> element_readers;
8105 element_readers.push_back(fake_reader);
8106 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8107
8108 HttpRequestInfo request;
8109 request.method = "POST";
8110 request.url = GURL("http://www.google.com/upload");
8111 request.upload_data_stream = &upload_data_stream;
8112 request.load_flags = 0;
8113
[email protected]3fe8d2f82013-10-17 08:56:078114 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038115 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]02cad5d2013-10-02 08:14:038117
8118 StaticSocketDataProvider data;
8119 session_deps_.socket_factory->AddSocketDataProvider(&data);
8120
8121 TestCompletionCallback callback;
8122 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8123 EXPECT_EQ(ERR_IO_PENDING, rv);
8124 base::MessageLoop::current()->RunUntilIdle();
8125
8126 // Transaction is pending on request body initialization.
8127 ASSERT_FALSE(fake_reader->callback().is_null());
8128
8129 // Return Init()'s result after the transaction gets destroyed.
8130 trans.reset();
8131 fake_reader->callback().Run(OK); // Should not crash.
8132}
8133
[email protected]aeefc9e82010-02-19 16:18:278134// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028135TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278136
8137 HttpRequestInfo request;
8138 request.method = "GET";
8139 request.url = GURL("http://www.google.com/");
8140 request.load_flags = 0;
8141
8142 // First transaction will request a resource and receive a Basic challenge
8143 // with realm="first_realm".
8144 MockWrite data_writes1[] = {
8145 MockWrite("GET / HTTP/1.1\r\n"
8146 "Host: www.google.com\r\n"
8147 "Connection: keep-alive\r\n"
8148 "\r\n"),
8149 };
8150 MockRead data_reads1[] = {
8151 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8152 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8153 "\r\n"),
8154 };
8155
8156 // After calling trans->RestartWithAuth(), provide an Authentication header
8157 // for first_realm. The server will reject and provide a challenge with
8158 // second_realm.
8159 MockWrite data_writes2[] = {
8160 MockWrite("GET / HTTP/1.1\r\n"
8161 "Host: www.google.com\r\n"
8162 "Connection: keep-alive\r\n"
8163 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8164 "\r\n"),
8165 };
8166 MockRead data_reads2[] = {
8167 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8168 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8169 "\r\n"),
8170 };
8171
8172 // This again fails, and goes back to first_realm. Make sure that the
8173 // entry is removed from cache.
8174 MockWrite data_writes3[] = {
8175 MockWrite("GET / HTTP/1.1\r\n"
8176 "Host: www.google.com\r\n"
8177 "Connection: keep-alive\r\n"
8178 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8179 "\r\n"),
8180 };
8181 MockRead data_reads3[] = {
8182 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8183 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8184 "\r\n"),
8185 };
8186
8187 // Try one last time (with the correct password) and get the resource.
8188 MockWrite data_writes4[] = {
8189 MockWrite("GET / HTTP/1.1\r\n"
8190 "Host: www.google.com\r\n"
8191 "Connection: keep-alive\r\n"
8192 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8193 "\r\n"),
8194 };
8195 MockRead data_reads4[] = {
8196 MockRead("HTTP/1.1 200 OK\r\n"
8197 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508198 "Content-Length: 5\r\n"
8199 "\r\n"
8200 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278201 };
8202
8203 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8204 data_writes1, arraysize(data_writes1));
8205 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8206 data_writes2, arraysize(data_writes2));
8207 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8208 data_writes3, arraysize(data_writes3));
8209 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8210 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078211 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8212 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8213 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8214 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278215
[email protected]49639fa2011-12-20 23:22:418216 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278217
[email protected]3fe8d2f82013-10-17 08:56:078218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508219 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078220 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0b0bf032010-09-21 18:08:508221
[email protected]aeefc9e82010-02-19 16:18:278222 // Issue the first request with Authorize headers. There should be a
8223 // password prompt for first_realm waiting to be filled in after the
8224 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418225 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278226 EXPECT_EQ(ERR_IO_PENDING, rv);
8227 rv = callback1.WaitForResult();
8228 EXPECT_EQ(OK, rv);
8229 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508230 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048231 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8232 ASSERT_FALSE(challenge == NULL);
8233 EXPECT_FALSE(challenge->is_proxy);
8234 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8235 EXPECT_EQ("first_realm", challenge->realm);
8236 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278237
8238 // Issue the second request with an incorrect password. There should be a
8239 // password prompt for second_realm waiting to be filled in after the
8240 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418241 TestCompletionCallback callback2;
8242 rv = trans->RestartWithAuth(
8243 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278244 EXPECT_EQ(ERR_IO_PENDING, rv);
8245 rv = callback2.WaitForResult();
8246 EXPECT_EQ(OK, rv);
8247 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508248 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048249 challenge = response->auth_challenge.get();
8250 ASSERT_FALSE(challenge == NULL);
8251 EXPECT_FALSE(challenge->is_proxy);
8252 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8253 EXPECT_EQ("second_realm", challenge->realm);
8254 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278255
8256 // Issue the third request with another incorrect password. There should be
8257 // a password prompt for first_realm waiting to be filled in. If the password
8258 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8259 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418260 TestCompletionCallback callback3;
8261 rv = trans->RestartWithAuth(
8262 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278263 EXPECT_EQ(ERR_IO_PENDING, rv);
8264 rv = callback3.WaitForResult();
8265 EXPECT_EQ(OK, rv);
8266 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508267 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048268 challenge = response->auth_challenge.get();
8269 ASSERT_FALSE(challenge == NULL);
8270 EXPECT_FALSE(challenge->is_proxy);
8271 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8272 EXPECT_EQ("first_realm", challenge->realm);
8273 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278274
8275 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418276 TestCompletionCallback callback4;
8277 rv = trans->RestartWithAuth(
8278 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278279 EXPECT_EQ(ERR_IO_PENDING, rv);
8280 rv = callback4.WaitForResult();
8281 EXPECT_EQ(OK, rv);
8282 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508283 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278284 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8285}
8286
[email protected]23e482282013-06-14 16:08:028287TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:038288 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:238289 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:428290
[email protected]8a0fc822013-06-27 20:52:438291 std::string alternate_protocol_http_header =
8292 GetAlternateProtocolHttpHeader();
8293
[email protected]564b4912010-03-09 16:30:428294 MockRead data_reads[] = {
8295 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438296 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428297 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068298 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428299 };
8300
8301 HttpRequestInfo request;
8302 request.method = "GET";
8303 request.url = GURL("http://www.google.com/");
8304 request.load_flags = 0;
8305
8306 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8307
[email protected]bb88e1d32013-05-03 23:11:078308 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428309
[email protected]49639fa2011-12-20 23:22:418310 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428311
[email protected]bb88e1d32013-05-03 23:11:078312 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368313 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508314 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428315
[email protected]49639fa2011-12-20 23:22:418316 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428317 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538318
[email protected]2fbaecf22010-07-22 22:20:358319 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558320 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538321 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428322 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538323 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428324
8325 EXPECT_EQ(OK, callback.WaitForResult());
8326
8327 const HttpResponseInfo* response = trans->GetResponseInfo();
8328 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508329 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428330 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538331 EXPECT_FALSE(response->was_fetched_via_spdy);
8332 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428333
8334 std::string response_data;
8335 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8336 EXPECT_EQ("hello world", response_data);
8337
[email protected]17291a022011-10-10 07:32:538338 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8339 const PortAlternateProtocolPair alternate =
8340 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8341 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:428342 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:438343 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:428344 EXPECT_TRUE(expected_alternate.Equals(alternate));
8345}
8346
[email protected]23e482282013-06-14 16:08:028347TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238348 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:388349 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:428350
8351 HttpRequestInfo request;
8352 request.method = "GET";
8353 request.url = GURL("http://www.google.com/");
8354 request.load_flags = 0;
8355
[email protected]d973e99a2012-02-17 21:02:368356 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428357 StaticSocketDataProvider first_data;
8358 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078359 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428360
8361 MockRead data_reads[] = {
8362 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8363 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068364 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428365 };
8366 StaticSocketDataProvider second_data(
8367 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078368 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428369
[email protected]bb88e1d32013-05-03 23:11:078370 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428371
[email protected]30d4c022013-07-18 22:58:168372 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538373 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118374 // Port must be < 1024, or the header will be ignored (since initial port was
8375 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538376 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118377 HostPortPair::FromURL(request.url),
8378 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438379 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428380
[email protected]262eec82013-03-19 21:01:368381 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508382 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418383 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428384
[email protected]49639fa2011-12-20 23:22:418385 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428386 EXPECT_EQ(ERR_IO_PENDING, rv);
8387 EXPECT_EQ(OK, callback.WaitForResult());
8388
8389 const HttpResponseInfo* response = trans->GetResponseInfo();
8390 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508391 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428392 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8393
8394 std::string response_data;
8395 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8396 EXPECT_EQ("hello world", response_data);
8397
[email protected]17291a022011-10-10 07:32:538398 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118399 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538400 const PortAlternateProtocolPair alternate =
8401 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118402 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538403 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428404}
8405
[email protected]23e482282013-06-14 16:08:028406TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238407 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118408 // Ensure that we're not allowed to redirect traffic via an alternate
8409 // protocol to an unrestricted (port >= 1024) when the original traffic was
8410 // on a restricted port (port < 1024). Ensure that we can redirect in all
8411 // other cases.
8412 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118413
8414 HttpRequestInfo restricted_port_request;
8415 restricted_port_request.method = "GET";
8416 restricted_port_request.url = GURL("http://www.google.com:1023/");
8417 restricted_port_request.load_flags = 0;
8418
[email protected]d973e99a2012-02-17 21:02:368419 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118420 StaticSocketDataProvider first_data;
8421 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078422 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118423
8424 MockRead data_reads[] = {
8425 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8426 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068427 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118428 };
8429 StaticSocketDataProvider second_data(
8430 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078431 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118432
[email protected]bb88e1d32013-05-03 23:11:078433 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118434
[email protected]30d4c022013-07-18 22:58:168435 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538436 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118437 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538438 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118439 HostPortPair::FromURL(restricted_port_request.url),
8440 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438441 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118442
[email protected]262eec82013-03-19 21:01:368443 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418445 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118446
[email protected]49639fa2011-12-20 23:22:418447 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368448 &restricted_port_request,
8449 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118450 EXPECT_EQ(ERR_IO_PENDING, rv);
8451 // Invalid change to unrestricted port should fail.
8452 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198453}
[email protected]3912662a32011-10-04 00:51:118454
[email protected]23e482282013-06-14 16:08:028455TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198456 AlternateProtocolPortRestrictedPermitted) {
8457 // Ensure that we're allowed to redirect traffic via an alternate
8458 // protocol to an unrestricted (port >= 1024) when the original traffic was
8459 // on a restricted port (port < 1024) if we set
8460 // enable_user_alternate_protocol_ports.
8461
8462 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078463 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198464
8465 HttpRequestInfo restricted_port_request;
8466 restricted_port_request.method = "GET";
8467 restricted_port_request.url = GURL("http://www.google.com:1023/");
8468 restricted_port_request.load_flags = 0;
8469
8470 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8471 StaticSocketDataProvider first_data;
8472 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078473 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198474
8475 MockRead data_reads[] = {
8476 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8477 MockRead("hello world"),
8478 MockRead(ASYNC, OK),
8479 };
8480 StaticSocketDataProvider second_data(
8481 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078482 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198483
[email protected]bb88e1d32013-05-03 23:11:078484 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198485
[email protected]30d4c022013-07-18 22:58:168486 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198487 session->http_server_properties();
8488 const int kUnrestrictedAlternatePort = 1024;
8489 http_server_properties->SetAlternateProtocol(
8490 HostPortPair::FromURL(restricted_port_request.url),
8491 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438492 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198493
[email protected]262eec82013-03-19 21:01:368494 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508495 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198496 TestCompletionCallback callback;
8497
8498 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368499 &restricted_port_request,
8500 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198501 // Change to unrestricted port should succeed.
8502 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118503}
8504
[email protected]23e482282013-06-14 16:08:028505TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238506 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118507 // Ensure that we're not allowed to redirect traffic via an alternate
8508 // protocol to an unrestricted (port >= 1024) when the original traffic was
8509 // on a restricted port (port < 1024). Ensure that we can redirect in all
8510 // other cases.
8511 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118512
8513 HttpRequestInfo restricted_port_request;
8514 restricted_port_request.method = "GET";
8515 restricted_port_request.url = GURL("http://www.google.com:1023/");
8516 restricted_port_request.load_flags = 0;
8517
[email protected]d973e99a2012-02-17 21:02:368518 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118519 StaticSocketDataProvider first_data;
8520 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078521 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118522
8523 MockRead data_reads[] = {
8524 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8525 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068526 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118527 };
8528 StaticSocketDataProvider second_data(
8529 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078530 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118531
[email protected]bb88e1d32013-05-03 23:11:078532 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118533
[email protected]30d4c022013-07-18 22:58:168534 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538535 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118536 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538537 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118538 HostPortPair::FromURL(restricted_port_request.url),
8539 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438540 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118541
[email protected]262eec82013-03-19 21:01:368542 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508543 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418544 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118545
[email protected]49639fa2011-12-20 23:22:418546 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368547 &restricted_port_request,
8548 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118549 EXPECT_EQ(ERR_IO_PENDING, rv);
8550 // Valid change to restricted port should pass.
8551 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118552}
8553
[email protected]23e482282013-06-14 16:08:028554TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238555 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118556 // Ensure that we're not allowed to redirect traffic via an alternate
8557 // protocol to an unrestricted (port >= 1024) when the original traffic was
8558 // on a restricted port (port < 1024). Ensure that we can redirect in all
8559 // other cases.
8560 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118561
8562 HttpRequestInfo unrestricted_port_request;
8563 unrestricted_port_request.method = "GET";
8564 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8565 unrestricted_port_request.load_flags = 0;
8566
[email protected]d973e99a2012-02-17 21:02:368567 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118568 StaticSocketDataProvider first_data;
8569 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078570 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118571
8572 MockRead data_reads[] = {
8573 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8574 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068575 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118576 };
8577 StaticSocketDataProvider second_data(
8578 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078579 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118580
[email protected]bb88e1d32013-05-03 23:11:078581 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118582
[email protected]30d4c022013-07-18 22:58:168583 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538584 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118585 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538586 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118587 HostPortPair::FromURL(unrestricted_port_request.url),
8588 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438589 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118590
[email protected]262eec82013-03-19 21:01:368591 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508592 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418593 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118594
[email protected]49639fa2011-12-20 23:22:418595 int rv = trans->Start(
8596 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118597 EXPECT_EQ(ERR_IO_PENDING, rv);
8598 // Valid change to restricted port should pass.
8599 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118600}
8601
[email protected]23e482282013-06-14 16:08:028602TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238603 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118604 // Ensure that we're not allowed to redirect traffic via an alternate
8605 // protocol to an unrestricted (port >= 1024) when the original traffic was
8606 // on a restricted port (port < 1024). Ensure that we can redirect in all
8607 // other cases.
8608 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118609
8610 HttpRequestInfo unrestricted_port_request;
8611 unrestricted_port_request.method = "GET";
8612 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8613 unrestricted_port_request.load_flags = 0;
8614
[email protected]d973e99a2012-02-17 21:02:368615 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118616 StaticSocketDataProvider first_data;
8617 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078618 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118619
8620 MockRead data_reads[] = {
8621 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8622 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068623 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118624 };
8625 StaticSocketDataProvider second_data(
8626 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078627 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118628
[email protected]bb88e1d32013-05-03 23:11:078629 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118630
[email protected]30d4c022013-07-18 22:58:168631 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538632 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118633 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538634 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118635 HostPortPair::FromURL(unrestricted_port_request.url),
8636 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438637 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118638
[email protected]262eec82013-03-19 21:01:368639 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418641 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118642
[email protected]49639fa2011-12-20 23:22:418643 int rv = trans->Start(
8644 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118645 EXPECT_EQ(ERR_IO_PENDING, rv);
8646 // Valid change to an unrestricted port should pass.
8647 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118648}
8649
[email protected]23e482282013-06-14 16:08:028650TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238651 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028652 // Ensure that we're not allowed to redirect traffic via an alternate
8653 // protocol to an unsafe port, and that we resume the second
8654 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8655 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028656
8657 HttpRequestInfo request;
8658 request.method = "GET";
8659 request.url = GURL("http://www.google.com/");
8660 request.load_flags = 0;
8661
8662 // The alternate protocol request will error out before we attempt to connect,
8663 // so only the standard HTTP request will try to connect.
8664 MockRead data_reads[] = {
8665 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8666 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068667 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028668 };
8669 StaticSocketDataProvider data(
8670 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078671 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028672
[email protected]bb88e1d32013-05-03 23:11:078673 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028674
[email protected]30d4c022013-07-18 22:58:168675 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028676 session->http_server_properties();
8677 const int kUnsafePort = 7;
8678 http_server_properties->SetAlternateProtocol(
8679 HostPortPair::FromURL(request.url),
8680 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438681 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028682
[email protected]262eec82013-03-19 21:01:368683 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508684 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028685 TestCompletionCallback callback;
8686
8687 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8688 EXPECT_EQ(ERR_IO_PENDING, rv);
8689 // The HTTP request should succeed.
8690 EXPECT_EQ(OK, callback.WaitForResult());
8691
8692 // Disable alternate protocol before the asserts.
8693 HttpStreamFactory::set_use_alternate_protocols(false);
8694
8695 const HttpResponseInfo* response = trans->GetResponseInfo();
8696 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508697 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028698 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8699
8700 std::string response_data;
8701 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8702 EXPECT_EQ("hello world", response_data);
8703}
8704
[email protected]23e482282013-06-14 16:08:028705TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388706 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038707 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548708
8709 HttpRequestInfo request;
8710 request.method = "GET";
8711 request.url = GURL("http://www.google.com/");
8712 request.load_flags = 0;
8713
[email protected]8a0fc822013-06-27 20:52:438714 std::string alternate_protocol_http_header =
8715 GetAlternateProtocolHttpHeader();
8716
[email protected]2ff8b312010-04-26 22:20:548717 MockRead data_reads[] = {
8718 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438719 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548720 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178721 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8722 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548723 };
8724
8725 StaticSocketDataProvider first_transaction(
8726 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078727 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548728
[email protected]8ddf8322012-02-23 18:08:068729 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028730 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078731 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548732
[email protected]cdf8f7e72013-05-23 10:56:468733 scoped_ptr<SpdyFrame> req(
8734 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138735 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548736
[email protected]23e482282013-06-14 16:08:028737 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8738 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548739 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138740 CreateMockRead(*resp),
8741 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068742 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548743 };
8744
[email protected]dd54bd82012-07-19 23:44:578745 DelayedSocketData spdy_data(
8746 1, // wait for one write to finish before reading.
8747 spdy_reads, arraysize(spdy_reads),
8748 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078749 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548750
[email protected]d973e99a2012-02-17 21:02:368751 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558752 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8753 NULL, 0, NULL, 0);
8754 hanging_non_alternate_protocol_socket.set_connect_data(
8755 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078756 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558757 &hanging_non_alternate_protocol_socket);
8758
[email protected]49639fa2011-12-20 23:22:418759 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548760
[email protected]bb88e1d32013-05-03 23:11:078761 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368762 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508763 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548764
[email protected]49639fa2011-12-20 23:22:418765 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548766 EXPECT_EQ(ERR_IO_PENDING, rv);
8767 EXPECT_EQ(OK, callback.WaitForResult());
8768
8769 const HttpResponseInfo* response = trans->GetResponseInfo();
8770 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508771 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548772 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8773
8774 std::string response_data;
8775 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8776 EXPECT_EQ("hello world", response_data);
8777
[email protected]90499482013-06-01 00:39:508778 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548779
[email protected]49639fa2011-12-20 23:22:418780 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548781 EXPECT_EQ(ERR_IO_PENDING, rv);
8782 EXPECT_EQ(OK, callback.WaitForResult());
8783
8784 response = trans->GetResponseInfo();
8785 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508786 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548787 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538788 EXPECT_TRUE(response->was_fetched_via_spdy);
8789 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548790
8791 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8792 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548793}
8794
[email protected]23e482282013-06-14 16:08:028795TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558796 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038797 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558798
8799 HttpRequestInfo request;
8800 request.method = "GET";
8801 request.url = GURL("http://www.google.com/");
8802 request.load_flags = 0;
8803
[email protected]8a0fc822013-06-27 20:52:438804 std::string alternate_protocol_http_header =
8805 GetAlternateProtocolHttpHeader();
8806
[email protected]2d6728692011-03-12 01:39:558807 MockRead data_reads[] = {
8808 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438809 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558810 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178811 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068812 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558813 };
8814
8815 StaticSocketDataProvider first_transaction(
8816 data_reads, arraysize(data_reads), NULL, 0);
8817 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078818 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558819
[email protected]d973e99a2012-02-17 21:02:368820 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558821 StaticSocketDataProvider hanging_socket(
8822 NULL, 0, NULL, 0);
8823 hanging_socket.set_connect_data(never_finishing_connect);
8824 // Socket 2 and 3 are the hanging Alternate-Protocol and
8825 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078826 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8827 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558828
[email protected]8ddf8322012-02-23 18:08:068829 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028830 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078831 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558832
[email protected]cdf8f7e72013-05-23 10:56:468833 scoped_ptr<SpdyFrame> req1(
8834 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8835 scoped_ptr<SpdyFrame> req2(
8836 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558837 MockWrite spdy_writes[] = {
8838 CreateMockWrite(*req1),
8839 CreateMockWrite(*req2),
8840 };
[email protected]23e482282013-06-14 16:08:028841 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8842 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8843 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8844 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558845 MockRead spdy_reads[] = {
8846 CreateMockRead(*resp1),
8847 CreateMockRead(*data1),
8848 CreateMockRead(*resp2),
8849 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068850 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558851 };
8852
[email protected]dd54bd82012-07-19 23:44:578853 DelayedSocketData spdy_data(
8854 2, // wait for writes to finish before reading.
8855 spdy_reads, arraysize(spdy_reads),
8856 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558857 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078858 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558859
8860 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078861 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558862
[email protected]bb88e1d32013-05-03 23:11:078863 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418864 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508865 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558866
[email protected]49639fa2011-12-20 23:22:418867 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558868 EXPECT_EQ(ERR_IO_PENDING, rv);
8869 EXPECT_EQ(OK, callback1.WaitForResult());
8870
8871 const HttpResponseInfo* response = trans1.GetResponseInfo();
8872 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508873 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558874 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8875
8876 std::string response_data;
8877 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8878 EXPECT_EQ("hello world", response_data);
8879
[email protected]49639fa2011-12-20 23:22:418880 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508881 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418882 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558883 EXPECT_EQ(ERR_IO_PENDING, rv);
8884
[email protected]49639fa2011-12-20 23:22:418885 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508886 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418887 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558888 EXPECT_EQ(ERR_IO_PENDING, rv);
8889
8890 EXPECT_EQ(OK, callback2.WaitForResult());
8891 EXPECT_EQ(OK, callback3.WaitForResult());
8892
8893 response = trans2.GetResponseInfo();
8894 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508895 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558896 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8897 EXPECT_TRUE(response->was_fetched_via_spdy);
8898 EXPECT_TRUE(response->was_npn_negotiated);
8899 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8900 EXPECT_EQ("hello!", response_data);
8901
8902 response = trans3.GetResponseInfo();
8903 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508904 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558905 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8906 EXPECT_TRUE(response->was_fetched_via_spdy);
8907 EXPECT_TRUE(response->was_npn_negotiated);
8908 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8909 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558910}
8911
[email protected]23e482282013-06-14 16:08:028912TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558913 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038914 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558915
8916 HttpRequestInfo request;
8917 request.method = "GET";
8918 request.url = GURL("http://www.google.com/");
8919 request.load_flags = 0;
8920
[email protected]8a0fc822013-06-27 20:52:438921 std::string alternate_protocol_http_header =
8922 GetAlternateProtocolHttpHeader();
8923
[email protected]2d6728692011-03-12 01:39:558924 MockRead data_reads[] = {
8925 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438926 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558927 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178928 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068929 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558930 };
8931
8932 StaticSocketDataProvider first_transaction(
8933 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078934 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558935
[email protected]8ddf8322012-02-23 18:08:068936 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028937 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078938 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558939
[email protected]d973e99a2012-02-17 21:02:368940 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558941 StaticSocketDataProvider hanging_alternate_protocol_socket(
8942 NULL, 0, NULL, 0);
8943 hanging_alternate_protocol_socket.set_connect_data(
8944 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078945 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558946 &hanging_alternate_protocol_socket);
8947
8948 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078949 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558950
[email protected]49639fa2011-12-20 23:22:418951 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558952
[email protected]bb88e1d32013-05-03 23:11:078953 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368954 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508955 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558956
[email protected]49639fa2011-12-20 23:22:418957 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558958 EXPECT_EQ(ERR_IO_PENDING, rv);
8959 EXPECT_EQ(OK, callback.WaitForResult());
8960
8961 const HttpResponseInfo* response = trans->GetResponseInfo();
8962 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508963 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558964 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8965
8966 std::string response_data;
8967 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8968 EXPECT_EQ("hello world", response_data);
8969
[email protected]90499482013-06-01 00:39:508970 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558971
[email protected]49639fa2011-12-20 23:22:418972 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558973 EXPECT_EQ(ERR_IO_PENDING, rv);
8974 EXPECT_EQ(OK, callback.WaitForResult());
8975
8976 response = trans->GetResponseInfo();
8977 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508978 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558979 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8980 EXPECT_FALSE(response->was_fetched_via_spdy);
8981 EXPECT_FALSE(response->was_npn_negotiated);
8982
8983 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8984 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558985}
8986
[email protected]631f1322010-04-30 17:59:118987class CapturingProxyResolver : public ProxyResolver {
8988 public:
8989 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8990 virtual ~CapturingProxyResolver() {}
8991
8992 virtual int GetProxyForURL(const GURL& url,
8993 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318994 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118995 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168996 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408997 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8998 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428999 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119000 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429001 return OK;
[email protected]631f1322010-04-30 17:59:119002 }
9003
[email protected]46fadfd2013-02-06 09:40:169004 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:119005 NOTREACHED();
9006 }
9007
[email protected]f2c971f2011-11-08 00:33:179008 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
9009 NOTREACHED();
9010 return LOAD_STATE_IDLE;
9011 }
9012
[email protected]46fadfd2013-02-06 09:40:169013 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:409014 NOTREACHED();
9015 }
9016
[email protected]24476402010-07-20 20:55:179017 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:169018 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:429019 return OK;
[email protected]631f1322010-04-30 17:59:119020 }
9021
[email protected]24476402010-07-20 20:55:179022 const std::vector<GURL>& resolved() const { return resolved_; }
9023
9024 private:
[email protected]631f1322010-04-30 17:59:119025 std::vector<GURL> resolved_;
9026
9027 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9028};
9029
[email protected]23e482282013-06-14 16:08:029030TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239031 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:389032 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039033 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:119034
9035 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429036 proxy_config.set_auto_detect(true);
9037 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119038
[email protected]631f1322010-04-30 17:59:119039 CapturingProxyResolver* capturing_proxy_resolver =
9040 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:079041 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:389042 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9043 NULL));
[email protected]029c83b62013-01-24 05:28:209044 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079045 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119046
9047 HttpRequestInfo request;
9048 request.method = "GET";
9049 request.url = GURL("http://www.google.com/");
9050 request.load_flags = 0;
9051
[email protected]8a0fc822013-06-27 20:52:439052 std::string alternate_protocol_http_header =
9053 GetAlternateProtocolHttpHeader();
9054
[email protected]631f1322010-04-30 17:59:119055 MockRead data_reads[] = {
9056 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439057 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119058 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179059 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069060 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119061 };
9062
9063 StaticSocketDataProvider first_transaction(
9064 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079065 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119066
[email protected]8ddf8322012-02-23 18:08:069067 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029068 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119070
[email protected]cdf8f7e72013-05-23 10:56:469071 scoped_ptr<SpdyFrame> req(
9072 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119073 MockWrite spdy_writes[] = {
9074 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9075 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:429076 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:469077 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:119078 };
9079
[email protected]d911f1b2010-05-05 22:39:429080 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9081
[email protected]23e482282013-06-14 16:08:029082 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9083 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119084 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069085 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:139086 CreateMockRead(*resp.get(), 4), // 2, 4
9087 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:069088 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:119089 };
9090
[email protected]dd54bd82012-07-19 23:44:579091 OrderedSocketData spdy_data(
9092 spdy_reads, arraysize(spdy_reads),
9093 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079094 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119095
[email protected]d973e99a2012-02-17 21:02:369096 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559097 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9098 NULL, 0, NULL, 0);
9099 hanging_non_alternate_protocol_socket.set_connect_data(
9100 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079101 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559102 &hanging_non_alternate_protocol_socket);
9103
[email protected]49639fa2011-12-20 23:22:419104 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119105
[email protected]bb88e1d32013-05-03 23:11:079106 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369107 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509108 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119109
[email protected]49639fa2011-12-20 23:22:419110 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119111 EXPECT_EQ(ERR_IO_PENDING, rv);
9112 EXPECT_EQ(OK, callback.WaitForResult());
9113
9114 const HttpResponseInfo* response = trans->GetResponseInfo();
9115 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509116 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119117 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539118 EXPECT_FALSE(response->was_fetched_via_spdy);
9119 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119120
9121 std::string response_data;
9122 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9123 EXPECT_EQ("hello world", response_data);
9124
[email protected]90499482013-06-01 00:39:509125 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119126
[email protected]49639fa2011-12-20 23:22:419127 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119128 EXPECT_EQ(ERR_IO_PENDING, rv);
9129 EXPECT_EQ(OK, callback.WaitForResult());
9130
9131 response = trans->GetResponseInfo();
9132 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509133 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119134 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539135 EXPECT_TRUE(response->was_fetched_via_spdy);
9136 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119137
9138 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9139 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559140 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:429141 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:119142 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:429143 EXPECT_EQ("https://www.google.com/",
9144 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119145
[email protected]029c83b62013-01-24 05:28:209146 LoadTimingInfo load_timing_info;
9147 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9148 TestLoadTimingNotReusedWithPac(load_timing_info,
9149 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119150}
[email protected]631f1322010-04-30 17:59:119151
[email protected]23e482282013-06-14 16:08:029152TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549153 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:389154 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039155 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:549156
9157 HttpRequestInfo request;
9158 request.method = "GET";
9159 request.url = GURL("http://www.google.com/");
9160 request.load_flags = 0;
9161
[email protected]8a0fc822013-06-27 20:52:439162 std::string alternate_protocol_http_header =
9163 GetAlternateProtocolHttpHeader();
9164
[email protected]2ff8b312010-04-26 22:20:549165 MockRead data_reads[] = {
9166 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439167 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549168 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069169 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549170 };
9171
9172 StaticSocketDataProvider first_transaction(
9173 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079174 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549175
[email protected]8ddf8322012-02-23 18:08:069176 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029177 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079178 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549179
[email protected]cdf8f7e72013-05-23 10:56:469180 scoped_ptr<SpdyFrame> req(
9181 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139182 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549183
[email protected]23e482282013-06-14 16:08:029184 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9185 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549186 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139187 CreateMockRead(*resp),
9188 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069189 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549190 };
9191
[email protected]dd54bd82012-07-19 23:44:579192 DelayedSocketData spdy_data(
9193 1, // wait for one write to finish before reading.
9194 spdy_reads, arraysize(spdy_reads),
9195 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079196 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549197
[email protected]83039bb2011-12-09 18:43:559198 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549199
[email protected]bb88e1d32013-05-03 23:11:079200 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549201
[email protected]262eec82013-03-19 21:01:369202 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509203 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549204
[email protected]49639fa2011-12-20 23:22:419205 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549206 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419207 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549208
9209 const HttpResponseInfo* response = trans->GetResponseInfo();
9210 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509211 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549212 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9213
9214 std::string response_data;
9215 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9216 EXPECT_EQ("hello world", response_data);
9217
9218 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389219 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409220 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9221 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:279222 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269223 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389224
[email protected]90499482013-06-01 00:39:509225 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549226
[email protected]49639fa2011-12-20 23:22:419227 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549228 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419229 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549230
9231 response = trans->GetResponseInfo();
9232 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509233 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549234 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539235 EXPECT_TRUE(response->was_fetched_via_spdy);
9236 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549237
9238 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9239 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429240}
9241
[email protected]044de0642010-06-17 10:42:159242// GenerateAuthToken is a mighty big test.
9243// It tests all permutation of GenerateAuthToken behavior:
9244// - Synchronous and Asynchronous completion.
9245// - OK or error on completion.
9246// - Direct connection, non-authenticating proxy, and authenticating proxy.
9247// - HTTP or HTTPS backend (to include proxy tunneling).
9248// - Non-authenticating and authenticating backend.
9249//
[email protected]fe3b7dc2012-02-03 19:52:099250// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159251// problems generating an auth token for an authenticating proxy, we don't
9252// need to test all permutations of the backend server).
9253//
9254// The test proceeds by going over each of the configuration cases, and
9255// potentially running up to three rounds in each of the tests. The TestConfig
9256// specifies both the configuration for the test as well as the expectations
9257// for the results.
[email protected]23e482282013-06-14 16:08:029258TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509259 static const char kServer[] = "http://www.example.com";
9260 static const char kSecureServer[] = "https://www.example.com";
9261 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159262 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9263
9264 enum AuthTiming {
9265 AUTH_NONE,
9266 AUTH_SYNC,
9267 AUTH_ASYNC,
9268 };
9269
9270 const MockWrite kGet(
9271 "GET / HTTP/1.1\r\n"
9272 "Host: www.example.com\r\n"
9273 "Connection: keep-alive\r\n\r\n");
9274 const MockWrite kGetProxy(
9275 "GET http://www.example.com/ HTTP/1.1\r\n"
9276 "Host: www.example.com\r\n"
9277 "Proxy-Connection: keep-alive\r\n\r\n");
9278 const MockWrite kGetAuth(
9279 "GET / HTTP/1.1\r\n"
9280 "Host: www.example.com\r\n"
9281 "Connection: keep-alive\r\n"
9282 "Authorization: auth_token\r\n\r\n");
9283 const MockWrite kGetProxyAuth(
9284 "GET http://www.example.com/ HTTP/1.1\r\n"
9285 "Host: www.example.com\r\n"
9286 "Proxy-Connection: keep-alive\r\n"
9287 "Proxy-Authorization: auth_token\r\n\r\n");
9288 const MockWrite kGetAuthThroughProxy(
9289 "GET http://www.example.com/ HTTP/1.1\r\n"
9290 "Host: www.example.com\r\n"
9291 "Proxy-Connection: keep-alive\r\n"
9292 "Authorization: auth_token\r\n\r\n");
9293 const MockWrite kGetAuthWithProxyAuth(
9294 "GET http://www.example.com/ HTTP/1.1\r\n"
9295 "Host: www.example.com\r\n"
9296 "Proxy-Connection: keep-alive\r\n"
9297 "Proxy-Authorization: auth_token\r\n"
9298 "Authorization: auth_token\r\n\r\n");
9299 const MockWrite kConnect(
9300 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9301 "Host: www.example.com\r\n"
9302 "Proxy-Connection: keep-alive\r\n\r\n");
9303 const MockWrite kConnectProxyAuth(
9304 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9305 "Host: www.example.com\r\n"
9306 "Proxy-Connection: keep-alive\r\n"
9307 "Proxy-Authorization: auth_token\r\n\r\n");
9308
9309 const MockRead kSuccess(
9310 "HTTP/1.1 200 OK\r\n"
9311 "Content-Type: text/html; charset=iso-8859-1\r\n"
9312 "Content-Length: 3\r\n\r\n"
9313 "Yes");
9314 const MockRead kFailure(
9315 "Should not be called.");
9316 const MockRead kServerChallenge(
9317 "HTTP/1.1 401 Unauthorized\r\n"
9318 "WWW-Authenticate: Mock realm=server\r\n"
9319 "Content-Type: text/html; charset=iso-8859-1\r\n"
9320 "Content-Length: 14\r\n\r\n"
9321 "Unauthorized\r\n");
9322 const MockRead kProxyChallenge(
9323 "HTTP/1.1 407 Unauthorized\r\n"
9324 "Proxy-Authenticate: Mock realm=proxy\r\n"
9325 "Proxy-Connection: close\r\n"
9326 "Content-Type: text/html; charset=iso-8859-1\r\n"
9327 "Content-Length: 14\r\n\r\n"
9328 "Unauthorized\r\n");
9329 const MockRead kProxyConnected(
9330 "HTTP/1.1 200 Connection Established\r\n\r\n");
9331
9332 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9333 // no constructors, but the C++ compiler on Windows warns about
9334 // unspecified data in compound literals. So, moved to using constructors,
9335 // and TestRound's created with the default constructor should not be used.
9336 struct TestRound {
9337 TestRound()
9338 : expected_rv(ERR_UNEXPECTED),
9339 extra_write(NULL),
9340 extra_read(NULL) {
9341 }
9342 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9343 int expected_rv_arg)
9344 : write(write_arg),
9345 read(read_arg),
9346 expected_rv(expected_rv_arg),
9347 extra_write(NULL),
9348 extra_read(NULL) {
9349 }
9350 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9351 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019352 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159353 : write(write_arg),
9354 read(read_arg),
9355 expected_rv(expected_rv_arg),
9356 extra_write(extra_write_arg),
9357 extra_read(extra_read_arg) {
9358 }
9359 MockWrite write;
9360 MockRead read;
9361 int expected_rv;
9362 const MockWrite* extra_write;
9363 const MockRead* extra_read;
9364 };
9365
9366 static const int kNoSSL = 500;
9367
9368 struct TestConfig {
9369 const char* proxy_url;
9370 AuthTiming proxy_auth_timing;
9371 int proxy_auth_rv;
9372 const char* server_url;
9373 AuthTiming server_auth_timing;
9374 int server_auth_rv;
9375 int num_auth_rounds;
9376 int first_ssl_round;
9377 TestRound rounds[3];
9378 } test_configs[] = {
9379 // Non-authenticating HTTP server with a direct connection.
9380 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9381 { TestRound(kGet, kSuccess, OK)}},
9382 // Authenticating HTTP server with a direct connection.
9383 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9384 { TestRound(kGet, kServerChallenge, OK),
9385 TestRound(kGetAuth, kSuccess, OK)}},
9386 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9387 { TestRound(kGet, kServerChallenge, OK),
9388 TestRound(kGetAuth, kFailure, kAuthErr)}},
9389 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9390 { TestRound(kGet, kServerChallenge, OK),
9391 TestRound(kGetAuth, kSuccess, OK)}},
9392 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9393 { TestRound(kGet, kServerChallenge, OK),
9394 TestRound(kGetAuth, kFailure, kAuthErr)}},
9395 // Non-authenticating HTTP server through a non-authenticating proxy.
9396 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9397 { TestRound(kGetProxy, kSuccess, OK)}},
9398 // Authenticating HTTP server through a non-authenticating proxy.
9399 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9400 { TestRound(kGetProxy, kServerChallenge, OK),
9401 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9402 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9403 { TestRound(kGetProxy, kServerChallenge, OK),
9404 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9405 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9406 { TestRound(kGetProxy, kServerChallenge, OK),
9407 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9408 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9409 { TestRound(kGetProxy, kServerChallenge, OK),
9410 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9411 // Non-authenticating HTTP server through an authenticating proxy.
9412 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9413 { TestRound(kGetProxy, kProxyChallenge, OK),
9414 TestRound(kGetProxyAuth, kSuccess, OK)}},
9415 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9416 { TestRound(kGetProxy, kProxyChallenge, OK),
9417 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9418 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9419 { TestRound(kGetProxy, kProxyChallenge, OK),
9420 TestRound(kGetProxyAuth, kSuccess, OK)}},
9421 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9422 { TestRound(kGetProxy, kProxyChallenge, OK),
9423 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9424 // Authenticating HTTP server through an authenticating proxy.
9425 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9426 { TestRound(kGetProxy, kProxyChallenge, OK),
9427 TestRound(kGetProxyAuth, kServerChallenge, OK),
9428 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9429 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9430 { TestRound(kGetProxy, kProxyChallenge, OK),
9431 TestRound(kGetProxyAuth, kServerChallenge, OK),
9432 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9433 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9434 { TestRound(kGetProxy, kProxyChallenge, OK),
9435 TestRound(kGetProxyAuth, kServerChallenge, OK),
9436 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9437 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9438 { TestRound(kGetProxy, kProxyChallenge, OK),
9439 TestRound(kGetProxyAuth, kServerChallenge, OK),
9440 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9441 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9442 { TestRound(kGetProxy, kProxyChallenge, OK),
9443 TestRound(kGetProxyAuth, kServerChallenge, OK),
9444 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9445 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9446 { TestRound(kGetProxy, kProxyChallenge, OK),
9447 TestRound(kGetProxyAuth, kServerChallenge, OK),
9448 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9449 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9450 { TestRound(kGetProxy, kProxyChallenge, OK),
9451 TestRound(kGetProxyAuth, kServerChallenge, OK),
9452 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9453 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9454 { TestRound(kGetProxy, kProxyChallenge, OK),
9455 TestRound(kGetProxyAuth, kServerChallenge, OK),
9456 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9457 // Non-authenticating HTTPS server with a direct connection.
9458 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9459 { TestRound(kGet, kSuccess, OK)}},
9460 // Authenticating HTTPS server with a direct connection.
9461 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9462 { TestRound(kGet, kServerChallenge, OK),
9463 TestRound(kGetAuth, kSuccess, OK)}},
9464 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9465 { TestRound(kGet, kServerChallenge, OK),
9466 TestRound(kGetAuth, kFailure, kAuthErr)}},
9467 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9468 { TestRound(kGet, kServerChallenge, OK),
9469 TestRound(kGetAuth, kSuccess, OK)}},
9470 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9471 { TestRound(kGet, kServerChallenge, OK),
9472 TestRound(kGetAuth, kFailure, kAuthErr)}},
9473 // Non-authenticating HTTPS server with a non-authenticating proxy.
9474 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9475 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9476 // Authenticating HTTPS server through a non-authenticating proxy.
9477 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9478 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9479 TestRound(kGetAuth, kSuccess, OK)}},
9480 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9481 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9482 TestRound(kGetAuth, kFailure, kAuthErr)}},
9483 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9484 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9485 TestRound(kGetAuth, kSuccess, OK)}},
9486 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9487 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9488 TestRound(kGetAuth, kFailure, kAuthErr)}},
9489 // Non-Authenticating HTTPS server through an authenticating proxy.
9490 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9491 { TestRound(kConnect, kProxyChallenge, OK),
9492 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9493 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9494 { TestRound(kConnect, kProxyChallenge, OK),
9495 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9496 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9497 { TestRound(kConnect, kProxyChallenge, OK),
9498 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9499 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9500 { TestRound(kConnect, kProxyChallenge, OK),
9501 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9502 // Authenticating HTTPS server through an authenticating proxy.
9503 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9504 { TestRound(kConnect, kProxyChallenge, OK),
9505 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9506 &kGet, &kServerChallenge),
9507 TestRound(kGetAuth, kSuccess, OK)}},
9508 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9509 { TestRound(kConnect, kProxyChallenge, OK),
9510 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9511 &kGet, &kServerChallenge),
9512 TestRound(kGetAuth, kFailure, kAuthErr)}},
9513 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9514 { TestRound(kConnect, kProxyChallenge, OK),
9515 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9516 &kGet, &kServerChallenge),
9517 TestRound(kGetAuth, kSuccess, OK)}},
9518 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9519 { TestRound(kConnect, kProxyChallenge, OK),
9520 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9521 &kGet, &kServerChallenge),
9522 TestRound(kGetAuth, kFailure, kAuthErr)}},
9523 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9524 { TestRound(kConnect, kProxyChallenge, OK),
9525 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9526 &kGet, &kServerChallenge),
9527 TestRound(kGetAuth, kSuccess, OK)}},
9528 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9529 { TestRound(kConnect, kProxyChallenge, OK),
9530 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9531 &kGet, &kServerChallenge),
9532 TestRound(kGetAuth, kFailure, kAuthErr)}},
9533 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9534 { TestRound(kConnect, kProxyChallenge, OK),
9535 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9536 &kGet, &kServerChallenge),
9537 TestRound(kGetAuth, kSuccess, OK)}},
9538 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9539 { TestRound(kConnect, kProxyChallenge, OK),
9540 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9541 &kGet, &kServerChallenge),
9542 TestRound(kGetAuth, kFailure, kAuthErr)}},
9543 };
9544
[email protected]044de0642010-06-17 10:42:159545 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089546 HttpAuthHandlerMock::Factory* auth_factory(
9547 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079548 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159549 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269550
9551 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159552 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089553 for (int n = 0; n < 2; n++) {
9554 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9555 std::string auth_challenge = "Mock realm=proxy";
9556 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:249557 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9558 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:089559 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9560 origin, BoundNetLog());
9561 auth_handler->SetGenerateExpectation(
9562 test_config.proxy_auth_timing == AUTH_ASYNC,
9563 test_config.proxy_auth_rv);
9564 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9565 }
[email protected]044de0642010-06-17 10:42:159566 }
9567 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009568 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159569 std::string auth_challenge = "Mock realm=server";
9570 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:249571 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9572 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:159573 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9574 origin, BoundNetLog());
9575 auth_handler->SetGenerateExpectation(
9576 test_config.server_auth_timing == AUTH_ASYNC,
9577 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089578 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159579 }
9580 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079581 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129582 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159583 } else {
[email protected]bb88e1d32013-05-03 23:11:079584 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159585 }
9586
9587 HttpRequestInfo request;
9588 request.method = "GET";
9589 request.url = GURL(test_config.server_url);
9590 request.load_flags = 0;
9591
[email protected]bb88e1d32013-05-03 23:11:079592 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:079593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]044de0642010-06-17 10:42:159594
9595 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9596 const TestRound& read_write_round = test_config.rounds[round];
9597
9598 // Set up expected reads and writes.
9599 MockRead reads[2];
9600 reads[0] = read_write_round.read;
9601 size_t length_reads = 1;
9602 if (read_write_round.extra_read) {
9603 reads[1] = *read_write_round.extra_read;
9604 length_reads = 2;
9605 }
9606
9607 MockWrite writes[2];
9608 writes[0] = read_write_round.write;
9609 size_t length_writes = 1;
9610 if (read_write_round.extra_write) {
9611 writes[1] = *read_write_round.extra_write;
9612 length_writes = 2;
9613 }
9614 StaticSocketDataProvider data_provider(
9615 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079616 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159617
9618 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069619 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159620 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079621 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159622 &ssl_socket_data_provider);
9623
9624 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419625 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159626 int rv;
9627 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419628 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159629 } else {
[email protected]49639fa2011-12-20 23:22:419630 rv = trans.RestartWithAuth(
9631 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159632 }
9633 if (rv == ERR_IO_PENDING)
9634 rv = callback.WaitForResult();
9635
9636 // Compare results with expected data.
9637 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509638 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159639 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509640 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159641 } else {
9642 EXPECT_TRUE(response == NULL);
9643 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9644 continue;
9645 }
9646 if (round + 1 < test_config.num_auth_rounds) {
9647 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9648 } else {
9649 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9650 }
9651 }
[email protected]e5ae96a2010-04-14 20:12:459652 }
9653}
9654
[email protected]23e482282013-06-14 16:08:029655TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149656 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149657 HttpAuthHandlerMock::Factory* auth_factory(
9658 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079659 session_deps_.http_auth_handler_factory.reset(auth_factory);
9660 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9661 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9662 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149663
9664 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9665 auth_handler->set_connection_based(true);
9666 std::string auth_challenge = "Mock realm=server";
9667 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:249668 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9669 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:149670 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9671 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089672 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149673
[email protected]c871bce92010-07-15 21:51:149674 int rv = OK;
9675 const HttpResponseInfo* response = NULL;
9676 HttpRequestInfo request;
9677 request.method = "GET";
9678 request.url = origin;
9679 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279680
[email protected]bb88e1d32013-05-03 23:11:079681 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109682
9683 // Use a TCP Socket Pool with only one connection per group. This is used
9684 // to validate that the TCP socket is not released to the pool between
9685 // each round of multi-round authentication.
9686 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289687 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9688 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109689 50, // Max sockets for pool
9690 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289691 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079692 session_deps_.host_resolver.get(),
9693 session_deps_.socket_factory.get(),
9694 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449695 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9696 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029697 mock_pool_manager->SetTransportSocketPool(transport_pool);
[email protected]831e4a32013-11-14 02:14:449698 session_peer.SetClientSocketPoolManager(
9699 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]7ef4cbbb2011-02-06 11:19:109700
[email protected]262eec82013-03-19 21:01:369701 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509702 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419703 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149704
9705 const MockWrite kGet(
9706 "GET / HTTP/1.1\r\n"
9707 "Host: www.example.com\r\n"
9708 "Connection: keep-alive\r\n\r\n");
9709 const MockWrite kGetAuth(
9710 "GET / HTTP/1.1\r\n"
9711 "Host: www.example.com\r\n"
9712 "Connection: keep-alive\r\n"
9713 "Authorization: auth_token\r\n\r\n");
9714
9715 const MockRead kServerChallenge(
9716 "HTTP/1.1 401 Unauthorized\r\n"
9717 "WWW-Authenticate: Mock realm=server\r\n"
9718 "Content-Type: text/html; charset=iso-8859-1\r\n"
9719 "Content-Length: 14\r\n\r\n"
9720 "Unauthorized\r\n");
9721 const MockRead kSuccess(
9722 "HTTP/1.1 200 OK\r\n"
9723 "Content-Type: text/html; charset=iso-8859-1\r\n"
9724 "Content-Length: 3\r\n\r\n"
9725 "Yes");
9726
9727 MockWrite writes[] = {
9728 // First round
9729 kGet,
9730 // Second round
9731 kGetAuth,
9732 // Third round
9733 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309734 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109735 kGetAuth,
9736 // Competing request
9737 kGet,
[email protected]c871bce92010-07-15 21:51:149738 };
9739 MockRead reads[] = {
9740 // First round
9741 kServerChallenge,
9742 // Second round
9743 kServerChallenge,
9744 // Third round
[email protected]eca50e122010-09-11 14:03:309745 kServerChallenge,
9746 // Fourth round
[email protected]c871bce92010-07-15 21:51:149747 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109748 // Competing response
9749 kSuccess,
[email protected]c871bce92010-07-15 21:51:149750 };
9751 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9752 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079753 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149754
[email protected]7ef4cbbb2011-02-06 11:19:109755 const char* const kSocketGroup = "www.example.com:80";
9756
9757 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149758 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419759 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149760 if (rv == ERR_IO_PENDING)
9761 rv = callback.WaitForResult();
9762 EXPECT_EQ(OK, rv);
9763 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509764 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149765 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289766 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149767
[email protected]7ef4cbbb2011-02-06 11:19:109768 // In between rounds, another request comes in for the same domain.
9769 // It should not be able to grab the TCP socket that trans has already
9770 // claimed.
9771 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509772 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419773 TestCompletionCallback callback_compete;
9774 rv = trans_compete->Start(
9775 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109776 EXPECT_EQ(ERR_IO_PENDING, rv);
9777 // callback_compete.WaitForResult at this point would stall forever,
9778 // since the HttpNetworkTransaction does not release the request back to
9779 // the pool until after authentication completes.
9780
9781 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149782 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419783 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149784 if (rv == ERR_IO_PENDING)
9785 rv = callback.WaitForResult();
9786 EXPECT_EQ(OK, rv);
9787 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509788 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149789 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289790 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149791
[email protected]7ef4cbbb2011-02-06 11:19:109792 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149793 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419794 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149795 if (rv == ERR_IO_PENDING)
9796 rv = callback.WaitForResult();
9797 EXPECT_EQ(OK, rv);
9798 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509799 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149800 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289801 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309802
[email protected]7ef4cbbb2011-02-06 11:19:109803 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309804 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419805 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309806 if (rv == ERR_IO_PENDING)
9807 rv = callback.WaitForResult();
9808 EXPECT_EQ(OK, rv);
9809 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509810 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309811 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289812 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109813
9814 // Read the body since the fourth round was successful. This will also
9815 // release the socket back to the pool.
9816 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509817 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109818 if (rv == ERR_IO_PENDING)
9819 rv = callback.WaitForResult();
9820 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509821 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109822 EXPECT_EQ(0, rv);
9823 // There are still 0 idle sockets, since the trans_compete transaction
9824 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289825 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109826
9827 // The competing request can now finish. Wait for the headers and then
9828 // read the body.
9829 rv = callback_compete.WaitForResult();
9830 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509831 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109832 if (rv == ERR_IO_PENDING)
9833 rv = callback.WaitForResult();
9834 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509835 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109836 EXPECT_EQ(0, rv);
9837
9838 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289839 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149840}
9841
[email protected]65041fa2010-05-21 06:56:539842// This tests the case that a request is issued via http instead of spdy after
9843// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029844TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389845 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]0ce3af82013-07-22 16:17:169846 std::vector<NextProto> next_protos;
9847 next_protos.push_back(kProtoHTTP11);
9848 HttpStreamFactory::SetNextProtos(next_protos);
[email protected]65041fa2010-05-21 06:56:539849 HttpRequestInfo request;
9850 request.method = "GET";
9851 request.url = GURL("https://www.google.com/");
9852 request.load_flags = 0;
9853
9854 MockWrite data_writes[] = {
9855 MockWrite("GET / HTTP/1.1\r\n"
9856 "Host: www.google.com\r\n"
9857 "Connection: keep-alive\r\n\r\n"),
9858 };
9859
[email protected]8a0fc822013-06-27 20:52:439860 std::string alternate_protocol_http_header =
9861 GetAlternateProtocolHttpHeader();
9862
[email protected]65041fa2010-05-21 06:56:539863 MockRead data_reads[] = {
9864 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439865 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539866 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069867 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539868 };
9869
[email protected]8ddf8322012-02-23 18:08:069870 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539871 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9872 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469873 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539874
[email protected]bb88e1d32013-05-03 23:11:079875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539876
9877 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9878 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079879 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539880
[email protected]49639fa2011-12-20 23:22:419881 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539882
[email protected]bb88e1d32013-05-03 23:11:079883 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369884 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539886
[email protected]49639fa2011-12-20 23:22:419887 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539888
9889 EXPECT_EQ(ERR_IO_PENDING, rv);
9890 EXPECT_EQ(OK, callback.WaitForResult());
9891
9892 const HttpResponseInfo* response = trans->GetResponseInfo();
9893 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509894 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539895 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9896
9897 std::string response_data;
9898 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9899 EXPECT_EQ("hello world", response_data);
9900
9901 EXPECT_FALSE(response->was_fetched_via_spdy);
9902 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539903}
[email protected]26ef6582010-06-24 02:30:479904
[email protected]23e482282013-06-14 16:08:029905TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479906 // Simulate the SSL handshake completing with an NPN negotiation
9907 // followed by an immediate server closing of the socket.
9908 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389909 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039910 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479911
9912 HttpRequestInfo request;
9913 request.method = "GET";
9914 request.url = GURL("https://www.google.com/");
9915 request.load_flags = 0;
9916
[email protected]8ddf8322012-02-23 18:08:069917 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029918 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079919 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479920
[email protected]cdf8f7e72013-05-23 10:56:469921 scoped_ptr<SpdyFrame> req(
9922 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139923 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479924
9925 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069926 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479927 };
9928
[email protected]dd54bd82012-07-19 23:44:579929 DelayedSocketData spdy_data(
9930 0, // don't wait in this case, immediate hangup.
9931 spdy_reads, arraysize(spdy_reads),
9932 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079933 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479934
[email protected]49639fa2011-12-20 23:22:419935 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479936
[email protected]bb88e1d32013-05-03 23:11:079937 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369938 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509939 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479940
[email protected]49639fa2011-12-20 23:22:419941 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479942 EXPECT_EQ(ERR_IO_PENDING, rv);
9943 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479944}
[email protected]65d34382010-07-01 18:12:269945
[email protected]795cbf82013-07-22 09:37:279946// A subclass of HttpAuthHandlerMock that records the request URL when
9947// it gets it. This is needed since the auth handler may get destroyed
9948// before we get a chance to query it.
9949class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9950 public:
9951 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9952
9953 virtual ~UrlRecordingHttpAuthHandlerMock() {}
9954
9955 protected:
9956 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9957 const HttpRequestInfo* request,
9958 const CompletionCallback& callback,
9959 std::string* auth_token) OVERRIDE {
9960 *url_ = request->url;
9961 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9962 credentials, request, callback, auth_token);
9963 }
9964
9965 private:
9966 GURL* url_;
9967};
9968
[email protected]23e482282013-06-14 16:08:029969TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309970 // This test ensures that the URL passed into the proxy is upgraded
9971 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389972 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439973 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309974
[email protected]bb88e1d32013-05-03 23:11:079975 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209976 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9977 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079978 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:279979 GURL request_url;
9980 {
9981 HttpAuthHandlerMock::Factory* auth_factory =
9982 new HttpAuthHandlerMock::Factory();
9983 UrlRecordingHttpAuthHandlerMock* auth_handler =
9984 new UrlRecordingHttpAuthHandlerMock(&request_url);
9985 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9986 auth_factory->set_do_init_from_challenge(true);
9987 session_deps_.http_auth_handler_factory.reset(auth_factory);
9988 }
[email protected]f45c1ee2010-08-03 00:54:309989
9990 HttpRequestInfo request;
9991 request.method = "GET";
9992 request.url = GURL("http://www.google.com");
9993 request.load_flags = 0;
9994
9995 // First round goes unauthenticated through the proxy.
9996 MockWrite data_writes_1[] = {
9997 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9998 "Host: www.google.com\r\n"
9999 "Proxy-Connection: keep-alive\r\n"
10000 "\r\n"),
10001 };
10002 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610003 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:3010004 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:2310005 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:3010006 "Proxy-Connection: close\r\n"
10007 "\r\n"),
10008 };
10009 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10010 data_writes_1, arraysize(data_writes_1));
10011
10012 // Second round tries to tunnel to www.google.com due to the
10013 // Alternate-Protocol announcement in the first round. It fails due
10014 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:5910015 // After the failure, a tunnel is established to www.google.com using
10016 // Proxy-Authorization headers. There is then a SPDY request round.
10017 //
[email protected]fe3b7dc2012-02-03 19:52:0910018 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10019 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10020 // does a Disconnect and Connect on the same socket, rather than trying
10021 // to obtain a new one.
10022 //
[email protected]394816e92010-08-03 07:38:5910023 // NOTE: Originally, the proxy response to the second CONNECT request
10024 // simply returned another 407 so the unit test could skip the SSL connection
10025 // establishment and SPDY framing issues. Alas, the
10026 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010027 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910028
[email protected]cdf8f7e72013-05-23 10:56:4610029 scoped_ptr<SpdyFrame> req(
10030 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210031 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10032 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010033
[email protected]394816e92010-08-03 07:38:5910034 MockWrite data_writes_2[] = {
10035 // First connection attempt without Proxy-Authorization.
10036 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10037 "Host: www.google.com\r\n"
10038 "Proxy-Connection: keep-alive\r\n"
10039 "\r\n"),
10040
10041 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:3010042 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10043 "Host: www.google.com\r\n"
10044 "Proxy-Connection: keep-alive\r\n"
10045 "Proxy-Authorization: auth_token\r\n"
10046 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010047
[email protected]394816e92010-08-03 07:38:5910048 // SPDY request
10049 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:3010050 };
[email protected]394816e92010-08-03 07:38:5910051 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10052 "Proxy-Authenticate: Mock\r\n"
10053 "Proxy-Connection: close\r\n"
10054 "\r\n");
10055 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10056 MockRead data_reads_2[] = {
10057 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:0610058 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10059 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:5910060 arraysize(kRejectConnectResponse) - 1, 1),
10061
10062 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:0610063 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:0910064 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:5910065
10066 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:0910067 CreateMockRead(*resp.get(), 6),
10068 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:0610069 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:5910070 };
[email protected]dd54bd82012-07-19 23:44:5710071 OrderedSocketData data_2(
10072 data_reads_2, arraysize(data_reads_2),
10073 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010074
[email protected]8ddf8322012-02-23 18:08:0610075 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210076 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:3010077
[email protected]d973e99a2012-02-17 21:02:3610078 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510079 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10080 NULL, 0, NULL, 0);
10081 hanging_non_alternate_protocol_socket.set_connect_data(
10082 never_finishing_connect);
10083
[email protected]bb88e1d32013-05-03 23:11:0710084 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10085 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10087 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510088 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710089 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010090
10091 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110092 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610093 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010094 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110095 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010096 EXPECT_EQ(ERR_IO_PENDING, rv);
10097 EXPECT_EQ(OK, callback_1.WaitForResult());
10098
10099 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110100 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610101 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010102 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110103 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010104 EXPECT_EQ(ERR_IO_PENDING, rv);
10105 EXPECT_EQ(OK, callback_2.WaitForResult());
10106 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010107 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010108 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10109
10110 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110111 TestCompletionCallback callback_3;
10112 rv = trans_2->RestartWithAuth(
10113 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010114 EXPECT_EQ(ERR_IO_PENDING, rv);
10115 EXPECT_EQ(OK, callback_3.WaitForResult());
10116
10117 // After all that work, these two lines (or actually, just the scheme) are
10118 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010119 EXPECT_EQ("https", request_url.scheme());
10120 EXPECT_EQ("www.google.com", request_url.host());
10121
[email protected]029c83b62013-01-24 05:28:2010122 LoadTimingInfo load_timing_info;
10123 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10124 TestLoadTimingNotReusedWithPac(load_timing_info,
10125 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810126}
10127
10128// Test that if we cancel the transaction as the connection is completing, that
10129// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210130TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810131 // Setup everything about the connection to complete synchronously, so that
10132 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10133 // for is the callback from the HttpStreamRequest.
10134 // Then cancel the transaction.
10135 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610136 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810137 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610138 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10139 MockRead(SYNCHRONOUS, "hello world"),
10140 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810141 };
10142
[email protected]8e6441ca2010-08-19 05:56:3810143 HttpRequestInfo request;
10144 request.method = "GET";
10145 request.url = GURL("http://www.google.com/");
10146 request.load_flags = 0;
10147
[email protected]bb88e1d32013-05-03 23:11:0710148 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710149 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710150 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0710151 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:2710152
[email protected]8e6441ca2010-08-19 05:56:3810153 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10154 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710155 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810156
[email protected]49639fa2011-12-20 23:22:4110157 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810158
[email protected]333bdf62012-06-08 22:57:2910159 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:4110160 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810161 EXPECT_EQ(ERR_IO_PENDING, rv);
10162 trans.reset(); // Cancel the transaction here.
10163
[email protected]2da659e2013-05-23 20:51:3410164 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010165}
10166
[email protected]76a505b2010-08-25 06:23:0010167// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210168TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710169 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010170 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910171 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710172 session_deps_.net_log = log.bound().net_log();
10173 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010174
[email protected]76a505b2010-08-25 06:23:0010175 HttpRequestInfo request;
10176 request.method = "GET";
10177 request.url = GURL("http://www.google.com/");
10178
10179 MockWrite data_writes1[] = {
10180 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10181 "Host: www.google.com\r\n"
10182 "Proxy-Connection: keep-alive\r\n\r\n"),
10183 };
10184
10185 MockRead data_reads1[] = {
10186 MockRead("HTTP/1.1 200 OK\r\n"),
10187 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10188 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610189 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010190 };
10191
10192 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10193 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710194 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010195
[email protected]49639fa2011-12-20 23:22:4110196 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010197
[email protected]262eec82013-03-19 21:01:3610198 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010200
[email protected]49639fa2011-12-20 23:22:4110201 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010202 EXPECT_EQ(ERR_IO_PENDING, rv);
10203
10204 rv = callback1.WaitForResult();
10205 EXPECT_EQ(OK, rv);
10206
10207 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010208 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010209
10210 EXPECT_TRUE(response->headers->IsKeepAlive());
10211 EXPECT_EQ(200, response->headers->response_code());
10212 EXPECT_EQ(100, response->headers->GetContentLength());
10213 EXPECT_TRUE(response->was_fetched_via_proxy);
10214 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010215
10216 LoadTimingInfo load_timing_info;
10217 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10218 TestLoadTimingNotReusedWithPac(load_timing_info,
10219 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010220}
10221
10222// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210223TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710224 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010225 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910226 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710227 session_deps_.net_log = log.bound().net_log();
10228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010229
[email protected]76a505b2010-08-25 06:23:0010230 HttpRequestInfo request;
10231 request.method = "GET";
10232 request.url = GURL("https://www.google.com/");
10233
10234 // Since we have proxy, should try to establish tunnel.
10235 MockWrite data_writes1[] = {
10236 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10237 "Host: www.google.com\r\n"
10238 "Proxy-Connection: keep-alive\r\n\r\n"),
10239
10240 MockWrite("GET / HTTP/1.1\r\n"
10241 "Host: www.google.com\r\n"
10242 "Connection: keep-alive\r\n\r\n"),
10243 };
10244
10245 MockRead data_reads1[] = {
10246 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10247
10248 MockRead("HTTP/1.1 200 OK\r\n"),
10249 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10250 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610251 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010252 };
10253
10254 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10255 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710256 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610257 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010259
[email protected]49639fa2011-12-20 23:22:4110260 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010261
[email protected]262eec82013-03-19 21:01:3610262 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010263 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010264
[email protected]49639fa2011-12-20 23:22:4110265 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010266 EXPECT_EQ(ERR_IO_PENDING, rv);
10267
10268 rv = callback1.WaitForResult();
10269 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710270 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010271 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010272 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010273 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010274 NetLog::PHASE_NONE);
10275 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010276 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010277 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10278 NetLog::PHASE_NONE);
10279
10280 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010281 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010282
10283 EXPECT_TRUE(response->headers->IsKeepAlive());
10284 EXPECT_EQ(200, response->headers->response_code());
10285 EXPECT_EQ(100, response->headers->GetContentLength());
10286 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10287 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:2010288
10289 LoadTimingInfo load_timing_info;
10290 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10291 TestLoadTimingNotReusedWithPac(load_timing_info,
10292 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010293}
10294
10295// Test a basic HTTPS GET request through a proxy, but the server hangs up
10296// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210297TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710298 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910299 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710300 session_deps_.net_log = log.bound().net_log();
10301 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010302
[email protected]76a505b2010-08-25 06:23:0010303 HttpRequestInfo request;
10304 request.method = "GET";
10305 request.url = GURL("https://www.google.com/");
10306
10307 // Since we have proxy, should try to establish tunnel.
10308 MockWrite data_writes1[] = {
10309 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10310 "Host: www.google.com\r\n"
10311 "Proxy-Connection: keep-alive\r\n\r\n"),
10312
10313 MockWrite("GET / HTTP/1.1\r\n"
10314 "Host: www.google.com\r\n"
10315 "Connection: keep-alive\r\n\r\n"),
10316 };
10317
10318 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610319 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010320 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610321 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010322 };
10323
10324 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10325 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710326 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610327 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710328 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010329
[email protected]49639fa2011-12-20 23:22:4110330 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010331
[email protected]262eec82013-03-19 21:01:3610332 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010334
[email protected]49639fa2011-12-20 23:22:4110335 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010336 EXPECT_EQ(ERR_IO_PENDING, rv);
10337
10338 rv = callback1.WaitForResult();
10339 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710340 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010341 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010342 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010343 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010344 NetLog::PHASE_NONE);
10345 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010346 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010347 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10348 NetLog::PHASE_NONE);
10349}
10350
[email protected]749eefa82010-09-13 22:14:0310351// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210352TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610353 scoped_ptr<SpdyFrame> req(
10354 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310355 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10356
[email protected]23e482282013-06-14 16:08:0210357 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10358 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310359 MockRead spdy_reads[] = {
10360 CreateMockRead(*resp),
10361 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610362 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310363 };
10364
[email protected]dd54bd82012-07-19 23:44:5710365 DelayedSocketData spdy_data(
10366 1, // wait for one write to finish before reading.
10367 spdy_reads, arraysize(spdy_reads),
10368 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710369 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310370
[email protected]8ddf8322012-02-23 18:08:0610371 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210372 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710373 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310374
[email protected]bb88e1d32013-05-03 23:11:0710375 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310376
10377 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810378 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010379 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10380 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:2710381 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610382 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310383
10384 HttpRequestInfo request;
10385 request.method = "GET";
10386 request.url = GURL("https://www.google.com/");
10387 request.load_flags = 0;
10388
10389 // This is the important line that marks this as a preconnect.
10390 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10391
[email protected]262eec82013-03-19 21:01:3610392 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010393 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310394
[email protected]41d64e82013-07-03 22:44:2610395 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110396 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310397 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110398 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310399}
10400
[email protected]73b8dd222010-11-11 19:55:2410401// Given a net error, cause that error to be returned from the first Write()
10402// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210403void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710404 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710405 net::HttpRequestInfo request_info;
10406 request_info.url = GURL("https://www.example.com/");
10407 request_info.method = "GET";
10408 request_info.load_flags = net::LOAD_NORMAL;
10409
[email protected]8ddf8322012-02-23 18:08:0610410 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410411 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610412 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410413 };
10414 net::StaticSocketDataProvider data(NULL, 0,
10415 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710416 session_deps_.socket_factory->AddSocketDataProvider(&data);
10417 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410418
[email protected]bb88e1d32013-05-03 23:11:0710419 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610420 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010421 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410422
[email protected]49639fa2011-12-20 23:22:4110423 TestCompletionCallback callback;
10424 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410425 if (rv == net::ERR_IO_PENDING)
10426 rv = callback.WaitForResult();
10427 ASSERT_EQ(error, rv);
10428}
10429
[email protected]23e482282013-06-14 16:08:0210430TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410431 // Just check a grab bag of cert errors.
10432 static const int kErrors[] = {
10433 ERR_CERT_COMMON_NAME_INVALID,
10434 ERR_CERT_AUTHORITY_INVALID,
10435 ERR_CERT_DATE_INVALID,
10436 };
10437 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610438 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10439 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410440 }
10441}
10442
[email protected]bd0b6772011-01-11 19:59:3010443// Ensure that a client certificate is removed from the SSL client auth
10444// cache when:
10445// 1) No proxy is involved.
10446// 2) TLS False Start is disabled.
10447// 3) The initial TLS handshake requests a client certificate.
10448// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210449TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310450 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710451 net::HttpRequestInfo request_info;
10452 request_info.url = GURL("https://www.example.com/");
10453 request_info.method = "GET";
10454 request_info.load_flags = net::LOAD_NORMAL;
10455
[email protected]bd0b6772011-01-11 19:59:3010456 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110457 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010458
10459 // [ssl_]data1 contains the data for the first SSL handshake. When a
10460 // CertificateRequest is received for the first time, the handshake will
10461 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610462 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010463 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710464 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010465 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710466 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010467
10468 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10469 // False Start is not being used, the result of the SSL handshake will be
10470 // returned as part of the SSLClientSocket::Connect() call. This test
10471 // matches the result of a server sending a handshake_failure alert,
10472 // rather than a Finished message, because it requires a client
10473 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610474 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010475 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010477 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710478 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010479
10480 // [ssl_]data3 contains the data for the third SSL handshake. When a
10481 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710482 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10483 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010484 // of the HttpNetworkTransaction. Because this test failure is due to
10485 // requiring a client certificate, this fallback handshake should also
10486 // fail.
[email protected]8ddf8322012-02-23 18:08:0610487 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010488 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710489 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010490 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710491 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010492
[email protected]80c75f682012-05-26 16:22:1710493 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10494 // connection to a server fails during an SSL handshake,
10495 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10496 // connection was attempted with TLSv1. This is transparent to the caller
10497 // of the HttpNetworkTransaction. Because this test failure is due to
10498 // requiring a client certificate, this fallback handshake should also
10499 // fail.
10500 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10501 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710503 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710504 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710505
[email protected]7799de12013-05-30 05:52:5110506 // Need one more if TLSv1.2 is enabled.
10507 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10508 ssl_data5.cert_request_info = cert_request.get();
10509 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10510 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10511 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10512
[email protected]bb88e1d32013-05-03 23:11:0710513 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610514 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010515 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010516
[email protected]bd0b6772011-01-11 19:59:3010517 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110518 TestCompletionCallback callback;
10519 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010520 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10521
10522 // Complete the SSL handshake, which should abort due to requiring a
10523 // client certificate.
10524 rv = callback.WaitForResult();
10525 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10526
10527 // Indicate that no certificate should be supplied. From the perspective
10528 // of SSLClientCertCache, NULL is just as meaningful as a real
10529 // certificate, so this is the same as supply a
10530 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110531 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010532 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10533
10534 // Ensure the certificate was added to the client auth cache before
10535 // allowing the connection to continue restarting.
10536 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110537 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10538 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010539 ASSERT_EQ(NULL, client_cert.get());
10540
10541 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710542 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10543 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010544 rv = callback.WaitForResult();
10545 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10546
10547 // Ensure that the client certificate is removed from the cache on a
10548 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110549 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10550 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010551}
10552
10553// Ensure that a client certificate is removed from the SSL client auth
10554// cache when:
10555// 1) No proxy is involved.
10556// 2) TLS False Start is enabled.
10557// 3) The initial TLS handshake requests a client certificate.
10558// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210559TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310560 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710561 net::HttpRequestInfo request_info;
10562 request_info.url = GURL("https://www.example.com/");
10563 request_info.method = "GET";
10564 request_info.load_flags = net::LOAD_NORMAL;
10565
[email protected]bd0b6772011-01-11 19:59:3010566 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110567 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010568
10569 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10570 // return successfully after reading up to the peer's Certificate message.
10571 // This is to allow the caller to call SSLClientSocket::Write(), which can
10572 // enqueue application data to be sent in the same packet as the
10573 // ChangeCipherSpec and Finished messages.
10574 // The actual handshake will be finished when SSLClientSocket::Read() is
10575 // called, which expects to process the peer's ChangeCipherSpec and
10576 // Finished messages. If there was an error negotiating with the peer,
10577 // such as due to the peer requiring a client certificate when none was
10578 // supplied, the alert sent by the peer won't be processed until Read() is
10579 // called.
10580
10581 // Like the non-False Start case, when a client certificate is requested by
10582 // the peer, the handshake is aborted during the Connect() call.
10583 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610584 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010585 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710586 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010587 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710588 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010589
10590 // When a client certificate is supplied, Connect() will not be aborted
10591 // when the peer requests the certificate. Instead, the handshake will
10592 // artificially succeed, allowing the caller to write the HTTP request to
10593 // the socket. The handshake messages are not processed until Read() is
10594 // called, which then detects that the handshake was aborted, due to the
10595 // peer sending a handshake_failure because it requires a client
10596 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610597 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010598 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710599 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010600 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610601 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010602 };
10603 net::StaticSocketDataProvider data2(
10604 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710605 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010606
10607 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710608 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10609 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610610 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010611 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010613 net::StaticSocketDataProvider data3(
10614 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710615 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010616
[email protected]80c75f682012-05-26 16:22:1710617 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10618 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10619 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10620 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710621 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710622 net::StaticSocketDataProvider data4(
10623 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710624 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710625
[email protected]7799de12013-05-30 05:52:5110626 // Need one more if TLSv1.2 is enabled.
10627 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10628 ssl_data5.cert_request_info = cert_request.get();
10629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10630 net::StaticSocketDataProvider data5(
10631 data2_reads, arraysize(data2_reads), NULL, 0);
10632 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10633
[email protected]bb88e1d32013-05-03 23:11:0710634 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610635 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010637
[email protected]bd0b6772011-01-11 19:59:3010638 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110639 TestCompletionCallback callback;
10640 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010641 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10642
10643 // Complete the SSL handshake, which should abort due to requiring a
10644 // client certificate.
10645 rv = callback.WaitForResult();
10646 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10647
10648 // Indicate that no certificate should be supplied. From the perspective
10649 // of SSLClientCertCache, NULL is just as meaningful as a real
10650 // certificate, so this is the same as supply a
10651 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110652 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010653 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10654
10655 // Ensure the certificate was added to the client auth cache before
10656 // allowing the connection to continue restarting.
10657 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110658 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10659 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010660 ASSERT_EQ(NULL, client_cert.get());
10661
[email protected]bd0b6772011-01-11 19:59:3010662 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710663 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10664 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010665 rv = callback.WaitForResult();
10666 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10667
10668 // Ensure that the client certificate is removed from the cache on a
10669 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110670 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10671 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010672}
10673
[email protected]8c405132011-01-11 22:03:1810674// Ensure that a client certificate is removed from the SSL client auth
10675// cache when:
10676// 1) An HTTPS proxy is involved.
10677// 3) The HTTPS proxy requests a client certificate.
10678// 4) The client supplies an invalid/unacceptable certificate for the
10679// proxy.
10680// The test is repeated twice, first for connecting to an HTTPS endpoint,
10681// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210682TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710683 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810684 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910685 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710686 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810687
10688 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110689 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1810690
10691 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10692 // [ssl_]data[1-3]. Rather than represending the endpoint
10693 // (www.example.com:443), they represent failures with the HTTPS proxy
10694 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610695 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810696 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710697 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810698 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710699 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810700
[email protected]8ddf8322012-02-23 18:08:0610701 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810702 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710703 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810704 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710705 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810706
[email protected]80c75f682012-05-26 16:22:1710707 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10708#if 0
[email protected]8ddf8322012-02-23 18:08:0610709 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810710 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710711 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810712 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710713 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710714#endif
[email protected]8c405132011-01-11 22:03:1810715
10716 net::HttpRequestInfo requests[2];
10717 requests[0].url = GURL("https://www.example.com/");
10718 requests[0].method = "GET";
10719 requests[0].load_flags = net::LOAD_NORMAL;
10720
10721 requests[1].url = GURL("http://www.example.com/");
10722 requests[1].method = "GET";
10723 requests[1].load_flags = net::LOAD_NORMAL;
10724
10725 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710726 session_deps_.socket_factory->ResetNextMockIndexes();
10727 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810728 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010729 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810730
10731 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110732 TestCompletionCallback callback;
10733 int rv = trans->Start(
10734 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810735 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10736
10737 // Complete the SSL handshake, which should abort due to requiring a
10738 // client certificate.
10739 rv = callback.WaitForResult();
10740 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10741
10742 // Indicate that no certificate should be supplied. From the perspective
10743 // of SSLClientCertCache, NULL is just as meaningful as a real
10744 // certificate, so this is the same as supply a
10745 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110746 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810747 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10748
10749 // Ensure the certificate was added to the client auth cache before
10750 // allowing the connection to continue restarting.
10751 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110752 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10753 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1810754 ASSERT_EQ(NULL, client_cert.get());
10755 // Ensure the certificate was NOT cached for the endpoint. This only
10756 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4110757 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10758 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810759
10760 // Restart the handshake. This will consume ssl_data2, which fails, and
10761 // then consume ssl_data3, which should also fail. The result code is
10762 // checked against what ssl_data3 should return.
10763 rv = callback.WaitForResult();
10764 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10765
10766 // Now that the new handshake has failed, ensure that the client
10767 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4110768 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10769 HostPortPair("proxy", 70), &client_cert));
10770 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10771 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810772 }
10773}
10774
[email protected]23e482282013-06-14 16:08:0210775// Unlike TEST/TEST_F, which are macros that expand to further macros,
10776// TEST_P is a macro that expands directly to code that stringizes the
10777// arguments. As a result, macros passed as parameters (such as prefix
10778// or test_case_name) will not be expanded by the preprocessor. To
10779// work around this, indirect the macro for TEST_P, so that the
10780// pre-processor will expand macros such as MAYBE_test_name before
10781// instantiating the test.
10782#define WRAPPED_TEST_P(test_case_name, test_name) \
10783 TEST_P(test_case_name, test_name)
10784
[email protected]45b170822012-05-04 21:18:1410785// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10786#if defined(OS_WIN)
10787#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10788#else
10789#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10790#endif
[email protected]23e482282013-06-14 16:08:0210791WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610792 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310793 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610794
10795 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710796 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10797 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610798 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10799 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610800
[email protected]8ddf8322012-02-23 18:08:0610801 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210802 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710803 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610804
[email protected]cdf8f7e72013-05-23 10:56:4610805 scoped_ptr<SpdyFrame> host1_req(
10806 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10807 scoped_ptr<SpdyFrame> host2_req(
10808 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610809 MockWrite spdy_writes[] = {
10810 CreateMockWrite(*host1_req, 1),
10811 CreateMockWrite(*host2_req, 4),
10812 };
[email protected]23e482282013-06-14 16:08:0210813 scoped_ptr<SpdyFrame> host1_resp(
10814 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10815 scoped_ptr<SpdyFrame> host1_resp_body(
10816 spdy_util_.ConstructSpdyBodyFrame(1, true));
10817 scoped_ptr<SpdyFrame> host2_resp(
10818 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10819 scoped_ptr<SpdyFrame> host2_resp_body(
10820 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610821 MockRead spdy_reads[] = {
10822 CreateMockRead(*host1_resp, 2),
10823 CreateMockRead(*host1_resp_body, 3),
10824 CreateMockRead(*host2_resp, 5),
10825 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610826 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610827 };
10828
[email protected]d2b5f092012-06-08 23:55:0210829 IPAddressNumber ip;
10830 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10831 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10832 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710833 OrderedSocketData spdy_data(
10834 connect,
10835 spdy_reads, arraysize(spdy_reads),
10836 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710837 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610838
[email protected]aa22b242011-11-16 18:58:2910839 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610840 HttpRequestInfo request1;
10841 request1.method = "GET";
10842 request1.url = GURL("https://www.google.com/");
10843 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010844 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610845
[email protected]49639fa2011-12-20 23:22:4110846 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610847 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110848 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610849
10850 const HttpResponseInfo* response = trans1.GetResponseInfo();
10851 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010852 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610853 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10854
10855 std::string response_data;
10856 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10857 EXPECT_EQ("hello!", response_data);
10858
10859 // Preload www.gmail.com into HostCache.
10860 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1010861 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4610862 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010863 rv = session_deps_.host_resolver->Resolve(resolve_info,
10864 DEFAULT_PRIORITY,
10865 &ignored,
10866 callback.callback(),
10867 NULL,
10868 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710869 EXPECT_EQ(ERR_IO_PENDING, rv);
10870 rv = callback.WaitForResult();
10871 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610872
10873 HttpRequestInfo request2;
10874 request2.method = "GET";
10875 request2.url = GURL("https://www.gmail.com/");
10876 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010877 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610878
[email protected]49639fa2011-12-20 23:22:4110879 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610880 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110881 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610882
10883 response = trans2.GetResponseInfo();
10884 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010885 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610886 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10887 EXPECT_TRUE(response->was_fetched_via_spdy);
10888 EXPECT_TRUE(response->was_npn_negotiated);
10889 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10890 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610891}
[email protected]45b170822012-05-04 21:18:1410892#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610893
[email protected]23e482282013-06-14 16:08:0210894TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210895 HttpStreamFactory::set_use_alternate_protocols(true);
10896 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10897
10898 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710899 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10900 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210901 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10902 pool_peer.DisableDomainAuthenticationVerification();
10903
10904 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210905 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710906 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210907
[email protected]cdf8f7e72013-05-23 10:56:4610908 scoped_ptr<SpdyFrame> host1_req(
10909 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10910 scoped_ptr<SpdyFrame> host2_req(
10911 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210912 MockWrite spdy_writes[] = {
10913 CreateMockWrite(*host1_req, 1),
10914 CreateMockWrite(*host2_req, 4),
10915 };
[email protected]23e482282013-06-14 16:08:0210916 scoped_ptr<SpdyFrame> host1_resp(
10917 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10918 scoped_ptr<SpdyFrame> host1_resp_body(
10919 spdy_util_.ConstructSpdyBodyFrame(1, true));
10920 scoped_ptr<SpdyFrame> host2_resp(
10921 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10922 scoped_ptr<SpdyFrame> host2_resp_body(
10923 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210924 MockRead spdy_reads[] = {
10925 CreateMockRead(*host1_resp, 2),
10926 CreateMockRead(*host1_resp_body, 3),
10927 CreateMockRead(*host2_resp, 5),
10928 CreateMockRead(*host2_resp_body, 6),
10929 MockRead(ASYNC, 0, 7),
10930 };
10931
10932 IPAddressNumber ip;
10933 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10934 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10935 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710936 OrderedSocketData spdy_data(
10937 connect,
10938 spdy_reads, arraysize(spdy_reads),
10939 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710940 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210941
10942 TestCompletionCallback callback;
10943 HttpRequestInfo request1;
10944 request1.method = "GET";
10945 request1.url = GURL("https://www.google.com/");
10946 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010947 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210948
10949 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10950 EXPECT_EQ(ERR_IO_PENDING, rv);
10951 EXPECT_EQ(OK, callback.WaitForResult());
10952
10953 const HttpResponseInfo* response = trans1.GetResponseInfo();
10954 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010955 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210956 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10957
10958 std::string response_data;
10959 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10960 EXPECT_EQ("hello!", response_data);
10961
10962 HttpRequestInfo request2;
10963 request2.method = "GET";
10964 request2.url = GURL("https://www.gmail.com/");
10965 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010966 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210967
10968 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10969 EXPECT_EQ(ERR_IO_PENDING, rv);
10970 EXPECT_EQ(OK, callback.WaitForResult());
10971
10972 response = trans2.GetResponseInfo();
10973 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010974 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210975 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10976 EXPECT_TRUE(response->was_fetched_via_spdy);
10977 EXPECT_TRUE(response->was_npn_negotiated);
10978 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10979 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210980}
10981
[email protected]e3ceb682011-06-28 23:55:4610982class OneTimeCachingHostResolver : public net::HostResolver {
10983 public:
10984 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10985 : host_port_(host_port) {}
10986 virtual ~OneTimeCachingHostResolver() {}
10987
10988 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10989
10990 // HostResolver methods:
10991 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1010992 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4610993 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910994 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610995 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010996 const BoundNetLog& net_log) OVERRIDE {
10997 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1010998 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010999 }
11000
11001 virtual int ResolveFromCache(const RequestInfo& info,
11002 AddressList* addresses,
11003 const BoundNetLog& net_log) OVERRIDE {
11004 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11005 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911006 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611007 return rv;
11008 }
11009
[email protected]95a214c2011-08-04 21:50:4011010 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4611011 host_resolver_.CancelRequest(req);
11012 }
11013
[email protected]46da33be2011-07-19 21:58:0411014 MockCachingHostResolver* GetMockHostResolver() {
11015 return &host_resolver_;
11016 }
11017
[email protected]e3ceb682011-06-28 23:55:4611018 private:
11019 MockCachingHostResolver host_resolver_;
11020 const HostPortPair host_port_;
11021};
11022
[email protected]45b170822012-05-04 21:18:1411023// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11024#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711025#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11026 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411027#else
[email protected]bb88e1d32013-05-03 23:11:0711028#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11029 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411030#endif
[email protected]23e482282013-06-14 16:08:0211031WRAPPED_TEST_P(HttpNetworkTransactionTest,
11032 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211033// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11034// prefix doesn't work with parametrized tests).
11035#if defined(OS_WIN)
11036 return;
[email protected]88c7b4be2014-03-19 23:04:0111037#else
[email protected]e3ceb682011-06-28 23:55:4611038 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0311039 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4611040
11041 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611042 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411043 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711044 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611045 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711046 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611047 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11048 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611049
[email protected]8ddf8322012-02-23 18:08:0611050 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211051 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611053
[email protected]cdf8f7e72013-05-23 10:56:4611054 scoped_ptr<SpdyFrame> host1_req(
11055 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11056 scoped_ptr<SpdyFrame> host2_req(
11057 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611058 MockWrite spdy_writes[] = {
11059 CreateMockWrite(*host1_req, 1),
11060 CreateMockWrite(*host2_req, 4),
11061 };
[email protected]23e482282013-06-14 16:08:0211062 scoped_ptr<SpdyFrame> host1_resp(
11063 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11064 scoped_ptr<SpdyFrame> host1_resp_body(
11065 spdy_util_.ConstructSpdyBodyFrame(1, true));
11066 scoped_ptr<SpdyFrame> host2_resp(
11067 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11068 scoped_ptr<SpdyFrame> host2_resp_body(
11069 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611070 MockRead spdy_reads[] = {
11071 CreateMockRead(*host1_resp, 2),
11072 CreateMockRead(*host1_resp_body, 3),
11073 CreateMockRead(*host2_resp, 5),
11074 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611075 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611076 };
11077
[email protected]d2b5f092012-06-08 23:55:0211078 IPAddressNumber ip;
11079 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11080 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11081 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711082 OrderedSocketData spdy_data(
11083 connect,
11084 spdy_reads, arraysize(spdy_reads),
11085 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711086 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611087
[email protected]aa22b242011-11-16 18:58:2911088 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611089 HttpRequestInfo request1;
11090 request1.method = "GET";
11091 request1.url = GURL("https://www.google.com/");
11092 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011093 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611094
[email protected]49639fa2011-12-20 23:22:4111095 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611096 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111097 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611098
11099 const HttpResponseInfo* response = trans1.GetResponseInfo();
11100 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011101 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611102 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11103
11104 std::string response_data;
11105 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11106 EXPECT_EQ("hello!", response_data);
11107
11108 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011109 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611110 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011111 rv = host_resolver.Resolve(resolve_info,
11112 DEFAULT_PRIORITY,
11113 &ignored,
11114 callback.callback(),
11115 NULL,
11116 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711117 EXPECT_EQ(ERR_IO_PENDING, rv);
11118 rv = callback.WaitForResult();
11119 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611120
11121 HttpRequestInfo request2;
11122 request2.method = "GET";
11123 request2.url = GURL("https://www.gmail.com/");
11124 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011125 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611126
[email protected]49639fa2011-12-20 23:22:4111127 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611128 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111129 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611130
11131 response = trans2.GetResponseInfo();
11132 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011133 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611134 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11135 EXPECT_TRUE(response->was_fetched_via_spdy);
11136 EXPECT_TRUE(response->was_npn_negotiated);
11137 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11138 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111139#endif
[email protected]e3ceb682011-06-28 23:55:4611140}
[email protected]45b170822012-05-04 21:18:1411141#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611142
[email protected]23e482282013-06-14 16:08:0211143TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2911144 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611145 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2911146 };
11147 MockRead data_reads2[] = {
11148 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11149 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611150 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2911151 };
11152 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
11153 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
11154 StaticSocketDataProvider* data[] = { &data1, &data2 };
11155
11156 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
11157
11158 EXPECT_EQ(OK, out.rv);
11159 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
11160 EXPECT_EQ("hello world", out.response_data);
11161}
11162
[email protected]23e482282013-06-14 16:08:0211163TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2911164 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0611165 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2911166 };
11167 MockWrite data_writes2[] = {
11168 MockWrite("GET / HTTP/1.1\r\n"
11169 "Host: www.google.com\r\n"
11170 "Connection: keep-alive\r\n\r\n"),
11171 };
11172 MockRead data_reads2[] = {
11173 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11174 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611175 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2911176 };
11177 StaticSocketDataProvider data1(NULL, 0,
11178 data_writes1, arraysize(data_writes1));
11179 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
11180 data_writes2, arraysize(data_writes2));
11181 StaticSocketDataProvider* data[] = { &data1, &data2 };
11182
11183 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
11184
11185 EXPECT_EQ(OK, out.rv);
11186 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
11187 EXPECT_EQ("hello world", out.response_data);
11188}
11189
[email protected]23e482282013-06-14 16:08:0211190TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0411191 const std::string https_url = "https://www.google.com/";
11192 const std::string http_url = "http://www.google.com:443/";
11193
11194 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611195 scoped_ptr<SpdyFrame> req1(
11196 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411197
11198 MockWrite writes1[] = {
11199 CreateMockWrite(*req1, 0),
11200 };
11201
[email protected]23e482282013-06-14 16:08:0211202 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11203 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411204 MockRead reads1[] = {
11205 CreateMockRead(*resp1, 1),
11206 CreateMockRead(*body1, 2),
11207 MockRead(ASYNC, ERR_IO_PENDING, 3)
11208 };
11209
[email protected]dd54bd82012-07-19 23:44:5711210 DelayedSocketData data1(
11211 1, reads1, arraysize(reads1),
11212 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411213 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711214 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411215
11216 // HTTP GET for the HTTP URL
11217 MockWrite writes2[] = {
11218 MockWrite(ASYNC, 4,
11219 "GET / HTTP/1.1\r\n"
11220 "Host: www.google.com:443\r\n"
11221 "Connection: keep-alive\r\n\r\n"),
11222 };
11223
11224 MockRead reads2[] = {
11225 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11226 MockRead(ASYNC, 6, "hello"),
11227 MockRead(ASYNC, 7, OK),
11228 };
11229
[email protected]dd54bd82012-07-19 23:44:5711230 DelayedSocketData data2(
11231 1, reads2, arraysize(reads2),
11232 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411233
[email protected]8450d722012-07-02 19:14:0411234 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211235 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711236 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11237 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11238 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411239
[email protected]bb88e1d32013-05-03 23:11:0711240 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411241
11242 // Start the first transaction to set up the SpdySession
11243 HttpRequestInfo request1;
11244 request1.method = "GET";
11245 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411246 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011247 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411248 TestCompletionCallback callback1;
11249 EXPECT_EQ(ERR_IO_PENDING,
11250 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411251 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411252
11253 EXPECT_EQ(OK, callback1.WaitForResult());
11254 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11255
11256 // Now, start the HTTP request
11257 HttpRequestInfo request2;
11258 request2.method = "GET";
11259 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411260 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011261 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411262 TestCompletionCallback callback2;
11263 EXPECT_EQ(ERR_IO_PENDING,
11264 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411265 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411266
11267 EXPECT_EQ(OK, callback2.WaitForResult());
11268 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11269}
11270
[email protected]23e482282013-06-14 16:08:0211271TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0411272 const std::string https_url = "https://www.google.com/";
11273 const std::string http_url = "http://www.google.com:443/";
11274
11275 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5411276 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11277 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611278 scoped_ptr<SpdyFrame> req1(
11279 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411280
11281 // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
[email protected]23e482282013-06-14 16:08:0211282 scoped_ptr<SpdyFrame> wrapped_req1(
11283 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]8450d722012-07-02 19:14:0411284 const char* const headers[] = {
[email protected]23e482282013-06-14 16:08:0211285 spdy_util_.GetMethodKey(), "GET",
11286 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
11287 spdy_util_.GetHostKey(), "www.google.com:443",
11288 spdy_util_.GetSchemeKey(), "http",
11289 spdy_util_.GetVersionKey(), "HTTP/1.1"
[email protected]8450d722012-07-02 19:14:0411290 };
[email protected]4bd46222013-05-14 19:32:2311291 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
11292 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
11293 headers, arraysize(headers), 0));
[email protected]8450d722012-07-02 19:14:0411294
11295 MockWrite writes1[] = {
11296 CreateMockWrite(*connect, 0),
11297 CreateMockWrite(*wrapped_req1, 2),
11298 CreateMockWrite(*req2, 5),
11299 };
11300
[email protected]23e482282013-06-14 16:08:0211301 scoped_ptr<SpdyFrame> conn_resp(
11302 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11303 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11304 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11305 scoped_ptr<SpdyFrame> wrapped_resp1(
11306 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11307 scoped_ptr<SpdyFrame> wrapped_body1(
11308 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11309 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11310 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411311 MockRead reads1[] = {
11312 CreateMockRead(*conn_resp, 1),
11313 CreateMockRead(*wrapped_resp1, 3),
11314 CreateMockRead(*wrapped_body1, 4),
11315 CreateMockRead(*resp2, 6),
11316 CreateMockRead(*body2, 7),
11317 MockRead(ASYNC, ERR_IO_PENDING, 8)
11318 };
11319
[email protected]dd54bd82012-07-19 23:44:5711320 DeterministicSocketData data1(reads1, arraysize(reads1),
11321 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411322 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711323 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411324
[email protected]bb88e1d32013-05-03 23:11:0711325 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211326 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11327 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711328 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411329 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211330 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711331 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411332 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211333 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711334 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11335 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411336
11337 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711338 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411339
11340 // Start the first transaction to set up the SpdySession
11341 HttpRequestInfo request1;
11342 request1.method = "GET";
11343 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411344 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011345 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411346 TestCompletionCallback callback1;
11347 EXPECT_EQ(ERR_IO_PENDING,
11348 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411349 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711350 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411351
11352 EXPECT_EQ(OK, callback1.WaitForResult());
11353 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11354
[email protected]f6c63db52013-02-02 00:35:2211355 LoadTimingInfo load_timing_info1;
11356 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11357 TestLoadTimingNotReusedWithPac(load_timing_info1,
11358 CONNECT_TIMING_HAS_SSL_TIMES);
11359
[email protected]8450d722012-07-02 19:14:0411360 // Now, start the HTTP request
11361 HttpRequestInfo request2;
11362 request2.method = "GET";
11363 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411364 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011365 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411366 TestCompletionCallback callback2;
11367 EXPECT_EQ(ERR_IO_PENDING,
11368 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411369 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711370 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411371
11372 EXPECT_EQ(OK, callback2.WaitForResult());
11373 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211374
11375 LoadTimingInfo load_timing_info2;
11376 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11377 // The established SPDY sessions is considered reused by the HTTP request.
11378 TestLoadTimingReusedWithPac(load_timing_info2);
11379 // HTTP requests over a SPDY session should have a different connection
11380 // socket_log_id than requests over a tunnel.
11381 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411382}
11383
[email protected]23e482282013-06-14 16:08:0211384TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0411385 HttpStreamFactory::set_force_spdy_always(true);
11386 const std::string https_url = "https://www.google.com/";
11387 const std::string http_url = "http://www.google.com:443/";
11388
11389 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611390 scoped_ptr<SpdyFrame> req1(
11391 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411392 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611393 scoped_ptr<SpdyFrame> req2(
11394 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411395
11396 MockWrite writes[] = {
11397 CreateMockWrite(*req1, 1),
11398 CreateMockWrite(*req2, 4),
11399 };
11400
[email protected]23e482282013-06-14 16:08:0211401 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11402 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11403 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11404 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411405 MockRead reads[] = {
11406 CreateMockRead(*resp1, 2),
11407 CreateMockRead(*body1, 3),
11408 CreateMockRead(*resp2, 5),
11409 CreateMockRead(*body2, 6),
11410 MockRead(ASYNC, ERR_IO_PENDING, 7)
11411 };
11412
[email protected]dd54bd82012-07-19 23:44:5711413 OrderedSocketData data(reads, arraysize(reads),
11414 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411415
[email protected]8450d722012-07-02 19:14:0411416 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211417 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11419 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411420
[email protected]bb88e1d32013-05-03 23:11:0711421 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411422
11423 // Start the first transaction to set up the SpdySession
11424 HttpRequestInfo request1;
11425 request1.method = "GET";
11426 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411427 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011428 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411429 TestCompletionCallback callback1;
11430 EXPECT_EQ(ERR_IO_PENDING,
11431 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411432 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411433
11434 EXPECT_EQ(OK, callback1.WaitForResult());
11435 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11436
11437 // Now, start the HTTP request
11438 HttpRequestInfo request2;
11439 request2.method = "GET";
11440 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411441 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011442 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411443 TestCompletionCallback callback2;
11444 EXPECT_EQ(ERR_IO_PENDING,
11445 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411446 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411447
11448 EXPECT_EQ(OK, callback2.WaitForResult());
11449 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11450}
11451
[email protected]2d88e7d2012-07-19 17:55:1711452// Test that in the case where we have a SPDY session to a SPDY proxy
11453// that we do not pool other origins that resolve to the same IP when
11454// the certificate does not match the new origin.
11455// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211456TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711457 const std::string url1 = "http://www.google.com/";
11458 const std::string url2 = "https://mail.google.com/";
11459 const std::string ip_addr = "1.2.3.4";
11460
11461 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211462 scoped_ptr<SpdyHeaderBlock> headers(
11463 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311464 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211465 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711466
11467 MockWrite writes1[] = {
11468 CreateMockWrite(*req1, 0),
11469 };
11470
[email protected]23e482282013-06-14 16:08:0211471 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11472 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711473 MockRead reads1[] = {
11474 CreateMockRead(*resp1, 1),
11475 CreateMockRead(*body1, 2),
11476 MockRead(ASYNC, OK, 3) // EOF
11477 };
11478
11479 scoped_ptr<DeterministicSocketData> data1(
11480 new DeterministicSocketData(reads1, arraysize(reads1),
11481 writes1, arraysize(writes1)));
11482 IPAddressNumber ip;
11483 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11484 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11485 MockConnect connect_data1(ASYNC, OK, peer_addr);
11486 data1->set_connect_data(connect_data1);
11487
11488 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611489 scoped_ptr<SpdyFrame> req2(
11490 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711491
11492 MockWrite writes2[] = {
11493 CreateMockWrite(*req2, 0),
11494 };
11495
[email protected]23e482282013-06-14 16:08:0211496 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11497 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711498 MockRead reads2[] = {
11499 CreateMockRead(*resp2, 1),
11500 CreateMockRead(*body2, 2),
11501 MockRead(ASYNC, OK, 3) // EOF
11502 };
11503
11504 scoped_ptr<DeterministicSocketData> data2(
11505 new DeterministicSocketData(reads2, arraysize(reads2),
11506 writes2, arraysize(writes2)));
11507 MockConnect connect_data2(ASYNC, OK);
11508 data2->set_connect_data(connect_data2);
11509
11510 // Set up a proxy config that sends HTTP requests to a proxy, and
11511 // all others direct.
11512 ProxyConfig proxy_config;
11513 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11514 CapturingProxyResolver* capturing_proxy_resolver =
11515 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711516 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711517 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11518 NULL));
11519
11520 // Load a valid cert. Note, that this does not need to
11521 // be valid for proxy because the MockSSLClientSocket does
11522 // not actually verify it. But SpdySession will use this
11523 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511524 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711525 scoped_refptr<X509Certificate> server_cert(
11526 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11527 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11528
11529 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211530 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711531 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711532 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11533 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11534 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711535
11536 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211537 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711538 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11539 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11540 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711541
[email protected]bb88e1d32013-05-03 23:11:0711542 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11543 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11544 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711545
11546 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711547 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711548
11549 // Start the first transaction to set up the SpdySession
11550 HttpRequestInfo request1;
11551 request1.method = "GET";
11552 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711553 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011554 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711555 TestCompletionCallback callback1;
11556 ASSERT_EQ(ERR_IO_PENDING,
11557 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11558 data1->RunFor(3);
11559
11560 ASSERT_TRUE(callback1.have_result());
11561 EXPECT_EQ(OK, callback1.WaitForResult());
11562 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11563
11564 // Now, start the HTTP request
11565 HttpRequestInfo request2;
11566 request2.method = "GET";
11567 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711568 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011569 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711570 TestCompletionCallback callback2;
11571 EXPECT_EQ(ERR_IO_PENDING,
11572 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411573 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711574 data2->RunFor(3);
11575
11576 ASSERT_TRUE(callback2.have_result());
11577 EXPECT_EQ(OK, callback2.WaitForResult());
11578 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11579}
11580
[email protected]85f97342013-04-17 06:12:2411581// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11582// error) in SPDY session, removes the socket from pool and closes the SPDY
11583// session. Verify that new url's from the same HttpNetworkSession (and a new
11584// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211585TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411586 const std::string https_url = "https://www.google.com/";
11587
11588 MockRead reads1[] = {
11589 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11590 };
11591
11592 scoped_ptr<DeterministicSocketData> data1(
11593 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11594 data1->SetStop(1);
11595
[email protected]cdf8f7e72013-05-23 10:56:4611596 scoped_ptr<SpdyFrame> req2(
11597 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411598 MockWrite writes2[] = {
11599 CreateMockWrite(*req2, 0),
11600 };
11601
[email protected]23e482282013-06-14 16:08:0211602 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11603 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411604 MockRead reads2[] = {
11605 CreateMockRead(*resp2, 1),
11606 CreateMockRead(*body2, 2),
11607 MockRead(ASYNC, OK, 3) // EOF
11608 };
11609
11610 scoped_ptr<DeterministicSocketData> data2(
11611 new DeterministicSocketData(reads2, arraysize(reads2),
11612 writes2, arraysize(writes2)));
11613
[email protected]85f97342013-04-17 06:12:2411614 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211615 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711616 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11617 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11618 data1.get());
[email protected]85f97342013-04-17 06:12:2411619
11620 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211621 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711622 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11623 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11624 data2.get());
[email protected]85f97342013-04-17 06:12:2411625
11626 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711627 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411628
11629 // Start the first transaction to set up the SpdySession and verify that
11630 // connection was closed.
11631 HttpRequestInfo request1;
11632 request1.method = "GET";
11633 request1.url = GURL(https_url);
11634 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011635 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411636 TestCompletionCallback callback1;
11637 EXPECT_EQ(ERR_IO_PENDING,
11638 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411639 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411640 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11641
11642 // Now, start the second request and make sure it succeeds.
11643 HttpRequestInfo request2;
11644 request2.method = "GET";
11645 request2.url = GURL(https_url);
11646 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011647 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411648 TestCompletionCallback callback2;
11649 EXPECT_EQ(ERR_IO_PENDING,
11650 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411651 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411652 data2->RunFor(3);
11653
11654 ASSERT_TRUE(callback2.have_result());
11655 EXPECT_EQ(OK, callback2.WaitForResult());
11656 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11657}
11658
[email protected]23e482282013-06-14 16:08:0211659TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311660 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11661 ClientSocketPoolManager::set_max_sockets_per_group(
11662 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11663 ClientSocketPoolManager::set_max_sockets_per_pool(
11664 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11665
11666 // Use two different hosts with different IPs so they don't get pooled.
11667 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11668 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11669 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11670
11671 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211672 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311673 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211674 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11676 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11677
[email protected]cdf8f7e72013-05-23 10:56:4611678 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311679 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11680 MockWrite spdy1_writes[] = {
11681 CreateMockWrite(*host1_req, 1),
11682 };
[email protected]23e482282013-06-14 16:08:0211683 scoped_ptr<SpdyFrame> host1_resp(
11684 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11685 scoped_ptr<SpdyFrame> host1_resp_body(
11686 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311687 MockRead spdy1_reads[] = {
11688 CreateMockRead(*host1_resp, 2),
11689 CreateMockRead(*host1_resp_body, 3),
11690 MockRead(ASYNC, ERR_IO_PENDING, 4),
11691 };
11692
11693 scoped_ptr<OrderedSocketData> spdy1_data(
11694 new OrderedSocketData(
11695 spdy1_reads, arraysize(spdy1_reads),
11696 spdy1_writes, arraysize(spdy1_writes)));
11697 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11698
[email protected]cdf8f7e72013-05-23 10:56:4611699 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311700 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11701 MockWrite spdy2_writes[] = {
11702 CreateMockWrite(*host2_req, 1),
11703 };
[email protected]23e482282013-06-14 16:08:0211704 scoped_ptr<SpdyFrame> host2_resp(
11705 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11706 scoped_ptr<SpdyFrame> host2_resp_body(
11707 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311708 MockRead spdy2_reads[] = {
11709 CreateMockRead(*host2_resp, 2),
11710 CreateMockRead(*host2_resp_body, 3),
11711 MockRead(ASYNC, ERR_IO_PENDING, 4),
11712 };
11713
11714 scoped_ptr<OrderedSocketData> spdy2_data(
11715 new OrderedSocketData(
11716 spdy2_reads, arraysize(spdy2_reads),
11717 spdy2_writes, arraysize(spdy2_writes)));
11718 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11719
11720 MockWrite http_write[] = {
11721 MockWrite("GET / HTTP/1.1\r\n"
11722 "Host: www.a.com\r\n"
11723 "Connection: keep-alive\r\n\r\n"),
11724 };
11725
11726 MockRead http_read[] = {
11727 MockRead("HTTP/1.1 200 OK\r\n"),
11728 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11729 MockRead("Content-Length: 6\r\n\r\n"),
11730 MockRead("hello!"),
11731 };
11732 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11733 http_write, arraysize(http_write));
11734 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11735
11736 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011737 SpdySessionKey spdy_session_key_a(
11738 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311739 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611740 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311741
11742 TestCompletionCallback callback;
11743 HttpRequestInfo request1;
11744 request1.method = "GET";
11745 request1.url = GURL("https://www.a.com/");
11746 request1.load_flags = 0;
11747 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011748 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311749
11750 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11751 EXPECT_EQ(ERR_IO_PENDING, rv);
11752 EXPECT_EQ(OK, callback.WaitForResult());
11753
11754 const HttpResponseInfo* response = trans->GetResponseInfo();
11755 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011756 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311757 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11758 EXPECT_TRUE(response->was_fetched_via_spdy);
11759 EXPECT_TRUE(response->was_npn_negotiated);
11760
11761 std::string response_data;
11762 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11763 EXPECT_EQ("hello!", response_data);
11764 trans.reset();
11765 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611766 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311767
11768 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011769 SpdySessionKey spdy_session_key_b(
11770 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311771 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611772 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311773 HttpRequestInfo request2;
11774 request2.method = "GET";
11775 request2.url = GURL("https://www.b.com/");
11776 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011777 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311778
11779 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11780 EXPECT_EQ(ERR_IO_PENDING, rv);
11781 EXPECT_EQ(OK, callback.WaitForResult());
11782
11783 response = trans->GetResponseInfo();
11784 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011785 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311786 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11787 EXPECT_TRUE(response->was_fetched_via_spdy);
11788 EXPECT_TRUE(response->was_npn_negotiated);
11789 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11790 EXPECT_EQ("hello!", response_data);
11791 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611792 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311793 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611794 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311795
11796 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011797 SpdySessionKey spdy_session_key_a1(
11798 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311799 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611800 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311801 HttpRequestInfo request3;
11802 request3.method = "GET";
11803 request3.url = GURL("http://www.a.com/");
11804 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011805 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311806
11807 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11808 EXPECT_EQ(ERR_IO_PENDING, rv);
11809 EXPECT_EQ(OK, callback.WaitForResult());
11810
11811 response = trans->GetResponseInfo();
11812 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011813 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311814 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11815 EXPECT_FALSE(response->was_fetched_via_spdy);
11816 EXPECT_FALSE(response->was_npn_negotiated);
11817 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11818 EXPECT_EQ("hello!", response_data);
11819 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611820 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311821 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611822 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311823}
11824
[email protected]79e1fd62013-06-20 06:50:0411825TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11826 HttpRequestInfo request;
11827 request.method = "GET";
11828 request.url = GURL("http://www.google.com/");
11829 request.load_flags = 0;
11830
[email protected]3fe8d2f82013-10-17 08:56:0711831 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411832 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711833 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411834
11835 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11836 StaticSocketDataProvider data;
11837 data.set_connect_data(mock_connect);
11838 session_deps_.socket_factory->AddSocketDataProvider(&data);
11839
11840 TestCompletionCallback callback;
11841
11842 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11843 EXPECT_EQ(ERR_IO_PENDING, rv);
11844
11845 rv = callback.WaitForResult();
11846 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11847
11848 EXPECT_EQ(NULL, trans->GetResponseInfo());
11849
11850 // We don't care whether this succeeds or fails, but it shouldn't crash.
11851 HttpRequestHeaders request_headers;
11852 trans->GetFullRequestHeaders(&request_headers);
11853}
11854
11855TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11856 HttpRequestInfo request;
11857 request.method = "GET";
11858 request.url = GURL("http://www.google.com/");
11859 request.load_flags = 0;
11860
[email protected]3fe8d2f82013-10-17 08:56:0711861 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411862 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711863 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411864
11865 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11866 StaticSocketDataProvider data;
11867 data.set_connect_data(mock_connect);
11868 session_deps_.socket_factory->AddSocketDataProvider(&data);
11869
11870 TestCompletionCallback callback;
11871
11872 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11873 EXPECT_EQ(ERR_IO_PENDING, rv);
11874
11875 rv = callback.WaitForResult();
11876 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11877
11878 EXPECT_EQ(NULL, trans->GetResponseInfo());
11879
11880 // We don't care whether this succeeds or fails, but it shouldn't crash.
11881 HttpRequestHeaders request_headers;
11882 trans->GetFullRequestHeaders(&request_headers);
11883}
11884
11885TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11886 HttpRequestInfo request;
11887 request.method = "GET";
11888 request.url = GURL("http://www.google.com/");
11889 request.load_flags = 0;
11890
[email protected]3fe8d2f82013-10-17 08:56:0711891 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411892 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411894
11895 MockWrite data_writes[] = {
11896 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11897 };
11898 MockRead data_reads[] = {
11899 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11900 };
11901
11902 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11903 data_writes, arraysize(data_writes));
11904 session_deps_.socket_factory->AddSocketDataProvider(&data);
11905
11906 TestCompletionCallback callback;
11907
11908 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11909 EXPECT_EQ(ERR_IO_PENDING, rv);
11910
11911 rv = callback.WaitForResult();
11912 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11913
11914 EXPECT_EQ(NULL, trans->GetResponseInfo());
11915
11916 HttpRequestHeaders request_headers;
11917 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11918 EXPECT_TRUE(request_headers.HasHeader("Host"));
11919}
11920
11921TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11922 HttpRequestInfo request;
11923 request.method = "GET";
11924 request.url = GURL("http://www.google.com/");
11925 request.load_flags = 0;
11926
[email protected]3fe8d2f82013-10-17 08:56:0711927 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411928 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711929 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411930
11931 MockWrite data_writes[] = {
11932 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11933 };
11934 MockRead data_reads[] = {
11935 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11936 };
11937
11938 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11939 data_writes, arraysize(data_writes));
11940 session_deps_.socket_factory->AddSocketDataProvider(&data);
11941
11942 TestCompletionCallback callback;
11943
11944 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11945 EXPECT_EQ(ERR_IO_PENDING, rv);
11946
11947 rv = callback.WaitForResult();
11948 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11949
11950 EXPECT_EQ(NULL, trans->GetResponseInfo());
11951
11952 HttpRequestHeaders request_headers;
11953 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11954 EXPECT_TRUE(request_headers.HasHeader("Host"));
11955}
11956
11957TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11958 HttpRequestInfo request;
11959 request.method = "GET";
11960 request.url = GURL("http://www.google.com/");
11961 request.load_flags = 0;
11962
[email protected]3fe8d2f82013-10-17 08:56:0711963 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411964 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711965 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411966
11967 MockWrite data_writes[] = {
11968 MockWrite("GET / HTTP/1.1\r\n"
11969 "Host: www.google.com\r\n"
11970 "Connection: keep-alive\r\n\r\n"),
11971 };
11972 MockRead data_reads[] = {
11973 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11974 };
11975
11976 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11977 data_writes, arraysize(data_writes));
11978 session_deps_.socket_factory->AddSocketDataProvider(&data);
11979
11980 TestCompletionCallback callback;
11981
11982 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11983 EXPECT_EQ(ERR_IO_PENDING, rv);
11984
11985 rv = callback.WaitForResult();
11986 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11987
11988 EXPECT_EQ(NULL, trans->GetResponseInfo());
11989
11990 HttpRequestHeaders request_headers;
11991 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11992 EXPECT_TRUE(request_headers.HasHeader("Host"));
11993}
11994
11995TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11996 HttpRequestInfo request;
11997 request.method = "GET";
11998 request.url = GURL("http://www.google.com/");
11999 request.load_flags = 0;
12000
[email protected]3fe8d2f82013-10-17 08:56:0712001 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412002 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712003 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412004
12005 MockWrite data_writes[] = {
12006 MockWrite("GET / HTTP/1.1\r\n"
12007 "Host: www.google.com\r\n"
12008 "Connection: keep-alive\r\n\r\n"),
12009 };
12010 MockRead data_reads[] = {
12011 MockRead(ASYNC, ERR_CONNECTION_RESET),
12012 };
12013
12014 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12015 data_writes, arraysize(data_writes));
12016 session_deps_.socket_factory->AddSocketDataProvider(&data);
12017
12018 TestCompletionCallback callback;
12019
12020 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12021 EXPECT_EQ(ERR_IO_PENDING, rv);
12022
12023 rv = callback.WaitForResult();
12024 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12025
12026 EXPECT_EQ(NULL, trans->GetResponseInfo());
12027
12028 HttpRequestHeaders request_headers;
12029 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12030 EXPECT_TRUE(request_headers.HasHeader("Host"));
12031}
12032
12033TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12034 HttpRequestInfo request;
12035 request.method = "GET";
12036 request.url = GURL("http://www.google.com/");
12037 request.load_flags = 0;
12038 request.extra_headers.SetHeader("X-Foo", "bar");
12039
[email protected]3fe8d2f82013-10-17 08:56:0712040 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412041 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412043
12044 MockWrite data_writes[] = {
12045 MockWrite("GET / HTTP/1.1\r\n"
12046 "Host: www.google.com\r\n"
12047 "Connection: keep-alive\r\n"
12048 "X-Foo: bar\r\n\r\n"),
12049 };
12050 MockRead data_reads[] = {
12051 MockRead("HTTP/1.1 200 OK\r\n"
12052 "Content-Length: 5\r\n\r\n"
12053 "hello"),
12054 MockRead(ASYNC, ERR_UNEXPECTED),
12055 };
12056
12057 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12058 data_writes, arraysize(data_writes));
12059 session_deps_.socket_factory->AddSocketDataProvider(&data);
12060
12061 TestCompletionCallback callback;
12062
12063 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12064 EXPECT_EQ(ERR_IO_PENDING, rv);
12065
12066 rv = callback.WaitForResult();
12067 EXPECT_EQ(OK, rv);
12068
12069 HttpRequestHeaders request_headers;
12070 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12071 std::string foo;
12072 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12073 EXPECT_EQ("bar", foo);
12074}
12075
[email protected]bf828982013-08-14 18:01:4712076namespace {
12077
[email protected]e86839fd2013-08-14 18:29:0312078// Fake HttpStreamBase that simply records calls to SetPriority().
12079class FakeStream : public HttpStreamBase,
12080 public base::SupportsWeakPtr<FakeStream> {
12081 public:
12082 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
12083 virtual ~FakeStream() {}
12084
12085 RequestPriority priority() const { return priority_; }
12086
12087 virtual int InitializeStream(const HttpRequestInfo* request_info,
12088 RequestPriority priority,
12089 const BoundNetLog& net_log,
12090 const CompletionCallback& callback) OVERRIDE {
12091 return ERR_IO_PENDING;
12092 }
12093
12094 virtual int SendRequest(const HttpRequestHeaders& request_headers,
12095 HttpResponseInfo* response,
12096 const CompletionCallback& callback) OVERRIDE {
12097 ADD_FAILURE();
12098 return ERR_UNEXPECTED;
12099 }
12100
12101 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
12102 ADD_FAILURE();
12103 return ERR_UNEXPECTED;
12104 }
12105
12106 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
12107 ADD_FAILURE();
12108 return NULL;
12109 }
12110
12111 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
12112 const CompletionCallback& callback) OVERRIDE {
12113 ADD_FAILURE();
12114 return ERR_UNEXPECTED;
12115 }
12116
12117 virtual void Close(bool not_reusable) OVERRIDE {}
12118
12119 virtual bool IsResponseBodyComplete() const OVERRIDE {
12120 ADD_FAILURE();
12121 return false;
12122 }
12123
12124 virtual bool CanFindEndOfResponse() const OVERRIDE {
12125 return false;
12126 }
12127
12128 virtual bool IsConnectionReused() const OVERRIDE {
12129 ADD_FAILURE();
12130 return false;
12131 }
12132
12133 virtual void SetConnectionReused() OVERRIDE {
12134 ADD_FAILURE();
12135 }
12136
12137 virtual bool IsConnectionReusable() const OVERRIDE {
12138 ADD_FAILURE();
12139 return false;
12140 }
12141
[email protected]bc92bc972013-12-13 08:32:5912142 virtual int64 GetTotalReceivedBytes() const OVERRIDE {
12143 ADD_FAILURE();
12144 return 0;
12145 }
12146
[email protected]e86839fd2013-08-14 18:29:0312147 virtual bool GetLoadTimingInfo(
12148 LoadTimingInfo* load_timing_info) const OVERRIDE {
12149 ADD_FAILURE();
12150 return false;
12151 }
12152
12153 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
12154 ADD_FAILURE();
12155 }
12156
12157 virtual void GetSSLCertRequestInfo(
12158 SSLCertRequestInfo* cert_request_info) OVERRIDE {
12159 ADD_FAILURE();
12160 }
12161
12162 virtual bool IsSpdyHttpStream() const OVERRIDE {
12163 ADD_FAILURE();
12164 return false;
12165 }
12166
12167 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
12168 ADD_FAILURE();
12169 }
12170
12171 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12172 priority_ = priority;
12173 }
12174
12175 private:
12176 RequestPriority priority_;
12177
12178 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12179};
12180
12181// Fake HttpStreamRequest that simply records calls to SetPriority()
12182// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712183class FakeStreamRequest : public HttpStreamRequest,
12184 public base::SupportsWeakPtr<FakeStreamRequest> {
12185 public:
[email protected]e86839fd2013-08-14 18:29:0312186 FakeStreamRequest(RequestPriority priority,
12187 HttpStreamRequest::Delegate* delegate)
12188 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412189 delegate_(delegate),
12190 websocket_stream_create_helper_(NULL) {}
12191
12192 FakeStreamRequest(RequestPriority priority,
12193 HttpStreamRequest::Delegate* delegate,
12194 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12195 : priority_(priority),
12196 delegate_(delegate),
12197 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312198
[email protected]bf828982013-08-14 18:01:4712199 virtual ~FakeStreamRequest() {}
12200
12201 RequestPriority priority() const { return priority_; }
12202
[email protected]831e4a32013-11-14 02:14:4412203 const WebSocketHandshakeStreamBase::CreateHelper*
12204 websocket_stream_create_helper() const {
12205 return websocket_stream_create_helper_;
12206 }
12207
[email protected]e86839fd2013-08-14 18:29:0312208 // Create a new FakeStream and pass it to the request's
12209 // delegate. Returns a weak pointer to the FakeStream.
12210 base::WeakPtr<FakeStream> FinishStreamRequest() {
12211 FakeStream* fake_stream = new FakeStream(priority_);
12212 // Do this before calling OnStreamReady() as OnStreamReady() may
12213 // immediately delete |fake_stream|.
12214 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12215 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12216 return weak_stream;
12217 }
12218
[email protected]bf828982013-08-14 18:01:4712219 virtual int RestartTunnelWithProxyAuth(
12220 const AuthCredentials& credentials) OVERRIDE {
12221 ADD_FAILURE();
12222 return ERR_UNEXPECTED;
12223 }
12224
12225 virtual LoadState GetLoadState() const OVERRIDE {
12226 ADD_FAILURE();
12227 return LoadState();
12228 }
12229
12230 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12231 priority_ = priority;
12232 }
12233
12234 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712235 return false;
12236 }
12237
12238 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712239 return kProtoUnknown;
12240 }
12241
12242 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712243 return false;
12244 }
12245
12246 private:
12247 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312248 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412249 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712250
12251 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12252};
12253
12254// Fake HttpStreamFactory that vends FakeStreamRequests.
12255class FakeStreamFactory : public HttpStreamFactory {
12256 public:
12257 FakeStreamFactory() {}
12258 virtual ~FakeStreamFactory() {}
12259
12260 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12261 // RequestStream() (which may be NULL if it was destroyed already).
12262 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12263 return last_stream_request_;
12264 }
12265
12266 virtual HttpStreamRequest* RequestStream(
12267 const HttpRequestInfo& info,
12268 RequestPriority priority,
12269 const SSLConfig& server_ssl_config,
12270 const SSLConfig& proxy_ssl_config,
12271 HttpStreamRequest::Delegate* delegate,
12272 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0312273 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712274 last_stream_request_ = fake_request->AsWeakPtr();
12275 return fake_request;
12276 }
12277
[email protected]a9cf2b92013-10-30 12:08:4912278 virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712279 const HttpRequestInfo& info,
12280 RequestPriority priority,
12281 const SSLConfig& server_ssl_config,
12282 const SSLConfig& proxy_ssl_config,
12283 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612284 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
[email protected]bf828982013-08-14 18:01:4712285 const BoundNetLog& net_log) OVERRIDE {
[email protected]831e4a32013-11-14 02:14:4412286 FakeStreamRequest* fake_request =
12287 new FakeStreamRequest(priority, delegate, create_helper);
12288 last_stream_request_ = fake_request->AsWeakPtr();
12289 return fake_request;
[email protected]bf828982013-08-14 18:01:4712290 }
12291
12292 virtual void PreconnectStreams(int num_streams,
12293 const HttpRequestInfo& info,
12294 RequestPriority priority,
12295 const SSLConfig& server_ssl_config,
12296 const SSLConfig& proxy_ssl_config) OVERRIDE {
12297 ADD_FAILURE();
12298 }
12299
12300 virtual base::Value* PipelineInfoToValue() const OVERRIDE {
12301 ADD_FAILURE();
12302 return NULL;
12303 }
12304
12305 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
12306 ADD_FAILURE();
12307 return NULL;
12308 }
12309
12310 private:
12311 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12312
12313 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12314};
12315
[email protected]831e4a32013-11-14 02:14:4412316// TODO(yhirano): Split this class out into a net/websockets file, if it is
12317// worth doing.
12318class FakeWebSocketStreamCreateHelper :
12319 public WebSocketHandshakeStreamBase::CreateHelper {
12320 public:
12321 virtual WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112322 scoped_ptr<ClientSocketHandle> connection,
[email protected]831e4a32013-11-14 02:14:4412323 bool using_proxy) OVERRIDE {
12324 NOTREACHED();
12325 return NULL;
12326 }
12327
12328 virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12329 const base::WeakPtr<SpdySession>& session,
12330 bool use_relative_url) OVERRIDE {
12331 NOTREACHED();
12332 return NULL;
12333 };
12334
12335 virtual ~FakeWebSocketStreamCreateHelper() {}
12336
12337 virtual scoped_ptr<WebSocketStream> Upgrade() {
12338 NOTREACHED();
12339 return scoped_ptr<WebSocketStream>();
12340 }
12341};
12342
[email protected]bf828982013-08-14 18:01:4712343} // namespace
12344
12345// Make sure that HttpNetworkTransaction passes on its priority to its
12346// stream request on start.
12347TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12348 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12349 HttpNetworkSessionPeer peer(session);
12350 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412351 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712352
12353 HttpNetworkTransaction trans(LOW, session);
12354
12355 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12356
12357 HttpRequestInfo request;
12358 TestCompletionCallback callback;
12359 EXPECT_EQ(ERR_IO_PENDING,
12360 trans.Start(&request, callback.callback(), BoundNetLog()));
12361
12362 base::WeakPtr<FakeStreamRequest> fake_request =
12363 fake_factory->last_stream_request();
12364 ASSERT_TRUE(fake_request != NULL);
12365 EXPECT_EQ(LOW, fake_request->priority());
12366}
12367
12368// Make sure that HttpNetworkTransaction passes on its priority
12369// updates to its stream request.
12370TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12371 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12372 HttpNetworkSessionPeer peer(session);
12373 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412374 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712375
12376 HttpNetworkTransaction trans(LOW, session);
12377
12378 HttpRequestInfo request;
12379 TestCompletionCallback callback;
12380 EXPECT_EQ(ERR_IO_PENDING,
12381 trans.Start(&request, callback.callback(), BoundNetLog()));
12382
12383 base::WeakPtr<FakeStreamRequest> fake_request =
12384 fake_factory->last_stream_request();
12385 ASSERT_TRUE(fake_request != NULL);
12386 EXPECT_EQ(LOW, fake_request->priority());
12387
12388 trans.SetPriority(LOWEST);
12389 ASSERT_TRUE(fake_request != NULL);
12390 EXPECT_EQ(LOWEST, fake_request->priority());
12391}
12392
[email protected]e86839fd2013-08-14 18:29:0312393// Make sure that HttpNetworkTransaction passes on its priority
12394// updates to its stream.
12395TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12396 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12397 HttpNetworkSessionPeer peer(session);
12398 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412399 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312400
12401 HttpNetworkTransaction trans(LOW, session);
12402
12403 HttpRequestInfo request;
12404 TestCompletionCallback callback;
12405 EXPECT_EQ(ERR_IO_PENDING,
12406 trans.Start(&request, callback.callback(), BoundNetLog()));
12407
12408 base::WeakPtr<FakeStreamRequest> fake_request =
12409 fake_factory->last_stream_request();
12410 ASSERT_TRUE(fake_request != NULL);
12411 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12412 ASSERT_TRUE(fake_stream != NULL);
12413 EXPECT_EQ(LOW, fake_stream->priority());
12414
12415 trans.SetPriority(LOWEST);
12416 EXPECT_EQ(LOWEST, fake_stream->priority());
12417}
12418
[email protected]831e4a32013-11-14 02:14:4412419TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12420 // The same logic needs to be tested for both ws: and wss: schemes, but this
12421 // test is already parameterised on NextProto, so it uses a loop to verify
12422 // that the different schemes work.
12423 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12424 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12425 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12426 HttpNetworkSessionPeer peer(session);
12427 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12428 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312429 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412430 scoped_ptr<HttpStreamFactory>(fake_factory));
12431
12432 HttpNetworkTransaction trans(LOW, session);
12433 trans.SetWebSocketHandshakeStreamCreateHelper(
12434 &websocket_stream_create_helper);
12435
12436 HttpRequestInfo request;
12437 TestCompletionCallback callback;
12438 request.method = "GET";
12439 request.url = GURL(test_cases[i]);
12440
12441 EXPECT_EQ(ERR_IO_PENDING,
12442 trans.Start(&request, callback.callback(), BoundNetLog()));
12443
12444 base::WeakPtr<FakeStreamRequest> fake_request =
12445 fake_factory->last_stream_request();
12446 ASSERT_TRUE(fake_request != NULL);
12447 EXPECT_EQ(&websocket_stream_create_helper,
12448 fake_request->websocket_stream_create_helper());
12449 }
12450}
12451
[email protected]043b68c82013-08-22 23:41:5212452// Tests that when a used socket is returned to the SSL socket pool, it's closed
12453// if the transport socket pool is stalled on the global socket limit.
12454TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12455 ClientSocketPoolManager::set_max_sockets_per_group(
12456 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12457 ClientSocketPoolManager::set_max_sockets_per_pool(
12458 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12459
12460 // Set up SSL request.
12461
12462 HttpRequestInfo ssl_request;
12463 ssl_request.method = "GET";
12464 ssl_request.url = GURL("https://www.google.com/");
12465
12466 MockWrite ssl_writes[] = {
12467 MockWrite("GET / HTTP/1.1\r\n"
12468 "Host: www.google.com\r\n"
12469 "Connection: keep-alive\r\n\r\n"),
12470 };
12471 MockRead ssl_reads[] = {
12472 MockRead("HTTP/1.1 200 OK\r\n"),
12473 MockRead("Content-Length: 11\r\n\r\n"),
12474 MockRead("hello world"),
12475 MockRead(SYNCHRONOUS, OK),
12476 };
12477 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12478 ssl_writes, arraysize(ssl_writes));
12479 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12480
12481 SSLSocketDataProvider ssl(ASYNC, OK);
12482 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12483
12484 // Set up HTTP request.
12485
12486 HttpRequestInfo http_request;
12487 http_request.method = "GET";
12488 http_request.url = GURL("http://www.google.com/");
12489
12490 MockWrite http_writes[] = {
12491 MockWrite("GET / HTTP/1.1\r\n"
12492 "Host: www.google.com\r\n"
12493 "Connection: keep-alive\r\n\r\n"),
12494 };
12495 MockRead http_reads[] = {
12496 MockRead("HTTP/1.1 200 OK\r\n"),
12497 MockRead("Content-Length: 7\r\n\r\n"),
12498 MockRead("falafel"),
12499 MockRead(SYNCHRONOUS, OK),
12500 };
12501 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12502 http_writes, arraysize(http_writes));
12503 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12504
12505 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12506
12507 // Start the SSL request.
12508 TestCompletionCallback ssl_callback;
12509 scoped_ptr<HttpTransaction> ssl_trans(
12510 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12511 ASSERT_EQ(ERR_IO_PENDING,
12512 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12513 BoundNetLog()));
12514
12515 // Start the HTTP request. Pool should stall.
12516 TestCompletionCallback http_callback;
12517 scoped_ptr<HttpTransaction> http_trans(
12518 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12519 ASSERT_EQ(ERR_IO_PENDING,
12520 http_trans->Start(&http_request, http_callback.callback(),
12521 BoundNetLog()));
12522 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12523
12524 // Wait for response from SSL request.
12525 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12526 std::string response_data;
12527 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12528 EXPECT_EQ("hello world", response_data);
12529
12530 // The SSL socket should automatically be closed, so the HTTP request can
12531 // start.
12532 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12533 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12534
12535 // The HTTP request can now complete.
12536 ASSERT_EQ(OK, http_callback.WaitForResult());
12537 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12538 EXPECT_EQ("falafel", response_data);
12539
12540 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12541}
12542
12543// Tests that when a SSL connection is established but there's no corresponding
12544// request that needs it, the new socket is closed if the transport socket pool
12545// is stalled on the global socket limit.
12546TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12547 ClientSocketPoolManager::set_max_sockets_per_group(
12548 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12549 ClientSocketPoolManager::set_max_sockets_per_pool(
12550 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12551
12552 // Set up an ssl request.
12553
12554 HttpRequestInfo ssl_request;
12555 ssl_request.method = "GET";
12556 ssl_request.url = GURL("https://www.foopy.com/");
12557
12558 // No data will be sent on the SSL socket.
12559 StaticSocketDataProvider ssl_data;
12560 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12561
12562 SSLSocketDataProvider ssl(ASYNC, OK);
12563 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12564
12565 // Set up HTTP request.
12566
12567 HttpRequestInfo http_request;
12568 http_request.method = "GET";
12569 http_request.url = GURL("http://www.google.com/");
12570
12571 MockWrite http_writes[] = {
12572 MockWrite("GET / HTTP/1.1\r\n"
12573 "Host: www.google.com\r\n"
12574 "Connection: keep-alive\r\n\r\n"),
12575 };
12576 MockRead http_reads[] = {
12577 MockRead("HTTP/1.1 200 OK\r\n"),
12578 MockRead("Content-Length: 7\r\n\r\n"),
12579 MockRead("falafel"),
12580 MockRead(SYNCHRONOUS, OK),
12581 };
12582 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12583 http_writes, arraysize(http_writes));
12584 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12585
12586 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12587
12588 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12589 // cancelled when a normal transaction is cancelled.
12590 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12591 net::SSLConfig ssl_config;
12592 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12593 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12594 ssl_config, ssl_config);
12595 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12596
12597 // Start the HTTP request. Pool should stall.
12598 TestCompletionCallback http_callback;
12599 scoped_ptr<HttpTransaction> http_trans(
12600 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12601 ASSERT_EQ(ERR_IO_PENDING,
12602 http_trans->Start(&http_request, http_callback.callback(),
12603 BoundNetLog()));
12604 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12605
12606 // The SSL connection will automatically be closed once the connection is
12607 // established, to let the HTTP request start.
12608 ASSERT_EQ(OK, http_callback.WaitForResult());
12609 std::string response_data;
12610 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12611 EXPECT_EQ("falafel", response_data);
12612
12613 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12614}
12615
[email protected]89ceba9a2009-03-21 03:46:0612616} // namespace net