blob: ab64040df1ab4b3619e28f2bb584e17c1abd9688 [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"
[email protected]c41737d2014-05-14 07:47:1949#include "net/http/http_transaction_test_util.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]0e75a732008-10-16 20:36:09268 }
269
[email protected]8a0fc822013-06-27 20:52:43270 // This is the expected return from a current server advertising SPDY.
271 std::string GetAlternateProtocolHttpHeader() {
272 return
273 std::string("Alternate-Protocol: 443:") +
274 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
275 "\r\n\r\n";
276 }
277
[email protected]202965992011-12-07 23:04:51278 // Either |write_failure| specifies a write failure or |read_failure|
279 // specifies a read failure when using a reused socket. In either case, the
280 // failure should cause the network transaction to resend the request, and the
281 // other argument should be NULL.
282 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
283 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52284
[email protected]a34f61ee2014-03-18 20:59:49285 // Either |write_failure| specifies a write failure or |read_failure|
286 // specifies a read failure when using a reused socket. In either case, the
287 // failure should cause the network transaction to resend the request, and the
288 // other argument should be NULL.
289 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10290 const MockRead* read_failure,
291 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49292
[email protected]5a60c8b2011-10-19 20:14:29293 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
294 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15295 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52296
[email protected]ff007e162009-05-23 09:13:15297 HttpRequestInfo request;
298 request.method = "GET";
299 request.url = GURL("http://www.google.com/");
300 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52301
[email protected]58e32bb2013-01-21 18:23:25302 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07303 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27305 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27307
[email protected]5a60c8b2011-10-19 20:14:29308 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07309 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29310 }
initial.commit586acc5fe2008-07-26 22:42:52311
[email protected]49639fa2011-12-20 23:22:41312 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52313
[email protected]c47c0372014-03-12 23:07:02314 EXPECT_TRUE(log.bound().IsLogging());
[email protected]49639fa2011-12-20 23:22:41315 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15316 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52317
[email protected]ff007e162009-05-23 09:13:15318 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25319
320 // Even in the failure cases that use this function, connections are always
321 // successfully established before the error.
322 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
323 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
324
[email protected]ff007e162009-05-23 09:13:15325 if (out.rv != OK)
326 return out;
327
328 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50329 // Can't use ASSERT_* inside helper functions like this, so
330 // return an error.
[email protected]90499482013-06-01 00:39:50331 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50332 out.rv = ERR_UNEXPECTED;
333 return out;
334 }
[email protected]ff007e162009-05-23 09:13:15335 out.status_line = response->headers->GetStatusLine();
336
[email protected]80a09a82012-11-16 17:40:06337 EXPECT_EQ("127.0.0.1", response->socket_address.host());
338 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19339
[email protected]ff007e162009-05-23 09:13:15340 rv = ReadTransaction(trans.get(), &out.response_data);
341 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40342
[email protected]f3da152d2012-06-02 01:00:57343 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40344 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39345 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40346 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12347 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39348 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40349 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39350 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
351 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15352
[email protected]f3da152d2012-06-02 01:00:57353 std::string line;
354 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
355 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
356
[email protected]79e1fd62013-06-20 06:50:04357 HttpRequestHeaders request_headers;
358 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
359 std::string value;
360 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
361 EXPECT_EQ("www.google.com", value);
362 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
363 EXPECT_EQ("keep-alive", value);
364
365 std::string response_headers;
366 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
367 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
368 response_headers);
[email protected]3deb9a52010-11-11 00:24:40369
[email protected]b8015c42013-12-24 15:18:19370 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
[email protected]aecfbf22008-10-16 02:02:47371 return out;
[email protected]ff007e162009-05-23 09:13:15372 }
initial.commit586acc5fe2008-07-26 22:42:52373
[email protected]5a60c8b2011-10-19 20:14:29374 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
375 size_t reads_count) {
376 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
377 StaticSocketDataProvider* data[] = { &reads };
378 return SimpleGetHelperForData(data, 1);
379 }
380
[email protected]b8015c42013-12-24 15:18:19381 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
382 int64 size = 0;
383 for (size_t i = 0; i < reads_count; ++i)
384 size += data_reads[i].data_len;
385 return size;
386 }
387
[email protected]ff007e162009-05-23 09:13:15388 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
389 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52390
[email protected]ff007e162009-05-23 09:13:15391 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07392
393 void BypassHostCacheOnRefreshHelper(int load_flags);
394
395 void CheckErrorIsPassedBack(int error, IoMode mode);
396
[email protected]4bd46222013-05-14 19:32:23397 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07398 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03399
400 // Original socket limits. Some tests set these. Safest to always restore
401 // them once each test has been run.
402 int old_max_group_sockets_;
403 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15404};
[email protected]231d5a32008-09-13 00:45:27405
[email protected]23e482282013-06-14 16:08:02406INSTANTIATE_TEST_CASE_P(
407 NextProto,
408 HttpNetworkTransactionTest,
[email protected]b05bcaa32013-10-06 05:26:02409 testing::Values(kProtoDeprecatedSPDY2,
[email protected]d10833bc2014-04-14 17:50:46410 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
[email protected]23e482282013-06-14 16:08:02411
[email protected]448d4ca52012-03-04 04:12:23412namespace {
413
[email protected]1826a402014-01-08 15:40:48414class BeforeNetworkStartHandler {
415 public:
416 explicit BeforeNetworkStartHandler(bool defer)
417 : defer_on_before_network_start_(defer),
418 observed_before_network_start_(false) {}
419
420 void OnBeforeNetworkStart(bool* defer) {
421 *defer = defer_on_before_network_start_;
422 observed_before_network_start_ = true;
423 }
424
425 bool observed_before_network_start() const {
426 return observed_before_network_start_;
427 }
428
429 private:
430 const bool defer_on_before_network_start_;
431 bool observed_before_network_start_;
432
433 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
434};
435
[email protected]597a1ab2014-06-26 08:12:27436class BeforeProxyHeadersSentHandler {
437 public:
438 BeforeProxyHeadersSentHandler()
439 : observed_before_proxy_headers_sent_(false) {}
440
[email protected]1252d42f2014-07-01 21:20:20441 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
442 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27443 observed_before_proxy_headers_sent_ = true;
444 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
445 }
446
447 bool observed_before_proxy_headers_sent() const {
448 return observed_before_proxy_headers_sent_;
449 }
450
451 std::string observed_proxy_server_uri() const {
452 return observed_proxy_server_uri_;
453 }
454
455 private:
456 bool observed_before_proxy_headers_sent_;
457 std::string observed_proxy_server_uri_;
458
459 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
460};
461
[email protected]15a5ccf82008-10-23 19:57:43462// Fill |str| with a long header list that consumes >= |size| bytes.
463void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19464 const char* row =
465 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
466 const int sizeof_row = strlen(row);
467 const int num_rows = static_cast<int>(
468 ceil(static_cast<float>(size) / sizeof_row));
469 const int sizeof_data = num_rows * sizeof_row;
470 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43471 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51472
[email protected]4ddaf2502008-10-23 18:26:19473 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43474 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19475}
476
[email protected]385a4672009-03-11 22:21:29477// Alternative functions that eliminate randomness and dependency on the local
478// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20479void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29480 static const uint8 bytes[] = {
481 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
482 };
483 static size_t current_byte = 0;
484 for (size_t i = 0; i < n; ++i) {
485 output[i] = bytes[current_byte++];
486 current_byte %= arraysize(bytes);
487 }
488}
489
[email protected]fe2bc6a2009-03-23 16:52:20490void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29491 static const uint8 bytes[] = {
492 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
493 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
494 };
495 static size_t current_byte = 0;
496 for (size_t i = 0; i < n; ++i) {
497 output[i] = bytes[current_byte++];
498 current_byte %= arraysize(bytes);
499 }
500}
501
[email protected]fe2bc6a2009-03-23 16:52:20502std::string MockGetHostName() {
503 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29504}
505
[email protected]e60e47a2010-07-14 03:37:18506template<typename ParentPool>
507class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31508 public:
[email protected]9e1bdd32011-02-03 21:48:34509 CaptureGroupNameSocketPool(HostResolver* host_resolver,
510 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18511
[email protected]d80a4322009-08-14 07:07:49512 const std::string last_group_name_received() const {
513 return last_group_name_;
514 }
515
[email protected]684970b2009-08-14 04:54:46516 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49517 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31518 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31519 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41520 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53521 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31522 last_group_name_ = group_name;
523 return ERR_IO_PENDING;
524 }
[email protected]04e5be32009-06-26 20:00:31525 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21526 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31527 virtual void ReleaseSocket(const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44528 scoped_ptr<StreamSocket> socket,
[email protected]9f95c692011-02-11 19:20:19529 int id) {}
[email protected]04e5be32009-06-26 20:00:31530 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31531 virtual int IdleSocketCount() const {
532 return 0;
533 }
534 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
535 return 0;
536 }
537 virtual LoadState GetLoadState(const std::string& group_name,
538 const ClientSocketHandle* handle) const {
539 return LOAD_STATE_IDLE;
540 }
[email protected]a796bcec2010-03-22 17:17:26541 virtual base::TimeDelta ConnectionTimeout() const {
542 return base::TimeDelta();
543 }
[email protected]d80a4322009-08-14 07:07:49544
545 private:
[email protected]04e5be32009-06-26 20:00:31546 std::string last_group_name_;
547};
548
[email protected]ab739042011-04-07 15:22:28549typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
550CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13551typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
552CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06553typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11554CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18555typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
556CaptureGroupNameSSLSocketPool;
557
558template<typename ParentPool>
559CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34560 HostResolver* host_resolver,
561 CertVerifier* /* cert_verifier */)
562 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18563
564template<>
[email protected]2df19bb2010-08-25 20:13:46565CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34566 HostResolver* host_resolver,
567 CertVerifier* /* cert_verifier */)
568 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46569
[email protected]007b3f82013-04-09 08:46:45570template <>
[email protected]e60e47a2010-07-14 03:37:18571CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34572 HostResolver* host_resolver,
573 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45574 : SSLClientSocketPool(0,
575 0,
576 NULL,
577 host_resolver,
578 cert_verifier,
579 NULL,
580 NULL,
[email protected]284303b62013-11-28 15:11:54581 NULL,
[email protected]007b3f82013-04-09 08:46:45582 std::string(),
583 NULL,
584 NULL,
585 NULL,
586 NULL,
587 NULL,
588 NULL) {}
[email protected]2227c692010-05-04 15:36:11589
[email protected]231d5a32008-09-13 00:45:27590//-----------------------------------------------------------------------------
591
[email protected]79cb5c12011-09-12 13:12:04592// Helper functions for validating that AuthChallengeInfo's are correctly
593// configured for common cases.
594bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
595 if (!auth_challenge)
596 return false;
597 EXPECT_FALSE(auth_challenge->is_proxy);
598 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
599 EXPECT_EQ("MyRealm1", auth_challenge->realm);
600 EXPECT_EQ("basic", auth_challenge->scheme);
601 return true;
602}
603
604bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
605 if (!auth_challenge)
606 return false;
607 EXPECT_TRUE(auth_challenge->is_proxy);
608 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
609 EXPECT_EQ("MyRealm1", auth_challenge->realm);
610 EXPECT_EQ("basic", auth_challenge->scheme);
611 return true;
612}
613
614bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
615 if (!auth_challenge)
616 return false;
617 EXPECT_FALSE(auth_challenge->is_proxy);
618 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
619 EXPECT_EQ("digestive", auth_challenge->realm);
620 EXPECT_EQ("digest", auth_challenge->scheme);
621 return true;
622}
623
624bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
625 if (!auth_challenge)
626 return false;
627 EXPECT_FALSE(auth_challenge->is_proxy);
628 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
629 EXPECT_EQ(std::string(), auth_challenge->realm);
630 EXPECT_EQ("ntlm", auth_challenge->scheme);
631 return true;
632}
633
[email protected]448d4ca52012-03-04 04:12:23634} // namespace
635
[email protected]23e482282013-06-14 16:08:02636TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07637 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40638 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]231d5a32008-09-13 00:45:27640}
641
[email protected]23e482282013-06-14 16:08:02642TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27643 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35644 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
645 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06646 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27647 };
[email protected]31a2bfe2010-02-09 08:03:39648 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
649 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42650 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27651 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
652 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19653 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
654 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27655}
656
657// Response with no status line.
[email protected]23e482282013-06-14 16:08:02658TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27659 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35660 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06661 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27662 };
[email protected]31a2bfe2010-02-09 08:03:39663 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
664 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42665 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27666 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
667 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19668 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
669 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27670}
671
672// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02673TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27674 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35675 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06676 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27677 };
[email protected]31a2bfe2010-02-09 08:03:39678 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
679 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42680 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27681 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
682 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19683 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
684 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27685}
686
687// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02688TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27689 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35690 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06691 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27692 };
[email protected]31a2bfe2010-02-09 08:03:39693 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
694 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42695 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27696 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
697 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19698 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
699 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27700}
701
702// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02703TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27704 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35705 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06706 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27707 };
[email protected]31a2bfe2010-02-09 08:03:39708 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
709 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42710 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25711 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
712 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19713 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
714 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27715}
716
717// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02718TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27719 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35720 MockRead("\n"),
721 MockRead("\n"),
722 MockRead("Q"),
723 MockRead("J"),
724 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06725 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27726 };
[email protected]31a2bfe2010-02-09 08:03:39727 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
728 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42729 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27730 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
731 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19732 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
733 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27734}
735
736// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02737TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27738 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35739 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06740 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27741 };
[email protected]31a2bfe2010-02-09 08:03:39742 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
743 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42744 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27745 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
746 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19747 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
748 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52749}
750
[email protected]f9d44aa2008-09-23 23:57:17751// Simulate a 204 response, lacking a Content-Length header, sent over a
752// persistent connection. The response should still terminate since a 204
753// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02754TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19755 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17756 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35757 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19758 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06759 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17760 };
[email protected]31a2bfe2010-02-09 08:03:39761 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
762 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42763 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17764 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
765 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19766 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
767 int64 response_size = reads_size - strlen(junk);
768 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17769}
770
[email protected]0877e3d2009-10-17 22:29:57771// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02772TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19773 std::string final_chunk = "0\r\n\r\n";
774 std::string extra_data = "HTTP/1.1 200 OK\r\n";
775 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57776 MockRead data_reads[] = {
777 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
778 MockRead("5\r\nHello\r\n"),
779 MockRead("1\r\n"),
780 MockRead(" \r\n"),
781 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19782 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06783 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57784 };
[email protected]31a2bfe2010-02-09 08:03:39785 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
786 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57787 EXPECT_EQ(OK, out.rv);
788 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
789 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19790 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
791 int64 response_size = reads_size - extra_data.size();
792 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57793}
794
[email protected]9fe44f52010-09-23 18:36:00795// Next tests deal with http://crbug.com/56344.
796
[email protected]23e482282013-06-14 16:08:02797TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00798 MultipleContentLengthHeadersNoTransferEncoding) {
799 MockRead data_reads[] = {
800 MockRead("HTTP/1.1 200 OK\r\n"),
801 MockRead("Content-Length: 10\r\n"),
802 MockRead("Content-Length: 5\r\n\r\n"),
803 };
804 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
805 arraysize(data_reads));
806 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
807}
808
[email protected]23e482282013-06-14 16:08:02809TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04810 DuplicateContentLengthHeadersNoTransferEncoding) {
811 MockRead data_reads[] = {
812 MockRead("HTTP/1.1 200 OK\r\n"),
813 MockRead("Content-Length: 5\r\n"),
814 MockRead("Content-Length: 5\r\n\r\n"),
815 MockRead("Hello"),
816 };
817 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
818 arraysize(data_reads));
819 EXPECT_EQ(OK, out.rv);
820 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
821 EXPECT_EQ("Hello", out.response_data);
822}
823
[email protected]23e482282013-06-14 16:08:02824TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04825 ComplexContentLengthHeadersNoTransferEncoding) {
826 // More than 2 dupes.
827 {
828 MockRead data_reads[] = {
829 MockRead("HTTP/1.1 200 OK\r\n"),
830 MockRead("Content-Length: 5\r\n"),
831 MockRead("Content-Length: 5\r\n"),
832 MockRead("Content-Length: 5\r\n\r\n"),
833 MockRead("Hello"),
834 };
835 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
836 arraysize(data_reads));
837 EXPECT_EQ(OK, out.rv);
838 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
839 EXPECT_EQ("Hello", out.response_data);
840 }
841 // HTTP/1.0
842 {
843 MockRead data_reads[] = {
844 MockRead("HTTP/1.0 200 OK\r\n"),
845 MockRead("Content-Length: 5\r\n"),
846 MockRead("Content-Length: 5\r\n"),
847 MockRead("Content-Length: 5\r\n\r\n"),
848 MockRead("Hello"),
849 };
850 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
851 arraysize(data_reads));
852 EXPECT_EQ(OK, out.rv);
853 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
854 EXPECT_EQ("Hello", out.response_data);
855 }
856 // 2 dupes and one mismatched.
857 {
858 MockRead data_reads[] = {
859 MockRead("HTTP/1.1 200 OK\r\n"),
860 MockRead("Content-Length: 10\r\n"),
861 MockRead("Content-Length: 10\r\n"),
862 MockRead("Content-Length: 5\r\n\r\n"),
863 };
864 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
865 arraysize(data_reads));
866 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
867 }
868}
869
[email protected]23e482282013-06-14 16:08:02870TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00871 MultipleContentLengthHeadersTransferEncoding) {
872 MockRead data_reads[] = {
873 MockRead("HTTP/1.1 200 OK\r\n"),
874 MockRead("Content-Length: 666\r\n"),
875 MockRead("Content-Length: 1337\r\n"),
876 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
877 MockRead("5\r\nHello\r\n"),
878 MockRead("1\r\n"),
879 MockRead(" \r\n"),
880 MockRead("5\r\nworld\r\n"),
881 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06882 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00883 };
884 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
885 arraysize(data_reads));
886 EXPECT_EQ(OK, out.rv);
887 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
888 EXPECT_EQ("Hello world", out.response_data);
889}
890
[email protected]1628fe92011-10-04 23:04:55891// Next tests deal with http://crbug.com/98895.
892
893// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02894TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55895 MockRead data_reads[] = {
896 MockRead("HTTP/1.1 200 OK\r\n"),
897 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
898 MockRead("Content-Length: 5\r\n\r\n"),
899 MockRead("Hello"),
900 };
901 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
902 arraysize(data_reads));
903 EXPECT_EQ(OK, out.rv);
904 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
905 EXPECT_EQ("Hello", out.response_data);
906}
907
[email protected]54a9c6e52012-03-21 20:10:59908// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02909TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59910 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55911 MockRead data_reads[] = {
912 MockRead("HTTP/1.1 200 OK\r\n"),
913 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
914 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
915 MockRead("Content-Length: 5\r\n\r\n"),
916 MockRead("Hello"),
917 };
918 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
919 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59920 EXPECT_EQ(OK, out.rv);
921 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
922 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55923}
924
925// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02926TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55927 MockRead data_reads[] = {
928 MockRead("HTTP/1.1 200 OK\r\n"),
929 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
930 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
931 MockRead("Content-Length: 5\r\n\r\n"),
932 MockRead("Hello"),
933 };
934 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
935 arraysize(data_reads));
936 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
937}
938
[email protected]54a9c6e52012-03-21 20:10:59939// Checks that two identical Location headers result in no error.
940// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02941TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55942 MockRead data_reads[] = {
943 MockRead("HTTP/1.1 302 Redirect\r\n"),
944 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59945 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55946 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06947 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55948 };
949
950 HttpRequestInfo request;
951 request.method = "GET";
952 request.url = GURL("http://redirect.com/");
953 request.load_flags = 0;
954
[email protected]3fe8d2f82013-10-17 08:56:07955 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55956 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07957 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]1628fe92011-10-04 23:04:55958
959 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07960 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55961
[email protected]49639fa2011-12-20 23:22:41962 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55963
[email protected]49639fa2011-12-20 23:22:41964 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55965 EXPECT_EQ(ERR_IO_PENDING, rv);
966
967 EXPECT_EQ(OK, callback.WaitForResult());
968
969 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50970 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55971 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
972 std::string url;
973 EXPECT_TRUE(response->headers->IsRedirect(&url));
974 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:15975 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:55976}
977
[email protected]1628fe92011-10-04 23:04:55978// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02979TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55980 MockRead data_reads[] = {
981 MockRead("HTTP/1.1 302 Redirect\r\n"),
982 MockRead("Location: http://good.com/\r\n"),
983 MockRead("Location: http://evil.com/\r\n"),
984 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06985 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55986 };
987 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
988 arraysize(data_reads));
989 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
990}
991
[email protected]ef0faf2e72009-03-05 23:27:23992// Do a request using the HEAD method. Verify that we don't try to read the
993// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02994TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42995 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23996 request.method = "HEAD";
997 request.url = GURL("http://www.google.com/");
998 request.load_flags = 0;
999
[email protected]3fe8d2f82013-10-17 08:56:071000 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271001 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071002 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]597a1ab2014-06-26 08:12:271003 BeforeProxyHeadersSentHandler proxy_headers_handler;
1004 trans->SetBeforeProxyHeadersSentCallback(
1005 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1006 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271007
[email protected]ef0faf2e72009-03-05 23:27:231008 MockWrite data_writes1[] = {
1009 MockWrite("HEAD / HTTP/1.1\r\n"
1010 "Host: www.google.com\r\n"
1011 "Connection: keep-alive\r\n"
1012 "Content-Length: 0\r\n\r\n"),
1013 };
1014 MockRead data_reads1[] = {
1015 MockRead("HTTP/1.1 404 Not Found\r\n"),
1016 MockRead("Server: Blah\r\n"),
1017 MockRead("Content-Length: 1234\r\n\r\n"),
1018
1019 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061020 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231021 };
1022
[email protected]31a2bfe2010-02-09 08:03:391023 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1024 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071025 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231026
[email protected]49639fa2011-12-20 23:22:411027 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231028
[email protected]49639fa2011-12-20 23:22:411029 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421030 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231031
1032 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421033 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231034
[email protected]1c773ea12009-04-28 19:58:421035 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501036 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231037
1038 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501039 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231040 EXPECT_EQ(1234, response->headers->GetContentLength());
1041 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151042 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271043 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231044
1045 std::string server_header;
1046 void* iter = NULL;
1047 bool has_server_header = response->headers->EnumerateHeader(
1048 &iter, "Server", &server_header);
1049 EXPECT_TRUE(has_server_header);
1050 EXPECT_EQ("Blah", server_header);
1051
1052 // Reading should give EOF right away, since there is no message body
1053 // (despite non-zero content-length).
1054 std::string response_data;
1055 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421056 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231057 EXPECT_EQ("", response_data);
1058}
1059
[email protected]23e482282013-06-14 16:08:021060TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071061 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521062
1063 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351064 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1065 MockRead("hello"),
1066 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1067 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061068 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521069 };
[email protected]31a2bfe2010-02-09 08:03:391070 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071071 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521072
[email protected]0b0bf032010-09-21 18:08:501073 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521074 "hello", "world"
1075 };
1076
1077 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421078 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521079 request.method = "GET";
1080 request.url = GURL("http://www.google.com/");
1081 request.load_flags = 0;
1082
[email protected]262eec82013-03-19 21:01:361083 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271085
[email protected]49639fa2011-12-20 23:22:411086 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521087
[email protected]49639fa2011-12-20 23:22:411088 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421089 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521090
1091 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421092 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521093
[email protected]1c773ea12009-04-28 19:58:421094 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501095 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521096
[email protected]90499482013-06-01 00:39:501097 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251098 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151099 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521100
1101 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571102 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421103 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251104 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521105 }
1106}
1107
[email protected]23e482282013-06-14 16:08:021108TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061109 ScopedVector<UploadElementReader> element_readers;
1110 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201111 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271112
[email protected]1c773ea12009-04-28 19:58:421113 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521114 request.method = "POST";
1115 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271116 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521117 request.load_flags = 0;
1118
[email protected]3fe8d2f82013-10-17 08:56:071119 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271120 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271122
initial.commit586acc5fe2008-07-26 22:42:521123 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351124 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1125 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1126 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061127 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521128 };
[email protected]31a2bfe2010-02-09 08:03:391129 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071130 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521131
[email protected]49639fa2011-12-20 23:22:411132 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521133
[email protected]49639fa2011-12-20 23:22:411134 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421135 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521136
1137 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421138 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521139
[email protected]1c773ea12009-04-28 19:58:421140 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501141 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521142
[email protected]90499482013-06-01 00:39:501143 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251144 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521145
1146 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571147 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421148 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251149 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521150}
1151
[email protected]3a2d3662009-03-27 03:49:141152// This test is almost the same as Ignores100 above, but the response contains
1153// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571154// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021155TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421156 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141157 request.method = "GET";
1158 request.url = GURL("http://www.foo.com/");
1159 request.load_flags = 0;
1160
[email protected]3fe8d2f82013-10-17 08:56:071161 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271162 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071163 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271164
[email protected]3a2d3662009-03-27 03:49:141165 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571166 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1167 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141168 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061169 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141170 };
[email protected]31a2bfe2010-02-09 08:03:391171 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071172 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141173
[email protected]49639fa2011-12-20 23:22:411174 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141175
[email protected]49639fa2011-12-20 23:22:411176 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421177 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141178
1179 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421180 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141181
[email protected]1c773ea12009-04-28 19:58:421182 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501183 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141184
[email protected]90499482013-06-01 00:39:501185 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141186 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1187
1188 std::string response_data;
1189 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421190 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141191 EXPECT_EQ("hello world", response_data);
1192}
1193
[email protected]23e482282013-06-14 16:08:021194TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381195 HttpRequestInfo request;
1196 request.method = "POST";
1197 request.url = GURL("http://www.foo.com/");
1198 request.load_flags = 0;
1199
[email protected]3fe8d2f82013-10-17 08:56:071200 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271201 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271203
[email protected]ee9410e72010-01-07 01:42:381204 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061205 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1206 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381207 };
[email protected]31a2bfe2010-02-09 08:03:391208 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071209 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381210
[email protected]49639fa2011-12-20 23:22:411211 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381212
[email protected]49639fa2011-12-20 23:22:411213 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381214 EXPECT_EQ(ERR_IO_PENDING, rv);
1215
1216 rv = callback.WaitForResult();
1217 EXPECT_EQ(OK, rv);
1218
1219 std::string response_data;
1220 rv = ReadTransaction(trans.get(), &response_data);
1221 EXPECT_EQ(OK, rv);
1222 EXPECT_EQ("", response_data);
1223}
1224
[email protected]23e482282013-06-14 16:08:021225TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381226 HttpRequestInfo request;
1227 request.method = "POST";
1228 request.url = GURL("http://www.foo.com/");
1229 request.load_flags = 0;
1230
[email protected]3fe8d2f82013-10-17 08:56:071231 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271232 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071233 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1234
[email protected]cb9bf6ca2011-01-28 13:15:271235
[email protected]ee9410e72010-01-07 01:42:381236 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061237 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381238 };
[email protected]31a2bfe2010-02-09 08:03:391239 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071240 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381241
[email protected]49639fa2011-12-20 23:22:411242 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381243
[email protected]49639fa2011-12-20 23:22:411244 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381245 EXPECT_EQ(ERR_IO_PENDING, rv);
1246
1247 rv = callback.WaitForResult();
1248 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1249}
1250
[email protected]23e482282013-06-14 16:08:021251void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511252 const MockWrite* write_failure,
1253 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421254 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521255 request.method = "GET";
1256 request.url = GURL("http://www.foo.com/");
1257 request.load_flags = 0;
1258
[email protected]58e32bb2013-01-21 18:23:251259 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071260 session_deps_.net_log = &net_log;
1261 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271262
[email protected]202965992011-12-07 23:04:511263 // Written data for successfully sending both requests.
1264 MockWrite data1_writes[] = {
1265 MockWrite("GET / HTTP/1.1\r\n"
1266 "Host: www.foo.com\r\n"
1267 "Connection: keep-alive\r\n\r\n"),
1268 MockWrite("GET / HTTP/1.1\r\n"
1269 "Host: www.foo.com\r\n"
1270 "Connection: keep-alive\r\n\r\n")
1271 };
1272
1273 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521274 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351275 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1276 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061277 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521278 };
[email protected]202965992011-12-07 23:04:511279
1280 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491281 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511282 data1_writes[1] = *write_failure;
1283 } else {
1284 ASSERT_TRUE(read_failure);
1285 data1_reads[2] = *read_failure;
1286 }
1287
1288 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1289 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071290 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521291
1292 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351293 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1294 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061295 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521296 };
[email protected]31a2bfe2010-02-09 08:03:391297 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071298 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521299
1300 const char* kExpectedResponseData[] = {
1301 "hello", "world"
1302 };
1303
[email protected]58e32bb2013-01-21 18:23:251304 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521305 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411306 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521307
[email protected]262eec82013-03-19 21:01:361308 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501309 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521310
[email protected]49639fa2011-12-20 23:22:411311 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421312 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521313
1314 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421315 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521316
[email protected]58e32bb2013-01-21 18:23:251317 LoadTimingInfo load_timing_info;
1318 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1319 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1320 if (i == 0) {
1321 first_socket_log_id = load_timing_info.socket_log_id;
1322 } else {
1323 // The second request should be using a new socket.
1324 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1325 }
1326
[email protected]1c773ea12009-04-28 19:58:421327 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501328 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521329
[email protected]90499482013-06-01 00:39:501330 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251331 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521332
1333 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571334 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421335 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251336 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521337 }
1338}
[email protected]3d2a59b2008-09-26 19:44:251339
[email protected]a34f61ee2014-03-18 20:59:491340void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1341 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101342 const MockRead* read_failure,
1343 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491344 HttpRequestInfo request;
1345 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101346 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491347 request.load_flags = 0;
1348
1349 CapturingNetLog net_log;
1350 session_deps_.net_log = &net_log;
1351 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1352
[email protected]09356c652014-03-25 15:36:101353 SSLSocketDataProvider ssl1(ASYNC, OK);
1354 SSLSocketDataProvider ssl2(ASYNC, OK);
1355 if (use_spdy) {
1356 ssl1.SetNextProto(GetParam());
1357 ssl2.SetNextProto(GetParam());
1358 }
1359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491361
[email protected]09356c652014-03-25 15:36:101362 // SPDY versions of the request and response.
1363 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1364 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1365 scoped_ptr<SpdyFrame> spdy_response(
1366 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1367 scoped_ptr<SpdyFrame> spdy_data(
1368 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491369
[email protected]09356c652014-03-25 15:36:101370 // HTTP/1.1 versions of the request and response.
1371 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1372 "Host: www.foo.com\r\n"
1373 "Connection: keep-alive\r\n\r\n";
1374 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1375 const char kHttpData[] = "hello";
1376
1377 std::vector<MockRead> data1_reads;
1378 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491379 if (write_failure) {
1380 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101381 data1_writes.push_back(*write_failure);
1382 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491383 } else {
1384 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101385 if (use_spdy) {
1386 data1_writes.push_back(CreateMockWrite(*spdy_request));
1387 } else {
1388 data1_writes.push_back(MockWrite(kHttpRequest));
1389 }
1390 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491391 }
1392
[email protected]09356c652014-03-25 15:36:101393 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1394 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491395 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1396
[email protected]09356c652014-03-25 15:36:101397 std::vector<MockRead> data2_reads;
1398 std::vector<MockWrite> data2_writes;
1399
1400 if (use_spdy) {
1401 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1402
1403 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1404 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1405 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1406 } else {
1407 data2_writes.push_back(
1408 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1409
1410 data2_reads.push_back(
1411 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1412 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1413 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1414 }
1415 OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1416 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491417 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1418
1419 // Preconnect a socket.
1420 net::SSLConfig ssl_config;
1421 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231422 session->GetNextProtos(&ssl_config.next_protos);
[email protected]a34f61ee2014-03-18 20:59:491423 session->http_stream_factory()->PreconnectStreams(
1424 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1425 // Wait for the preconnect to complete.
1426 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1427 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101428 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491429
1430 // Make the request.
1431 TestCompletionCallback callback;
1432
1433 scoped_ptr<HttpTransaction> trans(
1434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1435
1436 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1437 EXPECT_EQ(ERR_IO_PENDING, rv);
1438
1439 rv = callback.WaitForResult();
1440 EXPECT_EQ(OK, rv);
1441
1442 LoadTimingInfo load_timing_info;
1443 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101444 TestLoadTimingNotReused(
1445 load_timing_info,
1446 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491447
1448 const HttpResponseInfo* response = trans->GetResponseInfo();
1449 ASSERT_TRUE(response != NULL);
1450
1451 EXPECT_TRUE(response->headers.get() != NULL);
1452 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1453
1454 std::string response_data;
1455 rv = ReadTransaction(trans.get(), &response_data);
1456 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101457 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491458}
1459
[email protected]23e482282013-06-14 16:08:021460TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231461 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061462 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511463 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1464}
1465
[email protected]23e482282013-06-14 16:08:021466TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061467 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511468 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251469}
1470
[email protected]23e482282013-06-14 16:08:021471TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061472 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511473 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251474}
1475
[email protected]d58ceea82014-06-04 10:55:541476// Make sure that on a 408 response (Request Timeout), the request is retried,
1477// if the socket was a reused keep alive socket.
1478TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1479 MockRead read_failure(SYNCHRONOUS,
1480 "HTTP/1.1 408 Request Timeout\r\n"
1481 "Connection: Keep-Alive\r\n"
1482 "Content-Length: 6\r\n\r\n"
1483 "Pickle");
1484 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1485}
1486
[email protected]a34f61ee2014-03-18 20:59:491487TEST_P(HttpNetworkTransactionTest,
1488 PreconnectErrorNotConnectedOnWrite) {
1489 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101490 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491491}
1492
1493TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1494 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101495 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491496}
1497
1498TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1499 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101500 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1501}
1502
1503TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1504 MockRead read_failure(ASYNC, OK); // EOF
1505 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1506}
1507
[email protected]d58ceea82014-06-04 10:55:541508// Make sure that on a 408 response (Request Timeout), the request is retried,
1509// if the socket was a preconnected (UNUSED_IDLE) socket.
1510TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1511 MockRead read_failure(SYNCHRONOUS,
1512 "HTTP/1.1 408 Request Timeout\r\n"
1513 "Connection: Keep-Alive\r\n"
1514 "Content-Length: 6\r\n\r\n"
1515 "Pickle");
1516 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1517 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1518}
1519
[email protected]09356c652014-03-25 15:36:101520TEST_P(HttpNetworkTransactionTest,
1521 SpdyPreconnectErrorNotConnectedOnWrite) {
1522 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1523 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1524}
1525
1526TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1527 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1528 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1529}
1530
1531TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1532 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1533 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1534}
1535
1536TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1537 MockRead read_failure(ASYNC, OK); // EOF
1538 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491539}
1540
[email protected]23e482282013-06-14 16:08:021541TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421542 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251543 request.method = "GET";
1544 request.url = GURL("http://www.google.com/");
1545 request.load_flags = 0;
1546
[email protected]3fe8d2f82013-10-17 08:56:071547 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271548 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071549 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271550
[email protected]3d2a59b2008-09-26 19:44:251551 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061552 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351553 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1554 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061555 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251556 };
[email protected]31a2bfe2010-02-09 08:03:391557 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071558 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251559
[email protected]49639fa2011-12-20 23:22:411560 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251561
[email protected]49639fa2011-12-20 23:22:411562 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421563 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251564
1565 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421566 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251567
[email protected]1c773ea12009-04-28 19:58:421568 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251569 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251570}
1571
1572// What do various browsers do when the server closes a non-keepalive
1573// connection without sending any response header or body?
1574//
1575// IE7: error page
1576// Safari 3.1.2 (Windows): error page
1577// Firefox 3.0.1: blank page
1578// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421579// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1580// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021581TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251582 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061583 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351584 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1585 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061586 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251587 };
[email protected]31a2bfe2010-02-09 08:03:391588 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1589 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421590 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251591}
[email protected]038e9a32008-10-08 22:40:161592
[email protected]1826a402014-01-08 15:40:481593// Test that network access can be deferred and resumed.
1594TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1595 HttpRequestInfo request;
1596 request.method = "GET";
1597 request.url = GURL("http://www.google.com/");
1598 request.load_flags = 0;
1599
1600 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1601 scoped_ptr<HttpTransaction> trans(
1602 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1603
1604 // Defer on OnBeforeNetworkStart.
1605 BeforeNetworkStartHandler net_start_handler(true); // defer
1606 trans->SetBeforeNetworkStartCallback(
1607 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1608 base::Unretained(&net_start_handler)));
1609
1610 MockRead data_reads[] = {
1611 MockRead("HTTP/1.0 200 OK\r\n"),
1612 MockRead("Content-Length: 5\r\n\r\n"),
1613 MockRead("hello"),
1614 MockRead(SYNCHRONOUS, 0),
1615 };
1616 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1617 session_deps_.socket_factory->AddSocketDataProvider(&data);
1618
1619 TestCompletionCallback callback;
1620
1621 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1622 EXPECT_EQ(ERR_IO_PENDING, rv);
1623 base::MessageLoop::current()->RunUntilIdle();
1624
1625 // Should have deferred for network start.
1626 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1627 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1628 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1629
1630 trans->ResumeNetworkStart();
1631 rv = callback.WaitForResult();
1632 EXPECT_EQ(OK, rv);
1633 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1634
1635 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1636 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1637 if (rv == ERR_IO_PENDING)
1638 rv = callback.WaitForResult();
1639 EXPECT_EQ(5, rv);
1640 trans.reset();
1641}
1642
1643// Test that network use can be deferred and canceled.
1644TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1645 HttpRequestInfo request;
1646 request.method = "GET";
1647 request.url = GURL("http://www.google.com/");
1648 request.load_flags = 0;
1649
1650 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1651 scoped_ptr<HttpTransaction> trans(
1652 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1653
1654 // Defer on OnBeforeNetworkStart.
1655 BeforeNetworkStartHandler net_start_handler(true); // defer
1656 trans->SetBeforeNetworkStartCallback(
1657 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1658 base::Unretained(&net_start_handler)));
1659
1660 TestCompletionCallback callback;
1661
1662 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1663 EXPECT_EQ(ERR_IO_PENDING, rv);
1664 base::MessageLoop::current()->RunUntilIdle();
1665
1666 // Should have deferred for network start.
1667 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1668 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1669 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1670}
1671
[email protected]7a5378b2012-11-04 03:25:171672// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1673// tests. There was a bug causing HttpNetworkTransaction to hang in the
1674// destructor in such situations.
1675// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021676TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171677 HttpRequestInfo request;
1678 request.method = "GET";
1679 request.url = GURL("http://www.google.com/");
1680 request.load_flags = 0;
1681
[email protected]bb88e1d32013-05-03 23:11:071682 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361683 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501684 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171685
1686 MockRead data_reads[] = {
1687 MockRead("HTTP/1.0 200 OK\r\n"),
1688 MockRead("Connection: keep-alive\r\n"),
1689 MockRead("Content-Length: 100\r\n\r\n"),
1690 MockRead("hello"),
1691 MockRead(SYNCHRONOUS, 0),
1692 };
1693 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071694 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171695
1696 TestCompletionCallback callback;
1697
1698 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1699 EXPECT_EQ(ERR_IO_PENDING, rv);
1700
1701 rv = callback.WaitForResult();
1702 EXPECT_EQ(OK, rv);
1703
1704 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501705 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171706 if (rv == ERR_IO_PENDING)
1707 rv = callback.WaitForResult();
1708 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501709 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171710 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1711
1712 trans.reset();
[email protected]2da659e2013-05-23 20:51:341713 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171714 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1715}
1716
[email protected]23e482282013-06-14 16:08:021717TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171718 HttpRequestInfo request;
1719 request.method = "GET";
1720 request.url = GURL("http://www.google.com/");
1721 request.load_flags = 0;
1722
[email protected]bb88e1d32013-05-03 23:11:071723 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361724 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501725 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171726
1727 MockRead data_reads[] = {
1728 MockRead("HTTP/1.0 200 OK\r\n"),
1729 MockRead("Connection: keep-alive\r\n"),
1730 MockRead("Content-Length: 100\r\n\r\n"),
1731 MockRead(SYNCHRONOUS, 0),
1732 };
1733 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071734 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171735
1736 TestCompletionCallback callback;
1737
1738 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1739 EXPECT_EQ(ERR_IO_PENDING, rv);
1740
1741 rv = callback.WaitForResult();
1742 EXPECT_EQ(OK, rv);
1743
1744 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501745 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171746 if (rv == ERR_IO_PENDING)
1747 rv = callback.WaitForResult();
1748 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1749
1750 trans.reset();
[email protected]2da659e2013-05-23 20:51:341751 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171752 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1753}
1754
[email protected]0b0bf032010-09-21 18:08:501755// Test that we correctly reuse a keep-alive connection after not explicitly
1756// reading the body.
[email protected]23e482282013-06-14 16:08:021757TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131758 HttpRequestInfo request;
1759 request.method = "GET";
1760 request.url = GURL("http://www.foo.com/");
1761 request.load_flags = 0;
1762
[email protected]58e32bb2013-01-21 18:23:251763 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071764 session_deps_.net_log = &net_log;
1765 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271766
[email protected]0b0bf032010-09-21 18:08:501767 // Note that because all these reads happen in the same
1768 // StaticSocketDataProvider, it shows that the same socket is being reused for
1769 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131770 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501771 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1772 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131773 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501774 MockRead("HTTP/1.1 302 Found\r\n"
1775 "Content-Length: 0\r\n\r\n"),
1776 MockRead("HTTP/1.1 302 Found\r\n"
1777 "Content-Length: 5\r\n\r\n"
1778 "hello"),
1779 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1780 "Content-Length: 0\r\n\r\n"),
1781 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1782 "Content-Length: 5\r\n\r\n"
1783 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131784 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1785 MockRead("hello"),
1786 };
1787 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071788 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131789
1790 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061791 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131792 };
1793 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071794 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131795
[email protected]0b0bf032010-09-21 18:08:501796 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1797 std::string response_lines[kNumUnreadBodies];
1798
[email protected]58e32bb2013-01-21 18:23:251799 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501800 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411801 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131802
[email protected]262eec82013-03-19 21:01:361803 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131805
[email protected]49639fa2011-12-20 23:22:411806 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131807 EXPECT_EQ(ERR_IO_PENDING, rv);
1808
1809 rv = callback.WaitForResult();
1810 EXPECT_EQ(OK, rv);
1811
[email protected]58e32bb2013-01-21 18:23:251812 LoadTimingInfo load_timing_info;
1813 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1814 if (i == 0) {
1815 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1816 first_socket_log_id = load_timing_info.socket_log_id;
1817 } else {
1818 TestLoadTimingReused(load_timing_info);
1819 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1820 }
1821
[email protected]fc31d6a42010-06-24 18:05:131822 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501823 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131824
[email protected]90499482013-06-01 00:39:501825 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501826 response_lines[i] = response->headers->GetStatusLine();
1827
1828 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131829 }
[email protected]0b0bf032010-09-21 18:08:501830
1831 const char* const kStatusLines[] = {
1832 "HTTP/1.1 204 No Content",
1833 "HTTP/1.1 205 Reset Content",
1834 "HTTP/1.1 304 Not Modified",
1835 "HTTP/1.1 302 Found",
1836 "HTTP/1.1 302 Found",
1837 "HTTP/1.1 301 Moved Permanently",
1838 "HTTP/1.1 301 Moved Permanently",
1839 };
1840
1841 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1842 forgot_to_update_kStatusLines);
1843
1844 for (int i = 0; i < kNumUnreadBodies; ++i)
1845 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1846
[email protected]49639fa2011-12-20 23:22:411847 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361848 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411850 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501851 EXPECT_EQ(ERR_IO_PENDING, rv);
1852 rv = callback.WaitForResult();
1853 EXPECT_EQ(OK, rv);
1854 const HttpResponseInfo* response = trans->GetResponseInfo();
1855 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501856 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501857 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1858 std::string response_data;
1859 rv = ReadTransaction(trans.get(), &response_data);
1860 EXPECT_EQ(OK, rv);
1861 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131862}
1863
[email protected]038e9a32008-10-08 22:40:161864// Test the request-challenge-retry sequence for basic auth.
1865// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021866TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421867 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161868 request.method = "GET";
1869 request.url = GURL("http://www.google.com/");
1870 request.load_flags = 0;
1871
[email protected]58e32bb2013-01-21 18:23:251872 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071873 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071874 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271875 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071876 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271877
[email protected]f9ee6b52008-11-08 06:46:231878 MockWrite data_writes1[] = {
1879 MockWrite("GET / HTTP/1.1\r\n"
1880 "Host: www.google.com\r\n"
1881 "Connection: keep-alive\r\n\r\n"),
1882 };
1883
[email protected]038e9a32008-10-08 22:40:161884 MockRead data_reads1[] = {
1885 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1886 // Give a couple authenticate options (only the middle one is actually
1887 // supported).
[email protected]22927ad2009-09-21 19:56:191888 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161889 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1890 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1891 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1892 // Large content-length -- won't matter, as connection will be reset.
1893 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061894 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161895 };
1896
1897 // After calling trans->RestartWithAuth(), this is the request we should
1898 // be issuing -- the final header line contains the credentials.
1899 MockWrite data_writes2[] = {
1900 MockWrite("GET / HTTP/1.1\r\n"
1901 "Host: www.google.com\r\n"
1902 "Connection: keep-alive\r\n"
1903 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1904 };
1905
1906 // Lastly, the server responds with the actual content.
1907 MockRead data_reads2[] = {
1908 MockRead("HTTP/1.0 200 OK\r\n"),
1909 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1910 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061911 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161912 };
1913
[email protected]31a2bfe2010-02-09 08:03:391914 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1915 data_writes1, arraysize(data_writes1));
1916 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1917 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071918 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1919 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161920
[email protected]49639fa2011-12-20 23:22:411921 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161922
[email protected]49639fa2011-12-20 23:22:411923 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421924 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161925
1926 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421927 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161928
[email protected]58e32bb2013-01-21 18:23:251929 LoadTimingInfo load_timing_info1;
1930 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1931 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1932
[email protected]b8015c42013-12-24 15:18:191933 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1934 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1935
[email protected]1c773ea12009-04-28 19:58:421936 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501937 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041938 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161939
[email protected]49639fa2011-12-20 23:22:411940 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161941
[email protected]49639fa2011-12-20 23:22:411942 rv = trans->RestartWithAuth(
1943 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421944 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161945
1946 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421947 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161948
[email protected]58e32bb2013-01-21 18:23:251949 LoadTimingInfo load_timing_info2;
1950 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1951 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1952 // The load timing after restart should have a new socket ID, and times after
1953 // those of the first load timing.
1954 EXPECT_LE(load_timing_info1.receive_headers_end,
1955 load_timing_info2.connect_timing.connect_start);
1956 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1957
[email protected]b8015c42013-12-24 15:18:191958 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1959 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1960
[email protected]038e9a32008-10-08 22:40:161961 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501962 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161963 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1964 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161965}
1966
[email protected]23e482282013-06-14 16:08:021967TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461968 HttpRequestInfo request;
1969 request.method = "GET";
1970 request.url = GURL("http://www.google.com/");
1971 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1972
[email protected]3fe8d2f82013-10-17 08:56:071973 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271974 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071975 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271976
[email protected]861fcd52009-08-26 02:33:461977 MockWrite data_writes[] = {
1978 MockWrite("GET / HTTP/1.1\r\n"
1979 "Host: www.google.com\r\n"
1980 "Connection: keep-alive\r\n\r\n"),
1981 };
1982
1983 MockRead data_reads[] = {
1984 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1985 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1986 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1987 // Large content-length -- won't matter, as connection will be reset.
1988 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061989 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461990 };
1991
[email protected]31a2bfe2010-02-09 08:03:391992 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1993 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071994 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411995 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461996
[email protected]49639fa2011-12-20 23:22:411997 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461998 EXPECT_EQ(ERR_IO_PENDING, rv);
1999
2000 rv = callback.WaitForResult();
2001 EXPECT_EQ(0, rv);
2002
[email protected]b8015c42013-12-24 15:18:192003 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2004 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2005
[email protected]861fcd52009-08-26 02:33:462006 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502007 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462008 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2009}
2010
[email protected]2d2697f92009-02-18 21:00:322011// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2012// connection.
[email protected]23e482282013-06-14 16:08:022013TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422014 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322015 request.method = "GET";
2016 request.url = GURL("http://www.google.com/");
2017 request.load_flags = 0;
2018
[email protected]58e32bb2013-01-21 18:23:252019 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072020 session_deps_.net_log = &log;
2021 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272022
[email protected]2d2697f92009-02-18 21:00:322023 MockWrite data_writes1[] = {
2024 MockWrite("GET / HTTP/1.1\r\n"
2025 "Host: www.google.com\r\n"
2026 "Connection: keep-alive\r\n\r\n"),
2027
2028 // After calling trans->RestartWithAuth(), this is the request we should
2029 // be issuing -- the final header line contains the credentials.
2030 MockWrite("GET / HTTP/1.1\r\n"
2031 "Host: www.google.com\r\n"
2032 "Connection: keep-alive\r\n"
2033 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2034 };
2035
2036 MockRead data_reads1[] = {
2037 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2038 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2039 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2040 MockRead("Content-Length: 14\r\n\r\n"),
2041 MockRead("Unauthorized\r\n"),
2042
2043 // Lastly, the server responds with the actual content.
2044 MockRead("HTTP/1.1 200 OK\r\n"),
2045 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502046 MockRead("Content-Length: 5\r\n\r\n"),
2047 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322048 };
2049
[email protected]2d0a4f92011-05-05 16:38:462050 // If there is a regression where we disconnect a Keep-Alive
2051 // connection during an auth roundtrip, we'll end up reading this.
2052 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062053 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462054 };
2055
[email protected]31a2bfe2010-02-09 08:03:392056 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2057 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462058 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2059 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072060 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2061 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322062
[email protected]49639fa2011-12-20 23:22:412063 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322064
[email protected]262eec82013-03-19 21:01:362065 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412067 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422068 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322069
2070 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422071 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322072
[email protected]58e32bb2013-01-21 18:23:252073 LoadTimingInfo load_timing_info1;
2074 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2075 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2076
[email protected]1c773ea12009-04-28 19:58:422077 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502078 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042079 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322080
[email protected]49639fa2011-12-20 23:22:412081 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322082
[email protected]49639fa2011-12-20 23:22:412083 rv = trans->RestartWithAuth(
2084 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422085 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322086
2087 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422088 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322089
[email protected]58e32bb2013-01-21 18:23:252090 LoadTimingInfo load_timing_info2;
2091 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2092 TestLoadTimingReused(load_timing_info2);
2093 // The load timing after restart should have the same socket ID, and times
2094 // those of the first load timing.
2095 EXPECT_LE(load_timing_info1.receive_headers_end,
2096 load_timing_info2.send_start);
2097 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2098
[email protected]2d2697f92009-02-18 21:00:322099 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502100 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322101 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502102 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192103
2104 std::string response_data;
2105 rv = ReadTransaction(trans.get(), &response_data);
2106 EXPECT_EQ(OK, rv);
2107 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2108 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322109}
2110
2111// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2112// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022113TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422114 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322115 request.method = "GET";
2116 request.url = GURL("http://www.google.com/");
2117 request.load_flags = 0;
2118
[email protected]bb88e1d32013-05-03 23:11:072119 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272120
[email protected]2d2697f92009-02-18 21:00:322121 MockWrite data_writes1[] = {
2122 MockWrite("GET / HTTP/1.1\r\n"
2123 "Host: www.google.com\r\n"
2124 "Connection: keep-alive\r\n\r\n"),
2125
2126 // After calling trans->RestartWithAuth(), this is the request we should
2127 // be issuing -- the final header line contains the credentials.
2128 MockWrite("GET / HTTP/1.1\r\n"
2129 "Host: www.google.com\r\n"
2130 "Connection: keep-alive\r\n"
2131 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2132 };
2133
[email protected]2d2697f92009-02-18 21:00:322134 MockRead data_reads1[] = {
2135 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2136 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312137 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322138
2139 // Lastly, the server responds with the actual content.
2140 MockRead("HTTP/1.1 200 OK\r\n"),
2141 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502142 MockRead("Content-Length: 5\r\n\r\n"),
2143 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322144 };
2145
[email protected]2d0a4f92011-05-05 16:38:462146 // An incorrect reconnect would cause this to be read.
2147 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062148 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462149 };
2150
[email protected]31a2bfe2010-02-09 08:03:392151 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2152 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462153 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2154 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072155 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2156 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322157
[email protected]49639fa2011-12-20 23:22:412158 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322159
[email protected]262eec82013-03-19 21:01:362160 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502161 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412162 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422163 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322164
2165 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422166 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322167
[email protected]1c773ea12009-04-28 19:58:422168 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502169 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042170 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322171
[email protected]49639fa2011-12-20 23:22:412172 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322173
[email protected]49639fa2011-12-20 23:22:412174 rv = trans->RestartWithAuth(
2175 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422176 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322177
2178 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422179 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322180
2181 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502182 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322183 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502184 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322185}
2186
2187// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2188// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022189TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422190 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322191 request.method = "GET";
2192 request.url = GURL("http://www.google.com/");
2193 request.load_flags = 0;
2194
[email protected]bb88e1d32013-05-03 23:11:072195 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272196
[email protected]2d2697f92009-02-18 21:00:322197 MockWrite data_writes1[] = {
2198 MockWrite("GET / HTTP/1.1\r\n"
2199 "Host: www.google.com\r\n"
2200 "Connection: keep-alive\r\n\r\n"),
2201
2202 // After calling trans->RestartWithAuth(), this is the request we should
2203 // be issuing -- the final header line contains the credentials.
2204 MockWrite("GET / HTTP/1.1\r\n"
2205 "Host: www.google.com\r\n"
2206 "Connection: keep-alive\r\n"
2207 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2208 };
2209
2210 // Respond with 5 kb of response body.
2211 std::string large_body_string("Unauthorized");
2212 large_body_string.append(5 * 1024, ' ');
2213 large_body_string.append("\r\n");
2214
2215 MockRead data_reads1[] = {
2216 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2217 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2218 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2219 // 5134 = 12 + 5 * 1024 + 2
2220 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062221 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322222
2223 // Lastly, the server responds with the actual content.
2224 MockRead("HTTP/1.1 200 OK\r\n"),
2225 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502226 MockRead("Content-Length: 5\r\n\r\n"),
2227 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322228 };
2229
[email protected]2d0a4f92011-05-05 16:38:462230 // An incorrect reconnect would cause this to be read.
2231 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062232 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462233 };
2234
[email protected]31a2bfe2010-02-09 08:03:392235 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2236 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462237 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2238 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072239 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2240 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322241
[email protected]49639fa2011-12-20 23:22:412242 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322243
[email protected]262eec82013-03-19 21:01:362244 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502245 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412246 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422247 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322248
2249 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422250 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322251
[email protected]1c773ea12009-04-28 19:58:422252 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502253 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042254 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322255
[email protected]49639fa2011-12-20 23:22:412256 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322257
[email protected]49639fa2011-12-20 23:22:412258 rv = trans->RestartWithAuth(
2259 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422260 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322261
2262 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422263 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322264
2265 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502266 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322267 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502268 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322269}
2270
2271// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312272// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022273TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312274 HttpRequestInfo request;
2275 request.method = "GET";
2276 request.url = GURL("http://www.google.com/");
2277 request.load_flags = 0;
2278
[email protected]bb88e1d32013-05-03 23:11:072279 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272280
[email protected]11203f012009-11-12 23:02:312281 MockWrite data_writes1[] = {
2282 MockWrite("GET / HTTP/1.1\r\n"
2283 "Host: www.google.com\r\n"
2284 "Connection: keep-alive\r\n\r\n"),
2285 // This simulates the seemingly successful write to a closed connection
2286 // if the bug is not fixed.
2287 MockWrite("GET / HTTP/1.1\r\n"
2288 "Host: www.google.com\r\n"
2289 "Connection: keep-alive\r\n"
2290 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2291 };
2292
2293 MockRead data_reads1[] = {
2294 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2295 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2296 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2297 MockRead("Content-Length: 14\r\n\r\n"),
2298 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062299 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312300 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062301 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312302 };
2303
2304 // After calling trans->RestartWithAuth(), this is the request we should
2305 // be issuing -- the final header line contains the credentials.
2306 MockWrite data_writes2[] = {
2307 MockWrite("GET / HTTP/1.1\r\n"
2308 "Host: www.google.com\r\n"
2309 "Connection: keep-alive\r\n"
2310 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2311 };
2312
2313 // Lastly, the server responds with the actual content.
2314 MockRead data_reads2[] = {
2315 MockRead("HTTP/1.1 200 OK\r\n"),
2316 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502317 MockRead("Content-Length: 5\r\n\r\n"),
2318 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312319 };
2320
[email protected]31a2bfe2010-02-09 08:03:392321 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2322 data_writes1, arraysize(data_writes1));
2323 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2324 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2326 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312327
[email protected]49639fa2011-12-20 23:22:412328 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312329
[email protected]262eec82013-03-19 21:01:362330 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502331 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412332 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312333 EXPECT_EQ(ERR_IO_PENDING, rv);
2334
2335 rv = callback1.WaitForResult();
2336 EXPECT_EQ(OK, rv);
2337
2338 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502339 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042340 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312341
[email protected]49639fa2011-12-20 23:22:412342 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312343
[email protected]49639fa2011-12-20 23:22:412344 rv = trans->RestartWithAuth(
2345 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312346 EXPECT_EQ(ERR_IO_PENDING, rv);
2347
2348 rv = callback2.WaitForResult();
2349 EXPECT_EQ(OK, rv);
2350
2351 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502352 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312353 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502354 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312355}
2356
[email protected]394816e92010-08-03 07:38:592357// Test the request-challenge-retry sequence for basic auth, over a connection
2358// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022359TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:592360 HttpRequestInfo request;
2361 request.method = "GET";
2362 request.url = GURL("https://www.google.com/");
2363 // when the no authentication data flag is set.
2364 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2365
[email protected]cb9bf6ca2011-01-28 13:15:272366 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072367 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202368 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292369 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072370 session_deps_.net_log = log.bound().net_log();
2371 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272372
[email protected]394816e92010-08-03 07:38:592373 // Since we have proxy, should try to establish tunnel.
2374 MockWrite data_writes1[] = {
2375 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2376 "Host: www.google.com\r\n"
2377 "Proxy-Connection: keep-alive\r\n\r\n"),
2378
2379 // After calling trans->RestartWithAuth(), this is the request we should
2380 // be issuing -- the final header line contains the credentials.
2381 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2382 "Host: www.google.com\r\n"
2383 "Proxy-Connection: keep-alive\r\n"
2384 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2385
2386 MockWrite("GET / HTTP/1.1\r\n"
2387 "Host: www.google.com\r\n"
2388 "Connection: keep-alive\r\n\r\n"),
2389 };
2390
2391 // The proxy responds to the connect with a 407, using a persistent
2392 // connection.
2393 MockRead data_reads1[] = {
2394 // No credentials.
2395 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2396 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2397 MockRead("Proxy-Connection: close\r\n\r\n"),
2398
2399 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2400
2401 MockRead("HTTP/1.1 200 OK\r\n"),
2402 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502403 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062404 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592405 };
2406
2407 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2408 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072409 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062410 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072411 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592412
[email protected]49639fa2011-12-20 23:22:412413 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592414
[email protected]262eec82013-03-19 21:01:362415 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502416 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502417
[email protected]49639fa2011-12-20 23:22:412418 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592419 EXPECT_EQ(ERR_IO_PENDING, rv);
2420
2421 rv = callback1.WaitForResult();
2422 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572423 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402424 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592425 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402426 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592427 NetLog::PHASE_NONE);
2428 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402429 entries, pos,
[email protected]394816e92010-08-03 07:38:592430 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2431 NetLog::PHASE_NONE);
2432
2433 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502434 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502435 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592436 EXPECT_EQ(407, response->headers->response_code());
2437 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042438 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592439
[email protected]029c83b62013-01-24 05:28:202440 LoadTimingInfo load_timing_info;
2441 // CONNECT requests and responses are handled at the connect job level, so
2442 // the transaction does not yet have a connection.
2443 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2444
[email protected]49639fa2011-12-20 23:22:412445 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592446
[email protected]49639fa2011-12-20 23:22:412447 rv = trans->RestartWithAuth(
2448 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592449 EXPECT_EQ(ERR_IO_PENDING, rv);
2450
2451 rv = callback2.WaitForResult();
2452 EXPECT_EQ(OK, rv);
2453
2454 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502455 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592456
2457 EXPECT_TRUE(response->headers->IsKeepAlive());
2458 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502459 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592460 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2461
2462 // The password prompt info should not be set.
2463 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502464
[email protected]029c83b62013-01-24 05:28:202465 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2466 TestLoadTimingNotReusedWithPac(load_timing_info,
2467 CONNECT_TIMING_HAS_SSL_TIMES);
2468
[email protected]0b0bf032010-09-21 18:08:502469 trans.reset();
[email protected]102e27c2011-02-23 01:01:312470 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592471}
2472
[email protected]11203f012009-11-12 23:02:312473// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322474// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022475TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272476 HttpRequestInfo request;
2477 request.method = "GET";
2478 request.url = GURL("https://www.google.com/");
2479 // Ensure that proxy authentication is attempted even
2480 // when the no authentication data flag is set.
2481 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2482
[email protected]2d2697f92009-02-18 21:00:322483 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072484 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292485 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072486 session_deps_.net_log = log.bound().net_log();
2487 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322488
[email protected]262eec82013-03-19 21:01:362489 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502490 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322491
[email protected]2d2697f92009-02-18 21:00:322492 // Since we have proxy, should try to establish tunnel.
2493 MockWrite data_writes1[] = {
2494 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452495 "Host: www.google.com\r\n"
2496 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322497
2498 // After calling trans->RestartWithAuth(), this is the request we should
2499 // be issuing -- the final header line contains the credentials.
2500 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2501 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452502 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322503 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2504 };
2505
2506 // The proxy responds to the connect with a 407, using a persistent
2507 // connection.
2508 MockRead data_reads1[] = {
2509 // No credentials.
2510 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2511 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2512 MockRead("Content-Length: 10\r\n\r\n"),
2513 MockRead("0123456789"),
2514
2515 // Wrong credentials (wrong password).
2516 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2517 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2518 MockRead("Content-Length: 10\r\n\r\n"),
2519 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062520 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322521 };
2522
[email protected]31a2bfe2010-02-09 08:03:392523 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2524 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072525 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322526
[email protected]49639fa2011-12-20 23:22:412527 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322528
[email protected]49639fa2011-12-20 23:22:412529 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422530 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322531
2532 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422533 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572534 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402535 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392536 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402537 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392538 NetLog::PHASE_NONE);
2539 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402540 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392541 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2542 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322543
[email protected]1c773ea12009-04-28 19:58:422544 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502545 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502546 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322547 EXPECT_TRUE(response->headers->IsKeepAlive());
2548 EXPECT_EQ(407, response->headers->response_code());
2549 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422550 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042551 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322552
[email protected]49639fa2011-12-20 23:22:412553 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322554
2555 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412556 rv = trans->RestartWithAuth(
2557 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422558 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322559
2560 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422561 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322562
2563 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502564 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502565 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322566 EXPECT_TRUE(response->headers->IsKeepAlive());
2567 EXPECT_EQ(407, response->headers->response_code());
2568 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422569 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042570 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132571
[email protected]e60e47a2010-07-14 03:37:182572 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2573 // out of scope.
[email protected]102e27c2011-02-23 01:01:312574 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322575}
2576
[email protected]a8e9b162009-03-12 00:06:442577// Test that we don't read the response body when we fail to establish a tunnel,
2578// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022579TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272580 HttpRequestInfo request;
2581 request.method = "GET";
2582 request.url = GURL("https://www.google.com/");
2583 request.load_flags = 0;
2584
[email protected]a8e9b162009-03-12 00:06:442585 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072586 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442587
[email protected]bb88e1d32013-05-03 23:11:072588 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442589
[email protected]262eec82013-03-19 21:01:362590 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442592
[email protected]a8e9b162009-03-12 00:06:442593 // Since we have proxy, should try to establish tunnel.
2594 MockWrite data_writes[] = {
2595 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452596 "Host: www.google.com\r\n"
2597 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442598 };
2599
2600 // The proxy responds to the connect with a 407.
2601 MockRead data_reads[] = {
2602 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2603 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2604 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062605 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442606 };
2607
[email protected]31a2bfe2010-02-09 08:03:392608 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2609 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072610 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442611
[email protected]49639fa2011-12-20 23:22:412612 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442613
[email protected]49639fa2011-12-20 23:22:412614 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422615 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442616
2617 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422618 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442619
[email protected]1c773ea12009-04-28 19:58:422620 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502621 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442622
2623 EXPECT_TRUE(response->headers->IsKeepAlive());
2624 EXPECT_EQ(407, response->headers->response_code());
2625 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422626 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442627
2628 std::string response_data;
2629 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422630 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182631
2632 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312633 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442634}
2635
[email protected]8fdbcd22010-05-05 02:54:522636// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2637// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022638TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522639 HttpRequestInfo request;
2640 request.method = "GET";
2641 request.url = GURL("http://www.google.com/");
2642 request.load_flags = 0;
2643
[email protected]cb9bf6ca2011-01-28 13:15:272644 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072645 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272646 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:072647 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:272648
[email protected]8fdbcd22010-05-05 02:54:522649 MockWrite data_writes1[] = {
2650 MockWrite("GET / HTTP/1.1\r\n"
2651 "Host: www.google.com\r\n"
2652 "Connection: keep-alive\r\n\r\n"),
2653 };
2654
2655 MockRead data_reads1[] = {
2656 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2657 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2658 // Large content-length -- won't matter, as connection will be reset.
2659 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062660 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522661 };
2662
2663 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2664 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072665 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522666
[email protected]49639fa2011-12-20 23:22:412667 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522668
[email protected]49639fa2011-12-20 23:22:412669 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522670 EXPECT_EQ(ERR_IO_PENDING, rv);
2671
2672 rv = callback.WaitForResult();
2673 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2674}
2675
[email protected]7a67a8152010-11-05 18:31:102676// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2677// through a non-authenticating proxy. The request should fail with
2678// ERR_UNEXPECTED_PROXY_AUTH.
2679// Note that it is impossible to detect if an HTTP server returns a 407 through
2680// a non-authenticating proxy - there is nothing to indicate whether the
2681// response came from the proxy or the server, so it is treated as if the proxy
2682// issued the challenge.
[email protected]23e482282013-06-14 16:08:022683TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232684 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272685 HttpRequestInfo request;
2686 request.method = "GET";
2687 request.url = GURL("https://www.google.com/");
2688
[email protected]bb88e1d32013-05-03 23:11:072689 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292690 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072691 session_deps_.net_log = log.bound().net_log();
2692 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102693
[email protected]7a67a8152010-11-05 18:31:102694 // Since we have proxy, should try to establish tunnel.
2695 MockWrite data_writes1[] = {
2696 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2697 "Host: www.google.com\r\n"
2698 "Proxy-Connection: keep-alive\r\n\r\n"),
2699
2700 MockWrite("GET / HTTP/1.1\r\n"
2701 "Host: www.google.com\r\n"
2702 "Connection: keep-alive\r\n\r\n"),
2703 };
2704
2705 MockRead data_reads1[] = {
2706 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2707
2708 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2709 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2710 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062711 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102712 };
2713
2714 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2715 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072716 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062717 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072718 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102719
[email protected]49639fa2011-12-20 23:22:412720 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102721
[email protected]262eec82013-03-19 21:01:362722 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502723 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102724
[email protected]49639fa2011-12-20 23:22:412725 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102726 EXPECT_EQ(ERR_IO_PENDING, rv);
2727
2728 rv = callback1.WaitForResult();
2729 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572730 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402731 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102732 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402733 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102734 NetLog::PHASE_NONE);
2735 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402736 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102737 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2738 NetLog::PHASE_NONE);
2739}
[email protected]2df19bb2010-08-25 20:13:462740
[email protected]029c83b62013-01-24 05:28:202741// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022742TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202743 HttpRequestInfo request1;
2744 request1.method = "GET";
2745 request1.url = GURL("https://www.google.com/1");
2746
2747 HttpRequestInfo request2;
2748 request2.method = "GET";
2749 request2.url = GURL("https://www.google.com/2");
2750
2751 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072752 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202753 ProxyService::CreateFixed("PROXY myproxy:70"));
2754 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072755 session_deps_.net_log = log.bound().net_log();
2756 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202757
2758 // Since we have proxy, should try to establish tunnel.
2759 MockWrite data_writes1[] = {
2760 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2761 "Host: www.google.com\r\n"
2762 "Proxy-Connection: keep-alive\r\n\r\n"),
2763
2764 MockWrite("GET /1 HTTP/1.1\r\n"
2765 "Host: www.google.com\r\n"
2766 "Connection: keep-alive\r\n\r\n"),
2767
2768 MockWrite("GET /2 HTTP/1.1\r\n"
2769 "Host: www.google.com\r\n"
2770 "Connection: keep-alive\r\n\r\n"),
2771 };
2772
2773 // The proxy responds to the connect with a 407, using a persistent
2774 // connection.
2775 MockRead data_reads1[] = {
2776 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2777
2778 MockRead("HTTP/1.1 200 OK\r\n"),
2779 MockRead("Content-Length: 1\r\n\r\n"),
2780 MockRead(SYNCHRONOUS, "1"),
2781
2782 MockRead("HTTP/1.1 200 OK\r\n"),
2783 MockRead("Content-Length: 2\r\n\r\n"),
2784 MockRead(SYNCHRONOUS, "22"),
2785 };
2786
2787 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2788 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072789 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202790 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072791 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202792
2793 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362794 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502795 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202796
2797 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2798 EXPECT_EQ(ERR_IO_PENDING, rv);
2799
2800 rv = callback1.WaitForResult();
2801 EXPECT_EQ(OK, rv);
2802
2803 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2804 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502805 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202806 EXPECT_EQ(1, response1->headers->GetContentLength());
2807
2808 LoadTimingInfo load_timing_info1;
2809 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2810 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2811
2812 trans1.reset();
2813
2814 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362815 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502816 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202817
2818 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2819 EXPECT_EQ(ERR_IO_PENDING, rv);
2820
2821 rv = callback2.WaitForResult();
2822 EXPECT_EQ(OK, rv);
2823
2824 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2825 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502826 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202827 EXPECT_EQ(2, response2->headers->GetContentLength());
2828
2829 LoadTimingInfo load_timing_info2;
2830 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2831 TestLoadTimingReused(load_timing_info2);
2832
2833 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2834
2835 trans2.reset();
2836 session->CloseAllConnections();
2837}
2838
2839// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022840TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202841 HttpRequestInfo request1;
2842 request1.method = "GET";
2843 request1.url = GURL("https://www.google.com/1");
2844
2845 HttpRequestInfo request2;
2846 request2.method = "GET";
2847 request2.url = GURL("https://www.google.com/2");
2848
2849 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072850 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202851 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2852 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072853 session_deps_.net_log = log.bound().net_log();
2854 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202855
2856 // Since we have proxy, should try to establish tunnel.
2857 MockWrite data_writes1[] = {
2858 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2859 "Host: www.google.com\r\n"
2860 "Proxy-Connection: keep-alive\r\n\r\n"),
2861
2862 MockWrite("GET /1 HTTP/1.1\r\n"
2863 "Host: www.google.com\r\n"
2864 "Connection: keep-alive\r\n\r\n"),
2865
2866 MockWrite("GET /2 HTTP/1.1\r\n"
2867 "Host: www.google.com\r\n"
2868 "Connection: keep-alive\r\n\r\n"),
2869 };
2870
2871 // The proxy responds to the connect with a 407, using a persistent
2872 // connection.
2873 MockRead data_reads1[] = {
2874 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2875
2876 MockRead("HTTP/1.1 200 OK\r\n"),
2877 MockRead("Content-Length: 1\r\n\r\n"),
2878 MockRead(SYNCHRONOUS, "1"),
2879
2880 MockRead("HTTP/1.1 200 OK\r\n"),
2881 MockRead("Content-Length: 2\r\n\r\n"),
2882 MockRead(SYNCHRONOUS, "22"),
2883 };
2884
2885 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2886 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072887 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202888 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072889 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202890
2891 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362892 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202894
2895 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2896 EXPECT_EQ(ERR_IO_PENDING, rv);
2897
2898 rv = callback1.WaitForResult();
2899 EXPECT_EQ(OK, rv);
2900
2901 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2902 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502903 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202904 EXPECT_EQ(1, response1->headers->GetContentLength());
2905
2906 LoadTimingInfo load_timing_info1;
2907 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2908 TestLoadTimingNotReusedWithPac(load_timing_info1,
2909 CONNECT_TIMING_HAS_SSL_TIMES);
2910
2911 trans1.reset();
2912
2913 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362914 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502915 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202916
2917 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2918 EXPECT_EQ(ERR_IO_PENDING, rv);
2919
2920 rv = callback2.WaitForResult();
2921 EXPECT_EQ(OK, rv);
2922
2923 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2924 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502925 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202926 EXPECT_EQ(2, response2->headers->GetContentLength());
2927
2928 LoadTimingInfo load_timing_info2;
2929 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2930 TestLoadTimingReusedWithPac(load_timing_info2);
2931
2932 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2933
2934 trans2.reset();
2935 session->CloseAllConnections();
2936}
2937
[email protected]2df19bb2010-08-25 20:13:462938// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022939TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272940 HttpRequestInfo request;
2941 request.method = "GET";
2942 request.url = GURL("http://www.google.com/");
2943
[email protected]2df19bb2010-08-25 20:13:462944 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072945 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112946 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292947 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072948 session_deps_.net_log = log.bound().net_log();
2949 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462950
[email protected]2df19bb2010-08-25 20:13:462951 // Since we have proxy, should use full url
2952 MockWrite data_writes1[] = {
2953 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2954 "Host: www.google.com\r\n"
2955 "Proxy-Connection: keep-alive\r\n\r\n"),
2956 };
2957
2958 MockRead data_reads1[] = {
2959 MockRead("HTTP/1.1 200 OK\r\n"),
2960 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2961 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062962 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462963 };
2964
2965 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2966 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072967 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062968 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072969 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462970
[email protected]49639fa2011-12-20 23:22:412971 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462972
[email protected]262eec82013-03-19 21:01:362973 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502974 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502975
[email protected]49639fa2011-12-20 23:22:412976 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462977 EXPECT_EQ(ERR_IO_PENDING, rv);
2978
2979 rv = callback1.WaitForResult();
2980 EXPECT_EQ(OK, rv);
2981
[email protected]58e32bb2013-01-21 18:23:252982 LoadTimingInfo load_timing_info;
2983 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2984 TestLoadTimingNotReused(load_timing_info,
2985 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2986
[email protected]2df19bb2010-08-25 20:13:462987 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502988 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462989
2990 EXPECT_TRUE(response->headers->IsKeepAlive());
2991 EXPECT_EQ(200, response->headers->response_code());
2992 EXPECT_EQ(100, response->headers->GetContentLength());
2993 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2994
2995 // The password prompt info should not be set.
2996 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2997}
2998
[email protected]7642b5ae2010-09-01 20:55:172999// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023000TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273001 HttpRequestInfo request;
3002 request.method = "GET";
3003 request.url = GURL("http://www.google.com/");
3004 request.load_flags = 0;
3005
[email protected]7642b5ae2010-09-01 20:55:173006 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073007 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113008 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293009 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073010 session_deps_.net_log = log.bound().net_log();
3011 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173012
[email protected]7642b5ae2010-09-01 20:55:173013 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463014 scoped_ptr<SpdyFrame> req(
3015 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:173016 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
3017
[email protected]23e482282013-06-14 16:08:023018 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3019 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173020 MockRead spdy_reads[] = {
3021 CreateMockRead(*resp),
3022 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:063023 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:173024 };
3025
[email protected]dd54bd82012-07-19 23:44:573026 DelayedSocketData spdy_data(
3027 1, // wait for one write to finish before reading.
3028 spdy_reads, arraysize(spdy_reads),
3029 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073030 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173031
[email protected]8ddf8322012-02-23 18:08:063032 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023033 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073034 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173035
[email protected]49639fa2011-12-20 23:22:413036 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173037
[email protected]262eec82013-03-19 21:01:363038 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503039 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503040
[email protected]49639fa2011-12-20 23:22:413041 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173042 EXPECT_EQ(ERR_IO_PENDING, rv);
3043
3044 rv = callback1.WaitForResult();
3045 EXPECT_EQ(OK, rv);
3046
[email protected]58e32bb2013-01-21 18:23:253047 LoadTimingInfo load_timing_info;
3048 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3049 TestLoadTimingNotReused(load_timing_info,
3050 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3051
[email protected]7642b5ae2010-09-01 20:55:173052 const HttpResponseInfo* response = trans->GetResponseInfo();
3053 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503054 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173055 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3056
3057 std::string response_data;
3058 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233059 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173060}
3061
[email protected]1c173852014-06-19 12:51:503062// Verifies that a session which races and wins against the owning transaction
3063// (completing prior to host resolution), doesn't fail the transaction.
3064// Regression test for crbug.com/334413.
3065TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3066 HttpRequestInfo request;
3067 request.method = "GET";
3068 request.url = GURL("http://www.google.com/");
3069 request.load_flags = 0;
3070
3071 // Configure SPDY proxy server "proxy:70".
3072 session_deps_.proxy_service.reset(
3073 ProxyService::CreateFixed("https://proxy:70"));
3074 CapturingBoundNetLog log;
3075 session_deps_.net_log = log.bound().net_log();
3076 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3077
3078 // Fetch http://www.google.com/ through the SPDY proxy.
3079 scoped_ptr<SpdyFrame> req(
3080 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3081 MockWrite spdy_writes[] = {CreateMockWrite(*req)};
3082
3083 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3084 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3085 MockRead spdy_reads[] = {
3086 CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
3087 };
3088
3089 DelayedSocketData spdy_data(
3090 1, // wait for one write to finish before reading.
3091 spdy_reads,
3092 arraysize(spdy_reads),
3093 spdy_writes,
3094 arraysize(spdy_writes));
3095 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3096
3097 SSLSocketDataProvider ssl(ASYNC, OK);
3098 ssl.SetNextProto(GetParam());
3099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3100
3101 TestCompletionCallback callback1;
3102
3103 scoped_ptr<HttpTransaction> trans(
3104 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3105
3106 // Stall the hostname resolution begun by the transaction.
3107 session_deps_.host_resolver->set_synchronous_mode(false);
3108 session_deps_.host_resolver->set_ondemand_mode(true);
3109
3110 int rv = trans->Start(&request, callback1.callback(), log.bound());
3111 EXPECT_EQ(ERR_IO_PENDING, rv);
3112
3113 // Race a session to the proxy, which completes first.
3114 session_deps_.host_resolver->set_ondemand_mode(false);
3115 SpdySessionKey key(
3116 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3117 base::WeakPtr<SpdySession> spdy_session =
3118 CreateSecureSpdySession(session, key, log.bound());
3119
3120 // Unstall the resolution begun by the transaction.
3121 session_deps_.host_resolver->set_ondemand_mode(true);
3122 session_deps_.host_resolver->ResolveAllPending();
3123
3124 EXPECT_FALSE(callback1.have_result());
3125 rv = callback1.WaitForResult();
3126 EXPECT_EQ(OK, rv);
3127
3128 const HttpResponseInfo* response = trans->GetResponseInfo();
3129 ASSERT_TRUE(response != NULL);
3130 ASSERT_TRUE(response->headers.get() != NULL);
3131 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3132
3133 std::string response_data;
3134 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3135 EXPECT_EQ(kUploadData, response_data);
3136}
3137
[email protected]dc7bd1c52010-11-12 00:01:133138// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023139TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273140 HttpRequestInfo request;
3141 request.method = "GET";
3142 request.url = GURL("http://www.google.com/");
3143 request.load_flags = 0;
3144
[email protected]79cb5c12011-09-12 13:12:043145 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073146 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043147 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293148 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073149 session_deps_.net_log = log.bound().net_log();
3150 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133151
[email protected]dc7bd1c52010-11-12 00:01:133152 // The first request will be a bare GET, the second request will be a
3153 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193154 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463155 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133156 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463157 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133158 };
[email protected]ff98d7f02012-03-22 21:44:193159 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463160 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3161 arraysize(kExtraAuthorizationHeaders) / 2,
3162 false,
3163 3,
3164 LOWEST,
3165 false));
[email protected]dc7bd1c52010-11-12 00:01:133166 MockWrite spdy_writes[] = {
3167 CreateMockWrite(*req_get, 1),
3168 CreateMockWrite(*req_get_authorization, 4),
3169 };
3170
3171 // The first response is a 407 proxy authentication challenge, and the second
3172 // response will be a 200 response since the second request includes a valid
3173 // Authorization header.
3174 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463175 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133176 };
[email protected]ff98d7f02012-03-22 21:44:193177 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023178 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133179 "407 Proxy Authentication Required",
3180 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3181 1));
[email protected]ff98d7f02012-03-22 21:44:193182 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023183 spdy_util_.ConstructSpdyBodyFrame(1, true));
3184 scoped_ptr<SpdyFrame> resp_data(
3185 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3186 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133187 MockRead spdy_reads[] = {
3188 CreateMockRead(*resp_authentication, 2),
3189 CreateMockRead(*body_authentication, 3),
3190 CreateMockRead(*resp_data, 5),
3191 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:063192 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:133193 };
3194
[email protected]dd54bd82012-07-19 23:44:573195 OrderedSocketData data(
3196 spdy_reads, arraysize(spdy_reads),
3197 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073198 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133199
[email protected]8ddf8322012-02-23 18:08:063200 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023201 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073202 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133203
[email protected]49639fa2011-12-20 23:22:413204 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133205
[email protected]262eec82013-03-19 21:01:363206 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503207 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133208
[email protected]49639fa2011-12-20 23:22:413209 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133210 EXPECT_EQ(ERR_IO_PENDING, rv);
3211
3212 rv = callback1.WaitForResult();
3213 EXPECT_EQ(OK, rv);
3214
3215 const HttpResponseInfo* const response = trans->GetResponseInfo();
3216
3217 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503218 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133219 EXPECT_EQ(407, response->headers->response_code());
3220 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043221 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133222
[email protected]49639fa2011-12-20 23:22:413223 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133224
[email protected]49639fa2011-12-20 23:22:413225 rv = trans->RestartWithAuth(
3226 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133227 EXPECT_EQ(ERR_IO_PENDING, rv);
3228
3229 rv = callback2.WaitForResult();
3230 EXPECT_EQ(OK, rv);
3231
3232 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3233
3234 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503235 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133236 EXPECT_EQ(200, response_restart->headers->response_code());
3237 // The password prompt info should not be set.
3238 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3239}
3240
[email protected]d9da5fe2010-10-13 22:37:163241// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023242TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273243 HttpRequestInfo request;
3244 request.method = "GET";
3245 request.url = GURL("https://www.google.com/");
3246 request.load_flags = 0;
3247
[email protected]d9da5fe2010-10-13 22:37:163248 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073249 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113250 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293251 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073252 session_deps_.net_log = log.bound().net_log();
3253 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163254
[email protected]262eec82013-03-19 21:01:363255 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503256 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163257
[email protected]d9da5fe2010-10-13 22:37:163258 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543259 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3260 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163261 // fetch https://www.google.com/ via HTTP
3262
3263 const char get[] = "GET / HTTP/1.1\r\n"
3264 "Host: www.google.com\r\n"
3265 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193266 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023267 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3268 scoped_ptr<SpdyFrame> conn_resp(
3269 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163270 const char resp[] = "HTTP/1.1 200 OK\r\n"
3271 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193272 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023273 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193274 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023275 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193276 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203277 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043278
3279 MockWrite spdy_writes[] = {
3280 CreateMockWrite(*connect, 1),
3281 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:463282 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:043283 };
3284
[email protected]d9da5fe2010-10-13 22:37:163285 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063286 CreateMockRead(*conn_resp, 2, ASYNC),
3287 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3288 CreateMockRead(*wrapped_body, 6, ASYNC),
3289 CreateMockRead(*wrapped_body, 7, ASYNC),
3290 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163291 };
3292
[email protected]dd54bd82012-07-19 23:44:573293 OrderedSocketData spdy_data(
3294 spdy_reads, arraysize(spdy_reads),
3295 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073296 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163297
[email protected]8ddf8322012-02-23 18:08:063298 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023299 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073300 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063301 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163302 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463303 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073304 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163305
[email protected]49639fa2011-12-20 23:22:413306 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163307
[email protected]49639fa2011-12-20 23:22:413308 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163309 EXPECT_EQ(ERR_IO_PENDING, rv);
3310
3311 rv = callback1.WaitForResult();
3312 EXPECT_EQ(OK, rv);
3313
[email protected]58e32bb2013-01-21 18:23:253314 LoadTimingInfo load_timing_info;
3315 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3316 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3317
[email protected]d9da5fe2010-10-13 22:37:163318 const HttpResponseInfo* response = trans->GetResponseInfo();
3319 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503320 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163321 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3322
3323 std::string response_data;
3324 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3325 EXPECT_EQ("1234567890", response_data);
3326}
3327
3328// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023329TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273330 HttpRequestInfo request;
3331 request.method = "GET";
3332 request.url = GURL("https://www.google.com/");
3333 request.load_flags = 0;
3334
[email protected]d9da5fe2010-10-13 22:37:163335 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073336 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113337 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293338 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073339 session_deps_.net_log = log.bound().net_log();
3340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163341
[email protected]262eec82013-03-19 21:01:363342 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503343 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163344
[email protected]d9da5fe2010-10-13 22:37:163345 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543346 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3347 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163348 // fetch https://www.google.com/ via SPDY
3349 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463350 scoped_ptr<SpdyFrame> get(
3351 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023352 scoped_ptr<SpdyFrame> wrapped_get(
3353 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3354 scoped_ptr<SpdyFrame> conn_resp(
3355 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3356 scoped_ptr<SpdyFrame> get_resp(
3357 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193358 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023359 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3360 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3361 scoped_ptr<SpdyFrame> wrapped_body(
3362 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193363 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203364 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193365 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203366 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043367
3368 MockWrite spdy_writes[] = {
3369 CreateMockWrite(*connect, 1),
3370 CreateMockWrite(*wrapped_get, 3),
3371 CreateMockWrite(*window_update_get_resp, 5),
3372 CreateMockWrite(*window_update_body, 7),
3373 };
3374
[email protected]d9da5fe2010-10-13 22:37:163375 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063376 CreateMockRead(*conn_resp, 2, ASYNC),
3377 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3378 CreateMockRead(*wrapped_body, 6, ASYNC),
3379 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163380 };
3381
[email protected]dd54bd82012-07-19 23:44:573382 OrderedSocketData spdy_data(
3383 spdy_reads, arraysize(spdy_reads),
3384 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073385 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163386
[email protected]8ddf8322012-02-23 18:08:063387 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023388 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073389 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063390 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023391 ssl2.SetNextProto(GetParam());
3392 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073393 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163394
[email protected]49639fa2011-12-20 23:22:413395 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163396
[email protected]49639fa2011-12-20 23:22:413397 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163398 EXPECT_EQ(ERR_IO_PENDING, rv);
3399
3400 rv = callback1.WaitForResult();
3401 EXPECT_EQ(OK, rv);
3402
[email protected]58e32bb2013-01-21 18:23:253403 LoadTimingInfo load_timing_info;
3404 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3405 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3406
[email protected]d9da5fe2010-10-13 22:37:163407 const HttpResponseInfo* response = trans->GetResponseInfo();
3408 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503409 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163410 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3411
3412 std::string response_data;
3413 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233414 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163415}
3416
3417// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023418TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273419 HttpRequestInfo request;
3420 request.method = "GET";
3421 request.url = GURL("https://www.google.com/");
3422 request.load_flags = 0;
3423
[email protected]d9da5fe2010-10-13 22:37:163424 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073425 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113426 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293427 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073428 session_deps_.net_log = log.bound().net_log();
3429 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163430
[email protected]262eec82013-03-19 21:01:363431 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503432 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163433
[email protected]d9da5fe2010-10-13 22:37:163434 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543435 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3436 LOWEST));
[email protected]c10b20852013-05-15 21:29:203437 scoped_ptr<SpdyFrame> get(
3438 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163439
3440 MockWrite spdy_writes[] = {
3441 CreateMockWrite(*connect, 1),
3442 CreateMockWrite(*get, 3),
3443 };
3444
[email protected]23e482282013-06-14 16:08:023445 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3446 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163447 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063448 CreateMockRead(*resp, 2, ASYNC),
3449 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163450 };
3451
[email protected]dd54bd82012-07-19 23:44:573452 OrderedSocketData spdy_data(
3453 spdy_reads, arraysize(spdy_reads),
3454 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073455 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163456
[email protected]8ddf8322012-02-23 18:08:063457 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023458 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073459 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063460 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023461 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163463
[email protected]49639fa2011-12-20 23:22:413464 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163465
[email protected]49639fa2011-12-20 23:22:413466 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163467 EXPECT_EQ(ERR_IO_PENDING, rv);
3468
3469 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173470 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163471
[email protected]4eddbc732012-08-09 05:40:173472 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163473}
3474
[email protected]f6c63db52013-02-02 00:35:223475// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3476// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023477TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223478 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3479 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073480 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223481 "https://proxy:70"));
3482 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073483 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223484 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073485 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223486
3487 HttpRequestInfo request1;
3488 request1.method = "GET";
3489 request1.url = GURL("https://www.google.com/");
3490 request1.load_flags = 0;
3491
3492 HttpRequestInfo request2;
3493 request2.method = "GET";
3494 request2.url = GURL("https://news.google.com/");
3495 request2.load_flags = 0;
3496
3497 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543498 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3499 LOWEST));
[email protected]23e482282013-06-14 16:08:023500 scoped_ptr<SpdyFrame> conn_resp1(
3501 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223502
3503 // Fetch https://www.google.com/ via HTTP.
3504 const char get1[] = "GET / HTTP/1.1\r\n"
3505 "Host: www.google.com\r\n"
3506 "Connection: keep-alive\r\n\r\n";
3507 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023508 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223509 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3510 "Content-Length: 1\r\n\r\n";
3511 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023512 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3513 scoped_ptr<SpdyFrame> wrapped_body1(
3514 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223515 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203516 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223517
3518 // CONNECT to news.google.com:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293519 SpdyHeaderBlock connect2_block;
3520 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3521 connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3522 connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3523 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223524 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293525 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393526
[email protected]23e482282013-06-14 16:08:023527 scoped_ptr<SpdyFrame> conn_resp2(
3528 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223529
3530 // Fetch https://news.google.com/ via HTTP.
3531 const char get2[] = "GET / HTTP/1.1\r\n"
3532 "Host: news.google.com\r\n"
3533 "Connection: keep-alive\r\n\r\n";
3534 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023535 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223536 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3537 "Content-Length: 2\r\n\r\n";
3538 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023539 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223540 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023541 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223542
3543 MockWrite spdy_writes[] = {
3544 CreateMockWrite(*connect1, 0),
3545 CreateMockWrite(*wrapped_get1, 2),
3546 CreateMockWrite(*connect2, 5),
3547 CreateMockWrite(*wrapped_get2, 7),
3548 };
3549
3550 MockRead spdy_reads[] = {
3551 CreateMockRead(*conn_resp1, 1, ASYNC),
3552 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3553 CreateMockRead(*wrapped_body1, 4, ASYNC),
3554 CreateMockRead(*conn_resp2, 6, ASYNC),
3555 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3556 CreateMockRead(*wrapped_body2, 9, ASYNC),
3557 MockRead(ASYNC, 0, 10),
3558 };
3559
3560 DeterministicSocketData spdy_data(
3561 spdy_reads, arraysize(spdy_reads),
3562 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073563 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223564
3565 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023566 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073567 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223568 SSLSocketDataProvider ssl2(ASYNC, OK);
3569 ssl2.was_npn_negotiated = false;
3570 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073571 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223572 SSLSocketDataProvider ssl3(ASYNC, OK);
3573 ssl3.was_npn_negotiated = false;
3574 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073575 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223576
3577 TestCompletionCallback callback;
3578
[email protected]262eec82013-03-19 21:01:363579 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503580 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223581 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3582 EXPECT_EQ(ERR_IO_PENDING, rv);
3583 // The first connect and request, each of their responses, and the body.
3584 spdy_data.RunFor(5);
3585
3586 rv = callback.WaitForResult();
3587 EXPECT_EQ(OK, rv);
3588
3589 LoadTimingInfo load_timing_info;
3590 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3591 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3592
3593 const HttpResponseInfo* response = trans->GetResponseInfo();
3594 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503595 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223596 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3597
3598 std::string response_data;
3599 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503600 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223601
[email protected]262eec82013-03-19 21:01:363602 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503603 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223604 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3605 EXPECT_EQ(ERR_IO_PENDING, rv);
3606
3607 // The second connect and request, each of their responses, and the body.
3608 spdy_data.RunFor(5);
3609 rv = callback.WaitForResult();
3610 EXPECT_EQ(OK, rv);
3611
3612 LoadTimingInfo load_timing_info2;
3613 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3614 // Even though the SPDY connection is reused, a new tunnelled connection has
3615 // to be created, so the socket's load timing looks like a fresh connection.
3616 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3617
3618 // The requests should have different IDs, since they each are using their own
3619 // separate stream.
3620 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3621
[email protected]90499482013-06-01 00:39:503622 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223623}
3624
3625// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3626// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023627TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223628 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3629 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073630 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223631 "https://proxy:70"));
3632 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073633 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223634 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073635 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223636
3637 HttpRequestInfo request1;
3638 request1.method = "GET";
3639 request1.url = GURL("https://www.google.com/");
3640 request1.load_flags = 0;
3641
3642 HttpRequestInfo request2;
3643 request2.method = "GET";
3644 request2.url = GURL("https://www.google.com/2");
3645 request2.load_flags = 0;
3646
3647 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543648 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3649 LOWEST));
[email protected]23e482282013-06-14 16:08:023650 scoped_ptr<SpdyFrame> conn_resp1(
3651 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223652
3653 // Fetch https://www.google.com/ via HTTP.
3654 const char get1[] = "GET / HTTP/1.1\r\n"
3655 "Host: www.google.com\r\n"
3656 "Connection: keep-alive\r\n\r\n";
3657 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023658 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223659 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3660 "Content-Length: 1\r\n\r\n";
3661 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023662 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3663 scoped_ptr<SpdyFrame> wrapped_body1(
3664 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223665 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203666 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223667
3668 // Fetch https://www.google.com/2 via HTTP.
3669 const char get2[] = "GET /2 HTTP/1.1\r\n"
3670 "Host: www.google.com\r\n"
3671 "Connection: keep-alive\r\n\r\n";
3672 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023673 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223674 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3675 "Content-Length: 2\r\n\r\n";
3676 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023677 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223678 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023679 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223680
3681 MockWrite spdy_writes[] = {
3682 CreateMockWrite(*connect1, 0),
3683 CreateMockWrite(*wrapped_get1, 2),
3684 CreateMockWrite(*wrapped_get2, 5),
3685 };
3686
3687 MockRead spdy_reads[] = {
3688 CreateMockRead(*conn_resp1, 1, ASYNC),
3689 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3690 CreateMockRead(*wrapped_body1, 4, ASYNC),
3691 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3692 CreateMockRead(*wrapped_body2, 7, ASYNC),
3693 MockRead(ASYNC, 0, 8),
3694 };
3695
3696 DeterministicSocketData spdy_data(
3697 spdy_reads, arraysize(spdy_reads),
3698 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073699 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223700
3701 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023702 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073703 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223704 SSLSocketDataProvider ssl2(ASYNC, OK);
3705 ssl2.was_npn_negotiated = false;
3706 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073707 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223708
3709 TestCompletionCallback callback;
3710
[email protected]262eec82013-03-19 21:01:363711 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503712 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223713 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3714 EXPECT_EQ(ERR_IO_PENDING, rv);
3715 // The first connect and request, each of their responses, and the body.
3716 spdy_data.RunFor(5);
3717
3718 rv = callback.WaitForResult();
3719 EXPECT_EQ(OK, rv);
3720
3721 LoadTimingInfo load_timing_info;
3722 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3723 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3724
3725 const HttpResponseInfo* response = trans->GetResponseInfo();
3726 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503727 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223728 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3729
3730 std::string response_data;
3731 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503732 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223733 trans.reset();
3734
[email protected]262eec82013-03-19 21:01:363735 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503736 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223737 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3738 EXPECT_EQ(ERR_IO_PENDING, rv);
3739
3740 // The second request, response, and body. There should not be a second
3741 // connect.
3742 spdy_data.RunFor(3);
3743 rv = callback.WaitForResult();
3744 EXPECT_EQ(OK, rv);
3745
3746 LoadTimingInfo load_timing_info2;
3747 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3748 TestLoadTimingReused(load_timing_info2);
3749
3750 // The requests should have the same ID.
3751 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3752
[email protected]90499482013-06-01 00:39:503753 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223754}
3755
3756// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3757// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023758TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223759 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3760 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073761 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223762 "https://proxy:70"));
3763 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073764 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223765 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073766 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223767
3768 HttpRequestInfo request1;
3769 request1.method = "GET";
3770 request1.url = GURL("http://www.google.com/");
3771 request1.load_flags = 0;
3772
3773 HttpRequestInfo request2;
3774 request2.method = "GET";
3775 request2.url = GURL("http://news.google.com/");
3776 request2.load_flags = 0;
3777
3778 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023779 scoped_ptr<SpdyHeaderBlock> headers(
3780 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:293781 scoped_ptr<SpdyFrame> get1(
3782 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:023783 scoped_ptr<SpdyFrame> get_resp1(
3784 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3785 scoped_ptr<SpdyFrame> body1(
3786 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223787
3788 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023789 scoped_ptr<SpdyHeaderBlock> headers2(
3790 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]745aa9c2014-06-27 02:21:293791 scoped_ptr<SpdyFrame> get2(
3792 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:023793 scoped_ptr<SpdyFrame> get_resp2(
3794 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3795 scoped_ptr<SpdyFrame> body2(
3796 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223797
3798 MockWrite spdy_writes[] = {
3799 CreateMockWrite(*get1, 0),
3800 CreateMockWrite(*get2, 3),
3801 };
3802
3803 MockRead spdy_reads[] = {
3804 CreateMockRead(*get_resp1, 1, ASYNC),
3805 CreateMockRead(*body1, 2, ASYNC),
3806 CreateMockRead(*get_resp2, 4, ASYNC),
3807 CreateMockRead(*body2, 5, ASYNC),
3808 MockRead(ASYNC, 0, 6),
3809 };
3810
3811 DeterministicSocketData spdy_data(
3812 spdy_reads, arraysize(spdy_reads),
3813 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073814 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223815
3816 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023817 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073818 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223819
3820 TestCompletionCallback callback;
3821
[email protected]262eec82013-03-19 21:01:363822 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503823 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223824 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3825 EXPECT_EQ(ERR_IO_PENDING, rv);
3826 spdy_data.RunFor(2);
3827
3828 rv = callback.WaitForResult();
3829 EXPECT_EQ(OK, rv);
3830
3831 LoadTimingInfo load_timing_info;
3832 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3833 TestLoadTimingNotReused(load_timing_info,
3834 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3835
3836 const HttpResponseInfo* response = trans->GetResponseInfo();
3837 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503838 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223839 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3840
3841 std::string response_data;
3842 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503843 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223844 spdy_data.RunFor(1);
3845 EXPECT_EQ(1, callback.WaitForResult());
3846 // Delete the first request, so the second one can reuse the socket.
3847 trans.reset();
3848
[email protected]262eec82013-03-19 21:01:363849 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223851 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3852 EXPECT_EQ(ERR_IO_PENDING, rv);
3853
3854 spdy_data.RunFor(2);
3855 rv = callback.WaitForResult();
3856 EXPECT_EQ(OK, rv);
3857
3858 LoadTimingInfo load_timing_info2;
3859 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3860 TestLoadTimingReused(load_timing_info2);
3861
3862 // The requests should have the same ID.
3863 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3864
[email protected]90499482013-06-01 00:39:503865 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223866 spdy_data.RunFor(1);
3867 EXPECT_EQ(2, callback.WaitForResult());
3868}
3869
[email protected]2df19bb2010-08-25 20:13:463870// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023871TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463872 HttpRequestInfo request;
3873 request.method = "GET";
3874 request.url = GURL("http://www.google.com/");
3875 // when the no authentication data flag is set.
3876 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3877
[email protected]79cb5c12011-09-12 13:12:043878 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073879 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043880 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293881 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073882 session_deps_.net_log = log.bound().net_log();
3883 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273884
[email protected]2df19bb2010-08-25 20:13:463885 // Since we have proxy, should use full url
3886 MockWrite data_writes1[] = {
3887 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3888 "Host: www.google.com\r\n"
3889 "Proxy-Connection: keep-alive\r\n\r\n"),
3890
3891 // After calling trans->RestartWithAuth(), this is the request we should
3892 // be issuing -- the final header line contains the credentials.
3893 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3894 "Host: www.google.com\r\n"
3895 "Proxy-Connection: keep-alive\r\n"
3896 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3897 };
3898
3899 // The proxy responds to the GET with a 407, using a persistent
3900 // connection.
3901 MockRead data_reads1[] = {
3902 // No credentials.
3903 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3904 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3905 MockRead("Proxy-Connection: keep-alive\r\n"),
3906 MockRead("Content-Length: 0\r\n\r\n"),
3907
3908 MockRead("HTTP/1.1 200 OK\r\n"),
3909 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3910 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063911 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463912 };
3913
3914 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3915 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073916 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063917 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073918 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463919
[email protected]49639fa2011-12-20 23:22:413920 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463921
[email protected]262eec82013-03-19 21:01:363922 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503924
[email protected]49639fa2011-12-20 23:22:413925 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463926 EXPECT_EQ(ERR_IO_PENDING, rv);
3927
3928 rv = callback1.WaitForResult();
3929 EXPECT_EQ(OK, rv);
3930
[email protected]58e32bb2013-01-21 18:23:253931 LoadTimingInfo load_timing_info;
3932 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3933 TestLoadTimingNotReused(load_timing_info,
3934 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3935
[email protected]2df19bb2010-08-25 20:13:463936 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503937 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503938 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463939 EXPECT_EQ(407, response->headers->response_code());
3940 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043941 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463942
[email protected]49639fa2011-12-20 23:22:413943 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463944
[email protected]49639fa2011-12-20 23:22:413945 rv = trans->RestartWithAuth(
3946 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463947 EXPECT_EQ(ERR_IO_PENDING, rv);
3948
3949 rv = callback2.WaitForResult();
3950 EXPECT_EQ(OK, rv);
3951
[email protected]58e32bb2013-01-21 18:23:253952 load_timing_info = LoadTimingInfo();
3953 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3954 // Retrying with HTTP AUTH is considered to be reusing a socket.
3955 TestLoadTimingReused(load_timing_info);
3956
[email protected]2df19bb2010-08-25 20:13:463957 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503958 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463959
3960 EXPECT_TRUE(response->headers->IsKeepAlive());
3961 EXPECT_EQ(200, response->headers->response_code());
3962 EXPECT_EQ(100, response->headers->GetContentLength());
3963 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3964
3965 // The password prompt info should not be set.
3966 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3967}
3968
[email protected]23e482282013-06-14 16:08:023969void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083970 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423971 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083972 request.method = "GET";
3973 request.url = GURL("https://www.google.com/");
3974 request.load_flags = 0;
3975
[email protected]cb9bf6ca2011-01-28 13:15:273976 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073977 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073978 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273979
[email protected]c744cf22009-02-27 07:28:083980 // Since we have proxy, should try to establish tunnel.
3981 MockWrite data_writes[] = {
3982 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453983 "Host: www.google.com\r\n"
3984 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083985 };
3986
3987 MockRead data_reads[] = {
3988 status,
3989 MockRead("Content-Length: 10\r\n\r\n"),
3990 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063991 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083992 };
3993
[email protected]31a2bfe2010-02-09 08:03:393994 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3995 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073996 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083997
[email protected]49639fa2011-12-20 23:22:413998 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083999
[email protected]262eec82013-03-19 21:01:364000 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504002
[email protected]49639fa2011-12-20 23:22:414003 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424004 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084005
4006 rv = callback.WaitForResult();
4007 EXPECT_EQ(expected_status, rv);
4008}
4009
[email protected]23e482282013-06-14 16:08:024010void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234011 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084012 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424013 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084014}
4015
[email protected]23e482282013-06-14 16:08:024016TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084017 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4018}
4019
[email protected]23e482282013-06-14 16:08:024020TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084021 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4022}
4023
[email protected]23e482282013-06-14 16:08:024024TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084025 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4026}
4027
[email protected]23e482282013-06-14 16:08:024028TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084029 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4030}
4031
[email protected]23e482282013-06-14 16:08:024032TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084033 ConnectStatusHelper(
4034 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4035}
4036
[email protected]23e482282013-06-14 16:08:024037TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084038 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4039}
4040
[email protected]23e482282013-06-14 16:08:024041TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084042 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4043}
4044
[email protected]23e482282013-06-14 16:08:024045TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084046 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4047}
4048
[email protected]23e482282013-06-14 16:08:024049TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084050 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4051}
4052
[email protected]23e482282013-06-14 16:08:024053TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084054 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4055}
4056
[email protected]23e482282013-06-14 16:08:024057TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084058 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4059}
4060
[email protected]23e482282013-06-14 16:08:024061TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084062 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4063}
4064
[email protected]23e482282013-06-14 16:08:024065TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084066 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4067}
4068
[email protected]23e482282013-06-14 16:08:024069TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084070 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4071}
4072
[email protected]23e482282013-06-14 16:08:024073TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084074 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4075}
4076
[email protected]23e482282013-06-14 16:08:024077TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084078 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4079}
4080
[email protected]0a17aab32014-04-24 03:32:374081TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4082 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4083}
4084
[email protected]23e482282013-06-14 16:08:024085TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084086 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4087}
4088
[email protected]23e482282013-06-14 16:08:024089TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084090 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4091}
4092
[email protected]23e482282013-06-14 16:08:024093TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084094 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4095}
4096
[email protected]23e482282013-06-14 16:08:024097TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084098 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4099}
4100
[email protected]23e482282013-06-14 16:08:024101TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084102 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4103}
4104
[email protected]23e482282013-06-14 16:08:024105TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084106 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4107}
4108
[email protected]23e482282013-06-14 16:08:024109TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084110 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4111}
4112
[email protected]23e482282013-06-14 16:08:024113TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084114 ConnectStatusHelperWithExpectedStatus(
4115 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544116 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084117}
4118
[email protected]23e482282013-06-14 16:08:024119TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084120 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4121}
4122
[email protected]23e482282013-06-14 16:08:024123TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084124 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4125}
4126
[email protected]23e482282013-06-14 16:08:024127TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084128 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4129}
4130
[email protected]23e482282013-06-14 16:08:024131TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084132 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4133}
4134
[email protected]23e482282013-06-14 16:08:024135TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084136 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4137}
4138
[email protected]23e482282013-06-14 16:08:024139TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084140 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4141}
4142
[email protected]23e482282013-06-14 16:08:024143TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084144 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4145}
4146
[email protected]23e482282013-06-14 16:08:024147TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084148 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4149}
4150
[email protected]23e482282013-06-14 16:08:024151TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084152 ConnectStatusHelper(
4153 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4154}
4155
[email protected]23e482282013-06-14 16:08:024156TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084157 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4158}
4159
[email protected]23e482282013-06-14 16:08:024160TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084161 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4162}
4163
[email protected]23e482282013-06-14 16:08:024164TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084165 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4166}
4167
[email protected]23e482282013-06-14 16:08:024168TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084169 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4170}
4171
[email protected]23e482282013-06-14 16:08:024172TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084173 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4174}
4175
[email protected]23e482282013-06-14 16:08:024176TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084177 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4178}
4179
[email protected]23e482282013-06-14 16:08:024180TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084181 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4182}
4183
[email protected]038e9a32008-10-08 22:40:164184// Test the flow when both the proxy server AND origin server require
4185// authentication. Again, this uses basic auth for both since that is
4186// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024187TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274188 HttpRequestInfo request;
4189 request.method = "GET";
4190 request.url = GURL("http://www.google.com/");
4191 request.load_flags = 0;
4192
[email protected]038e9a32008-10-08 22:40:164193 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074194 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4195 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4196
4197 scoped_ptr<HttpTransaction> trans(
4198 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]038e9a32008-10-08 22:40:164199
[email protected]f9ee6b52008-11-08 06:46:234200 MockWrite data_writes1[] = {
4201 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4202 "Host: www.google.com\r\n"
4203 "Proxy-Connection: keep-alive\r\n\r\n"),
4204 };
4205
[email protected]038e9a32008-10-08 22:40:164206 MockRead data_reads1[] = {
4207 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4208 // Give a couple authenticate options (only the middle one is actually
4209 // supported).
[email protected]22927ad2009-09-21 19:56:194210 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164211 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4212 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4213 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4214 // Large content-length -- won't matter, as connection will be reset.
4215 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064216 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164217 };
4218
4219 // After calling trans->RestartWithAuth() the first time, this is the
4220 // request we should be issuing -- the final header line contains the
4221 // proxy's credentials.
4222 MockWrite data_writes2[] = {
4223 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4224 "Host: www.google.com\r\n"
4225 "Proxy-Connection: keep-alive\r\n"
4226 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4227 };
4228
4229 // Now the proxy server lets the request pass through to origin server.
4230 // The origin server responds with a 401.
4231 MockRead data_reads2[] = {
4232 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4233 // Note: We are using the same realm-name as the proxy server. This is
4234 // completely valid, as realms are unique across hosts.
4235 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4236 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4237 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064238 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164239 };
4240
4241 // After calling trans->RestartWithAuth() the second time, we should send
4242 // the credentials for both the proxy and origin server.
4243 MockWrite data_writes3[] = {
4244 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4245 "Host: www.google.com\r\n"
4246 "Proxy-Connection: keep-alive\r\n"
4247 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4248 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4249 };
4250
4251 // Lastly we get the desired content.
4252 MockRead data_reads3[] = {
4253 MockRead("HTTP/1.0 200 OK\r\n"),
4254 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4255 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064256 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164257 };
4258
[email protected]31a2bfe2010-02-09 08:03:394259 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4260 data_writes1, arraysize(data_writes1));
4261 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4262 data_writes2, arraysize(data_writes2));
4263 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4264 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074265 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4266 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4267 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164268
[email protected]49639fa2011-12-20 23:22:414269 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164270
[email protected]49639fa2011-12-20 23:22:414271 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424272 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164273
4274 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424275 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164276
[email protected]1c773ea12009-04-28 19:58:424277 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504278 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044279 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164280
[email protected]49639fa2011-12-20 23:22:414281 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164282
[email protected]49639fa2011-12-20 23:22:414283 rv = trans->RestartWithAuth(
4284 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424285 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164286
4287 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424288 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164289
4290 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504291 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044292 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164293
[email protected]49639fa2011-12-20 23:22:414294 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164295
[email protected]49639fa2011-12-20 23:22:414296 rv = trans->RestartWithAuth(
4297 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424298 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164299
4300 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424301 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164302
4303 response = trans->GetResponseInfo();
4304 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4305 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164306}
[email protected]4ddaf2502008-10-23 18:26:194307
[email protected]ea9dc9a2009-09-05 00:43:324308// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4309// can't hook into its internals to cause it to generate predictable NTLM
4310// authorization headers.
4311#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294312// The NTLM authentication unit tests were generated by capturing the HTTP
4313// requests and responses using Fiddler 2 and inspecting the generated random
4314// bytes in the debugger.
4315
4316// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024317TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424318 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244319 request.method = "GET";
4320 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544321
4322 // Ensure load is not disrupted by flags which suppress behaviour specific
4323 // to other auth schemes.
4324 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244325
[email protected]cb9bf6ca2011-01-28 13:15:274326 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4327 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074328 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274329
[email protected]3f918782009-02-28 01:29:244330 MockWrite data_writes1[] = {
4331 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4332 "Host: 172.22.68.17\r\n"
4333 "Connection: keep-alive\r\n\r\n"),
4334 };
4335
4336 MockRead data_reads1[] = {
4337 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044338 // Negotiate and NTLM are often requested together. However, we only want
4339 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4340 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244341 MockRead("WWW-Authenticate: NTLM\r\n"),
4342 MockRead("Connection: close\r\n"),
4343 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364344 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244345 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064346 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244347 };
4348
4349 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224350 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244351 // request we should be issuing -- the final header line contains a Type
4352 // 1 message.
4353 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4354 "Host: 172.22.68.17\r\n"
4355 "Connection: keep-alive\r\n"
4356 "Authorization: NTLM "
4357 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4358
4359 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4360 // (the credentials for the origin server). The second request continues
4361 // on the same connection.
4362 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4363 "Host: 172.22.68.17\r\n"
4364 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294365 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4366 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4367 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4368 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4369 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244370 };
4371
4372 MockRead data_reads2[] = {
4373 // The origin server responds with a Type 2 message.
4374 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4375 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294376 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244377 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4378 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4379 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4380 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4381 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4382 "BtAAAAAAA=\r\n"),
4383 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364384 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244385 MockRead("You are not authorized to view this page\r\n"),
4386
4387 // Lastly we get the desired content.
4388 MockRead("HTTP/1.1 200 OK\r\n"),
4389 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4390 MockRead("Content-Length: 13\r\n\r\n"),
4391 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064392 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244393 };
4394
[email protected]31a2bfe2010-02-09 08:03:394395 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4396 data_writes1, arraysize(data_writes1));
4397 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4398 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074399 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4400 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244401
[email protected]49639fa2011-12-20 23:22:414402 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244403
[email protected]262eec82013-03-19 21:01:364404 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504406
[email protected]49639fa2011-12-20 23:22:414407 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424408 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244409
4410 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424411 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244412
[email protected]0757e7702009-03-27 04:00:224413 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4414
[email protected]1c773ea12009-04-28 19:58:424415 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044416 ASSERT_FALSE(response == NULL);
4417 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244418
[email protected]49639fa2011-12-20 23:22:414419 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254420
[email protected]f3cf9802011-10-28 18:44:584421 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414422 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254423 EXPECT_EQ(ERR_IO_PENDING, rv);
4424
4425 rv = callback2.WaitForResult();
4426 EXPECT_EQ(OK, rv);
4427
4428 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4429
4430 response = trans->GetResponseInfo();
4431 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254432 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4433
[email protected]49639fa2011-12-20 23:22:414434 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244435
[email protected]49639fa2011-12-20 23:22:414436 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424437 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244438
[email protected]0757e7702009-03-27 04:00:224439 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424440 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244441
4442 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504443 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244444 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4445 EXPECT_EQ(13, response->headers->GetContentLength());
4446}
4447
[email protected]385a4672009-03-11 22:21:294448// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024449TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424450 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294451 request.method = "GET";
4452 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4453 request.load_flags = 0;
4454
[email protected]cb9bf6ca2011-01-28 13:15:274455 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4456 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074457 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274458
[email protected]385a4672009-03-11 22:21:294459 MockWrite data_writes1[] = {
4460 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4461 "Host: 172.22.68.17\r\n"
4462 "Connection: keep-alive\r\n\r\n"),
4463 };
4464
4465 MockRead data_reads1[] = {
4466 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044467 // Negotiate and NTLM are often requested together. However, we only want
4468 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4469 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294470 MockRead("WWW-Authenticate: NTLM\r\n"),
4471 MockRead("Connection: close\r\n"),
4472 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364473 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294474 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064475 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294476 };
4477
4478 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224479 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294480 // request we should be issuing -- the final header line contains a Type
4481 // 1 message.
4482 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4483 "Host: 172.22.68.17\r\n"
4484 "Connection: keep-alive\r\n"
4485 "Authorization: NTLM "
4486 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4487
4488 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4489 // (the credentials for the origin server). The second request continues
4490 // on the same connection.
4491 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4492 "Host: 172.22.68.17\r\n"
4493 "Connection: keep-alive\r\n"
4494 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4495 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4496 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4497 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4498 "4Ww7b7E=\r\n\r\n"),
4499 };
4500
4501 MockRead data_reads2[] = {
4502 // The origin server responds with a Type 2 message.
4503 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4504 MockRead("WWW-Authenticate: NTLM "
4505 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4506 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4507 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4508 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4509 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4510 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4511 "BtAAAAAAA=\r\n"),
4512 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364513 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294514 MockRead("You are not authorized to view this page\r\n"),
4515
4516 // Wrong password.
4517 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294518 MockRead("WWW-Authenticate: NTLM\r\n"),
4519 MockRead("Connection: close\r\n"),
4520 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364521 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294522 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064523 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294524 };
4525
4526 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224527 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294528 // request we should be issuing -- the final header line contains a Type
4529 // 1 message.
4530 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4531 "Host: 172.22.68.17\r\n"
4532 "Connection: keep-alive\r\n"
4533 "Authorization: NTLM "
4534 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4535
4536 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4537 // (the credentials for the origin server). The second request continues
4538 // on the same connection.
4539 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4540 "Host: 172.22.68.17\r\n"
4541 "Connection: keep-alive\r\n"
4542 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4543 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4544 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4545 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4546 "+4MUm7c=\r\n\r\n"),
4547 };
4548
4549 MockRead data_reads3[] = {
4550 // The origin server responds with a Type 2 message.
4551 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4552 MockRead("WWW-Authenticate: NTLM "
4553 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4554 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4555 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4556 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4557 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4558 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4559 "BtAAAAAAA=\r\n"),
4560 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364561 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294562 MockRead("You are not authorized to view this page\r\n"),
4563
4564 // Lastly we get the desired content.
4565 MockRead("HTTP/1.1 200 OK\r\n"),
4566 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4567 MockRead("Content-Length: 13\r\n\r\n"),
4568 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064569 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294570 };
4571
[email protected]31a2bfe2010-02-09 08:03:394572 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4573 data_writes1, arraysize(data_writes1));
4574 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4575 data_writes2, arraysize(data_writes2));
4576 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4577 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074578 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4579 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4580 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294581
[email protected]49639fa2011-12-20 23:22:414582 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294583
[email protected]262eec82013-03-19 21:01:364584 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504585 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504586
[email protected]49639fa2011-12-20 23:22:414587 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424588 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294589
4590 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424591 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294592
[email protected]0757e7702009-03-27 04:00:224593 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294594
[email protected]1c773ea12009-04-28 19:58:424595 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504596 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044597 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294598
[email protected]49639fa2011-12-20 23:22:414599 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294600
[email protected]0757e7702009-03-27 04:00:224601 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584602 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414603 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424604 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294605
[email protected]10af5fe72011-01-31 16:17:254606 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424607 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294608
[email protected]0757e7702009-03-27 04:00:224609 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414610 TestCompletionCallback callback3;
4611 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424612 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254613 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424614 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224615 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4616
4617 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044618 ASSERT_FALSE(response == NULL);
4619 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224620
[email protected]49639fa2011-12-20 23:22:414621 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224622
4623 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584624 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414625 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254626 EXPECT_EQ(ERR_IO_PENDING, rv);
4627
4628 rv = callback4.WaitForResult();
4629 EXPECT_EQ(OK, rv);
4630
4631 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4632
[email protected]49639fa2011-12-20 23:22:414633 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254634
4635 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414636 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424637 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224638
4639 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424640 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224641
[email protected]385a4672009-03-11 22:21:294642 response = trans->GetResponseInfo();
4643 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4644 EXPECT_EQ(13, response->headers->GetContentLength());
4645}
[email protected]ea9dc9a2009-09-05 00:43:324646#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294647
[email protected]4ddaf2502008-10-23 18:26:194648// Test reading a server response which has only headers, and no body.
4649// After some maximum number of bytes is consumed, the transaction should
4650// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024651TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424652 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194653 request.method = "GET";
4654 request.url = GURL("http://www.google.com/");
4655 request.load_flags = 0;
4656
[email protected]3fe8d2f82013-10-17 08:56:074657 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274658 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074659 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274660
[email protected]b75b7b2f2009-10-06 00:54:534661 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434662 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534663 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194664
4665 MockRead data_reads[] = {
4666 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064667 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194668 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064669 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194670 };
[email protected]31a2bfe2010-02-09 08:03:394671 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074672 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194673
[email protected]49639fa2011-12-20 23:22:414674 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194675
[email protected]49639fa2011-12-20 23:22:414676 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424677 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194678
4679 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424680 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194681
[email protected]1c773ea12009-04-28 19:58:424682 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194683 EXPECT_TRUE(response == NULL);
4684}
[email protected]f4e426b2008-11-05 00:24:494685
4686// Make sure that we don't try to reuse a TCPClientSocket when failing to
4687// establish tunnel.
4688// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024689TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234690 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274691 HttpRequestInfo request;
4692 request.method = "GET";
4693 request.url = GURL("https://www.google.com/");
4694 request.load_flags = 0;
4695
[email protected]f4e426b2008-11-05 00:24:494696 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074697 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014698
[email protected]bb88e1d32013-05-03 23:11:074699 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494700
[email protected]262eec82013-03-19 21:01:364701 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504702 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494703
[email protected]f4e426b2008-11-05 00:24:494704 // Since we have proxy, should try to establish tunnel.
4705 MockWrite data_writes1[] = {
4706 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454707 "Host: www.google.com\r\n"
4708 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494709 };
4710
[email protected]77848d12008-11-14 00:00:224711 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494712 // connection. Usually a proxy would return 501 (not implemented),
4713 // or 200 (tunnel established).
4714 MockRead data_reads1[] = {
4715 MockRead("HTTP/1.1 404 Not Found\r\n"),
4716 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064717 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494718 };
4719
[email protected]31a2bfe2010-02-09 08:03:394720 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4721 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074722 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494723
[email protected]49639fa2011-12-20 23:22:414724 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494725
[email protected]49639fa2011-12-20 23:22:414726 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424727 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494728
4729 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424730 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494731
[email protected]1c773ea12009-04-28 19:58:424732 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084733 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494734
[email protected]b4404c02009-04-10 16:38:524735 // Empty the current queue. This is necessary because idle sockets are
4736 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344737 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524738
[email protected]f4e426b2008-11-05 00:24:494739 // We now check to make sure the TCPClientSocket was not added back to
4740 // the pool.
[email protected]90499482013-06-01 00:39:504741 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494742 trans.reset();
[email protected]2da659e2013-05-23 20:51:344743 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494744 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504745 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494746}
[email protected]372d34a2008-11-05 21:30:514747
[email protected]1b157c02009-04-21 01:55:404748// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024749TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424750 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404751 request.method = "GET";
4752 request.url = GURL("http://www.google.com/");
4753 request.load_flags = 0;
4754
[email protected]bb88e1d32013-05-03 23:11:074755 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274756
[email protected]262eec82013-03-19 21:01:364757 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504758 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274759
[email protected]1b157c02009-04-21 01:55:404760 MockRead data_reads[] = {
4761 // A part of the response body is received with the response headers.
4762 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4763 // The rest of the response body is received in two parts.
4764 MockRead("lo"),
4765 MockRead(" world"),
4766 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064767 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404768 };
4769
[email protected]31a2bfe2010-02-09 08:03:394770 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074771 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404772
[email protected]49639fa2011-12-20 23:22:414773 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404774
[email protected]49639fa2011-12-20 23:22:414775 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424776 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404777
4778 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424779 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404780
[email protected]1c773ea12009-04-28 19:58:424781 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504782 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404783
[email protected]90499482013-06-01 00:39:504784 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404785 std::string status_line = response->headers->GetStatusLine();
4786 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4787
[email protected]90499482013-06-01 00:39:504788 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404789
4790 std::string response_data;
4791 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424792 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404793 EXPECT_EQ("hello world", response_data);
4794
4795 // Empty the current queue. This is necessary because idle sockets are
4796 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344797 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404798
4799 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504800 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404801}
4802
[email protected]76a505b2010-08-25 06:23:004803// Make sure that we recycle a SSL socket after reading all of the response
4804// body.
[email protected]23e482282013-06-14 16:08:024805TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004806 HttpRequestInfo request;
4807 request.method = "GET";
4808 request.url = GURL("https://www.google.com/");
4809 request.load_flags = 0;
4810
4811 MockWrite data_writes[] = {
4812 MockWrite("GET / HTTP/1.1\r\n"
4813 "Host: www.google.com\r\n"
4814 "Connection: keep-alive\r\n\r\n"),
4815 };
4816
4817 MockRead data_reads[] = {
4818 MockRead("HTTP/1.1 200 OK\r\n"),
4819 MockRead("Content-Length: 11\r\n\r\n"),
4820 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064821 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004822 };
4823
[email protected]8ddf8322012-02-23 18:08:064824 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074825 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004826
4827 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4828 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074829 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004830
[email protected]49639fa2011-12-20 23:22:414831 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004832
[email protected]bb88e1d32013-05-03 23:11:074833 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364834 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504835 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004836
[email protected]49639fa2011-12-20 23:22:414837 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004838
4839 EXPECT_EQ(ERR_IO_PENDING, rv);
4840 EXPECT_EQ(OK, callback.WaitForResult());
4841
4842 const HttpResponseInfo* response = trans->GetResponseInfo();
4843 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504844 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004845 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4846
[email protected]90499482013-06-01 00:39:504847 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004848
4849 std::string response_data;
4850 rv = ReadTransaction(trans.get(), &response_data);
4851 EXPECT_EQ(OK, rv);
4852 EXPECT_EQ("hello world", response_data);
4853
4854 // Empty the current queue. This is necessary because idle sockets are
4855 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344856 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004857
4858 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504859 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004860}
4861
4862// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4863// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024864TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004865 HttpRequestInfo request;
4866 request.method = "GET";
4867 request.url = GURL("https://www.google.com/");
4868 request.load_flags = 0;
4869
4870 MockWrite data_writes[] = {
4871 MockWrite("GET / HTTP/1.1\r\n"
4872 "Host: www.google.com\r\n"
4873 "Connection: keep-alive\r\n\r\n"),
4874 MockWrite("GET / HTTP/1.1\r\n"
4875 "Host: www.google.com\r\n"
4876 "Connection: keep-alive\r\n\r\n"),
4877 };
4878
4879 MockRead data_reads[] = {
4880 MockRead("HTTP/1.1 200 OK\r\n"),
4881 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064882 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004883 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064884 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004885 };
4886
[email protected]8ddf8322012-02-23 18:08:064887 SSLSocketDataProvider ssl(ASYNC, OK);
4888 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074889 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4890 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004891
4892 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4893 data_writes, arraysize(data_writes));
4894 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4895 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074896 session_deps_.socket_factory->AddSocketDataProvider(&data);
4897 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004898
[email protected]49639fa2011-12-20 23:22:414899 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004900
[email protected]bb88e1d32013-05-03 23:11:074901 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364902 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504903 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004904
[email protected]49639fa2011-12-20 23:22:414905 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004906
4907 EXPECT_EQ(ERR_IO_PENDING, rv);
4908 EXPECT_EQ(OK, callback.WaitForResult());
4909
4910 const HttpResponseInfo* response = trans->GetResponseInfo();
4911 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504912 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004913 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4914
[email protected]90499482013-06-01 00:39:504915 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004916
4917 std::string response_data;
4918 rv = ReadTransaction(trans.get(), &response_data);
4919 EXPECT_EQ(OK, rv);
4920 EXPECT_EQ("hello world", response_data);
4921
4922 // Empty the current queue. This is necessary because idle sockets are
4923 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344924 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004925
4926 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504927 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004928
4929 // Now start the second transaction, which should reuse the previous socket.
4930
[email protected]90499482013-06-01 00:39:504931 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004932
[email protected]49639fa2011-12-20 23:22:414933 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004934
4935 EXPECT_EQ(ERR_IO_PENDING, rv);
4936 EXPECT_EQ(OK, callback.WaitForResult());
4937
4938 response = trans->GetResponseInfo();
4939 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504940 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004941 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4942
[email protected]90499482013-06-01 00:39:504943 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004944
4945 rv = ReadTransaction(trans.get(), &response_data);
4946 EXPECT_EQ(OK, rv);
4947 EXPECT_EQ("hello world", response_data);
4948
4949 // Empty the current queue. This is necessary because idle sockets are
4950 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344951 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004952
4953 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504954 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004955}
4956
[email protected]b4404c02009-04-10 16:38:524957// Make sure that we recycle a socket after a zero-length response.
4958// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024959TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424960 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524961 request.method = "GET";
4962 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4963 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4964 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4965 "rt=prt.2642,ol.2649,xjs.2951");
4966 request.load_flags = 0;
4967
[email protected]bb88e1d32013-05-03 23:11:074968 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274969
[email protected]262eec82013-03-19 21:01:364970 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504971 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274972
[email protected]b4404c02009-04-10 16:38:524973 MockRead data_reads[] = {
4974 MockRead("HTTP/1.1 204 No Content\r\n"
4975 "Content-Length: 0\r\n"
4976 "Content-Type: text/html\r\n\r\n"),
4977 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064978 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524979 };
4980
[email protected]31a2bfe2010-02-09 08:03:394981 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074982 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524983
[email protected]49639fa2011-12-20 23:22:414984 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524985
[email protected]49639fa2011-12-20 23:22:414986 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424987 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524988
4989 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424990 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524991
[email protected]1c773ea12009-04-28 19:58:424992 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504993 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524994
[email protected]90499482013-06-01 00:39:504995 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524996 std::string status_line = response->headers->GetStatusLine();
4997 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4998
[email protected]90499482013-06-01 00:39:504999 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525000
5001 std::string response_data;
5002 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425003 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525004 EXPECT_EQ("", response_data);
5005
5006 // Empty the current queue. This is necessary because idle sockets are
5007 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345008 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525009
5010 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505011 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525012}
5013
[email protected]23e482282013-06-14 16:08:025014TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065015 ScopedVector<UploadElementReader> element_readers;
5016 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:205017 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275018
[email protected]1c773ea12009-04-28 19:58:425019 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515020 // Transaction 1: a GET request that succeeds. The socket is recycled
5021 // after use.
5022 request[0].method = "GET";
5023 request[0].url = GURL("http://www.google.com/");
5024 request[0].load_flags = 0;
5025 // Transaction 2: a POST request. Reuses the socket kept alive from
5026 // transaction 1. The first attempts fails when writing the POST data.
5027 // This causes the transaction to retry with a new socket. The second
5028 // attempt succeeds.
5029 request[1].method = "POST";
5030 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275031 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515032 request[1].load_flags = 0;
5033
[email protected]bb88e1d32013-05-03 23:11:075034 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515035
5036 // The first socket is used for transaction 1 and the first attempt of
5037 // transaction 2.
5038
5039 // The response of transaction 1.
5040 MockRead data_reads1[] = {
5041 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5042 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065043 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515044 };
5045 // The mock write results of transaction 1 and the first attempt of
5046 // transaction 2.
5047 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065048 MockWrite(SYNCHRONOUS, 64), // GET
5049 MockWrite(SYNCHRONOUS, 93), // POST
5050 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515051 };
[email protected]31a2bfe2010-02-09 08:03:395052 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5053 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515054
5055 // The second socket is used for the second attempt of transaction 2.
5056
5057 // The response of transaction 2.
5058 MockRead data_reads2[] = {
5059 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5060 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065061 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515062 };
5063 // The mock write results of the second attempt of transaction 2.
5064 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065065 MockWrite(SYNCHRONOUS, 93), // POST
5066 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515067 };
[email protected]31a2bfe2010-02-09 08:03:395068 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5069 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515070
[email protected]bb88e1d32013-05-03 23:11:075071 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5072 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515073
5074 const char* kExpectedResponseData[] = {
5075 "hello world", "welcome"
5076 };
5077
5078 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425079 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505080 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515081
[email protected]49639fa2011-12-20 23:22:415082 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515083
[email protected]49639fa2011-12-20 23:22:415084 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425085 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515086
5087 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425088 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515089
[email protected]1c773ea12009-04-28 19:58:425090 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505091 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515092
[email protected]90499482013-06-01 00:39:505093 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515094 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5095
5096 std::string response_data;
5097 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425098 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515099 EXPECT_EQ(kExpectedResponseData[i], response_data);
5100 }
5101}
[email protected]f9ee6b52008-11-08 06:46:235102
5103// Test the request-challenge-retry sequence for basic auth when there is
5104// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165105// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025106TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425107 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235108 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:295109 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415110 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295111
[email protected]3fe8d2f82013-10-17 08:56:075112 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275113 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075114 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275115
[email protected]a97cca42009-08-14 01:00:295116 // The password contains an escaped character -- for this test to pass it
5117 // will need to be unescaped by HttpNetworkTransaction.
5118 EXPECT_EQ("b%40r", request.url.password());
5119
[email protected]f9ee6b52008-11-08 06:46:235120 MockWrite data_writes1[] = {
5121 MockWrite("GET / HTTP/1.1\r\n"
5122 "Host: www.google.com\r\n"
5123 "Connection: keep-alive\r\n\r\n"),
5124 };
5125
5126 MockRead data_reads1[] = {
5127 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5128 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5129 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065130 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235131 };
5132
[email protected]2262e3a2012-05-22 16:08:165133 // After the challenge above, the transaction will be restarted using the
5134 // identity from the url (foo, b@r) to answer the challenge.
5135 MockWrite data_writes2[] = {
5136 MockWrite("GET / HTTP/1.1\r\n"
5137 "Host: www.google.com\r\n"
5138 "Connection: keep-alive\r\n"
5139 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5140 };
5141
5142 MockRead data_reads2[] = {
5143 MockRead("HTTP/1.0 200 OK\r\n"),
5144 MockRead("Content-Length: 100\r\n\r\n"),
5145 MockRead(SYNCHRONOUS, OK),
5146 };
5147
[email protected]31a2bfe2010-02-09 08:03:395148 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5149 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165150 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5151 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075152 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5153 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235154
[email protected]49639fa2011-12-20 23:22:415155 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415156 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425157 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235158 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425159 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165160 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5161
5162 TestCompletionCallback callback2;
5163 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5164 EXPECT_EQ(ERR_IO_PENDING, rv);
5165 rv = callback2.WaitForResult();
5166 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225167 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5168
[email protected]2262e3a2012-05-22 16:08:165169 const HttpResponseInfo* response = trans->GetResponseInfo();
5170 ASSERT_TRUE(response != NULL);
5171
5172 // There is no challenge info, since the identity in URL worked.
5173 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5174
5175 EXPECT_EQ(100, response->headers->GetContentLength());
5176
5177 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345178 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165179}
5180
5181// Test the request-challenge-retry sequence for basic auth when there is an
5182// incorrect identity in the URL. The identity from the URL should be used only
5183// once.
[email protected]23e482282013-06-14 16:08:025184TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165185 HttpRequestInfo request;
5186 request.method = "GET";
5187 // Note: the URL has a username:password in it. The password "baz" is
5188 // wrong (should be "bar").
5189 request.url = GURL("http://foo:[email protected]/");
5190
5191 request.load_flags = LOAD_NORMAL;
5192
[email protected]3fe8d2f82013-10-17 08:56:075193 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165194 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2262e3a2012-05-22 16:08:165196
5197 MockWrite data_writes1[] = {
5198 MockWrite("GET / HTTP/1.1\r\n"
5199 "Host: www.google.com\r\n"
5200 "Connection: keep-alive\r\n\r\n"),
5201 };
5202
5203 MockRead data_reads1[] = {
5204 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5205 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5206 MockRead("Content-Length: 10\r\n\r\n"),
5207 MockRead(SYNCHRONOUS, ERR_FAILED),
5208 };
5209
5210 // After the challenge above, the transaction will be restarted using the
5211 // identity from the url (foo, baz) to answer the challenge.
5212 MockWrite data_writes2[] = {
5213 MockWrite("GET / HTTP/1.1\r\n"
5214 "Host: www.google.com\r\n"
5215 "Connection: keep-alive\r\n"
5216 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5217 };
5218
5219 MockRead data_reads2[] = {
5220 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5221 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5222 MockRead("Content-Length: 10\r\n\r\n"),
5223 MockRead(SYNCHRONOUS, ERR_FAILED),
5224 };
5225
5226 // After the challenge above, the transaction will be restarted using the
5227 // identity supplied by the user (foo, bar) to answer the challenge.
5228 MockWrite data_writes3[] = {
5229 MockWrite("GET / HTTP/1.1\r\n"
5230 "Host: www.google.com\r\n"
5231 "Connection: keep-alive\r\n"
5232 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5233 };
5234
5235 MockRead data_reads3[] = {
5236 MockRead("HTTP/1.0 200 OK\r\n"),
5237 MockRead("Content-Length: 100\r\n\r\n"),
5238 MockRead(SYNCHRONOUS, OK),
5239 };
5240
5241 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5242 data_writes1, arraysize(data_writes1));
5243 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5244 data_writes2, arraysize(data_writes2));
5245 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5246 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075247 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5248 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5249 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165250
5251 TestCompletionCallback callback1;
5252
5253 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5254 EXPECT_EQ(ERR_IO_PENDING, rv);
5255
5256 rv = callback1.WaitForResult();
5257 EXPECT_EQ(OK, rv);
5258
5259 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5260 TestCompletionCallback callback2;
5261 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5262 EXPECT_EQ(ERR_IO_PENDING, rv);
5263 rv = callback2.WaitForResult();
5264 EXPECT_EQ(OK, rv);
5265 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5266
5267 const HttpResponseInfo* response = trans->GetResponseInfo();
5268 ASSERT_TRUE(response != NULL);
5269 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5270
5271 TestCompletionCallback callback3;
5272 rv = trans->RestartWithAuth(
5273 AuthCredentials(kFoo, kBar), callback3.callback());
5274 EXPECT_EQ(ERR_IO_PENDING, rv);
5275 rv = callback3.WaitForResult();
5276 EXPECT_EQ(OK, rv);
5277 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5278
5279 response = trans->GetResponseInfo();
5280 ASSERT_TRUE(response != NULL);
5281
5282 // There is no challenge info, since the identity worked.
5283 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5284
5285 EXPECT_EQ(100, response->headers->GetContentLength());
5286
[email protected]ea9dc9a2009-09-05 00:43:325287 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345288 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325289}
5290
[email protected]2217aa22013-10-11 03:03:545291
5292// Test the request-challenge-retry sequence for basic auth when there is a
5293// correct identity in the URL, but its use is being suppressed. The identity
5294// from the URL should never be used.
5295TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5296 HttpRequestInfo request;
5297 request.method = "GET";
5298 request.url = GURL("http://foo:[email protected]/");
5299 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5300
[email protected]3fe8d2f82013-10-17 08:56:075301 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545302 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075303 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2217aa22013-10-11 03:03:545304
5305 MockWrite data_writes1[] = {
5306 MockWrite("GET / HTTP/1.1\r\n"
5307 "Host: www.google.com\r\n"
5308 "Connection: keep-alive\r\n\r\n"),
5309 };
5310
5311 MockRead data_reads1[] = {
5312 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5313 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5314 MockRead("Content-Length: 10\r\n\r\n"),
5315 MockRead(SYNCHRONOUS, ERR_FAILED),
5316 };
5317
5318 // After the challenge above, the transaction will be restarted using the
5319 // identity supplied by the user, not the one in the URL, to answer the
5320 // challenge.
5321 MockWrite data_writes3[] = {
5322 MockWrite("GET / HTTP/1.1\r\n"
5323 "Host: www.google.com\r\n"
5324 "Connection: keep-alive\r\n"
5325 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5326 };
5327
5328 MockRead data_reads3[] = {
5329 MockRead("HTTP/1.0 200 OK\r\n"),
5330 MockRead("Content-Length: 100\r\n\r\n"),
5331 MockRead(SYNCHRONOUS, OK),
5332 };
5333
5334 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5335 data_writes1, arraysize(data_writes1));
5336 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5337 data_writes3, arraysize(data_writes3));
5338 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5339 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5340
5341 TestCompletionCallback callback1;
5342 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5343 EXPECT_EQ(ERR_IO_PENDING, rv);
5344 rv = callback1.WaitForResult();
5345 EXPECT_EQ(OK, rv);
5346 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5347
5348 const HttpResponseInfo* response = trans->GetResponseInfo();
5349 ASSERT_TRUE(response != NULL);
5350 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5351
5352 TestCompletionCallback callback3;
5353 rv = trans->RestartWithAuth(
5354 AuthCredentials(kFoo, kBar), callback3.callback());
5355 EXPECT_EQ(ERR_IO_PENDING, rv);
5356 rv = callback3.WaitForResult();
5357 EXPECT_EQ(OK, rv);
5358 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5359
5360 response = trans->GetResponseInfo();
5361 ASSERT_TRUE(response != NULL);
5362
5363 // There is no challenge info, since the identity worked.
5364 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5365 EXPECT_EQ(100, response->headers->GetContentLength());
5366
5367 // Empty the current queue.
5368 base::MessageLoop::current()->RunUntilIdle();
5369}
5370
[email protected]f9ee6b52008-11-08 06:46:235371// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025372TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075373 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235374
5375 // Transaction 1: authenticate (foo, bar) on MyRealm1
5376 {
[email protected]1c773ea12009-04-28 19:58:425377 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235378 request.method = "GET";
5379 request.url = GURL("http://www.google.com/x/y/z");
5380 request.load_flags = 0;
5381
[email protected]262eec82013-03-19 21:01:365382 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275384
[email protected]f9ee6b52008-11-08 06:46:235385 MockWrite data_writes1[] = {
5386 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5387 "Host: www.google.com\r\n"
5388 "Connection: keep-alive\r\n\r\n"),
5389 };
5390
5391 MockRead data_reads1[] = {
5392 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5393 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5394 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065395 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235396 };
5397
5398 // Resend with authorization (username=foo, password=bar)
5399 MockWrite data_writes2[] = {
5400 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5401 "Host: www.google.com\r\n"
5402 "Connection: keep-alive\r\n"
5403 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5404 };
5405
5406 // Sever accepts the authorization.
5407 MockRead data_reads2[] = {
5408 MockRead("HTTP/1.0 200 OK\r\n"),
5409 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065410 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235411 };
5412
[email protected]31a2bfe2010-02-09 08:03:395413 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5414 data_writes1, arraysize(data_writes1));
5415 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5416 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075417 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5418 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235419
[email protected]49639fa2011-12-20 23:22:415420 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235421
[email protected]49639fa2011-12-20 23:22:415422 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425423 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235424
5425 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425426 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235427
[email protected]1c773ea12009-04-28 19:58:425428 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505429 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045430 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235431
[email protected]49639fa2011-12-20 23:22:415432 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235433
[email protected]49639fa2011-12-20 23:22:415434 rv = trans->RestartWithAuth(
5435 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425436 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235437
5438 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425439 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235440
5441 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505442 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235443 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5444 EXPECT_EQ(100, response->headers->GetContentLength());
5445 }
5446
5447 // ------------------------------------------------------------------------
5448
5449 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5450 {
[email protected]1c773ea12009-04-28 19:58:425451 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235452 request.method = "GET";
5453 // Note that Transaction 1 was at /x/y/z, so this is in the same
5454 // protection space as MyRealm1.
5455 request.url = GURL("http://www.google.com/x/y/a/b");
5456 request.load_flags = 0;
5457
[email protected]262eec82013-03-19 21:01:365458 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275460
[email protected]f9ee6b52008-11-08 06:46:235461 MockWrite data_writes1[] = {
5462 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5463 "Host: www.google.com\r\n"
5464 "Connection: keep-alive\r\n"
5465 // Send preemptive authorization for MyRealm1
5466 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5467 };
5468
5469 // The server didn't like the preemptive authorization, and
5470 // challenges us for a different realm (MyRealm2).
5471 MockRead data_reads1[] = {
5472 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5473 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5474 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065475 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235476 };
5477
5478 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5479 MockWrite data_writes2[] = {
5480 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5481 "Host: www.google.com\r\n"
5482 "Connection: keep-alive\r\n"
5483 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5484 };
5485
5486 // Sever accepts the authorization.
5487 MockRead data_reads2[] = {
5488 MockRead("HTTP/1.0 200 OK\r\n"),
5489 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065490 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235491 };
5492
[email protected]31a2bfe2010-02-09 08:03:395493 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5494 data_writes1, arraysize(data_writes1));
5495 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5496 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075497 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5498 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235499
[email protected]49639fa2011-12-20 23:22:415500 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235501
[email protected]49639fa2011-12-20 23:22:415502 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425503 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235504
5505 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425506 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235507
[email protected]1c773ea12009-04-28 19:58:425508 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505509 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045510 ASSERT_TRUE(response->auth_challenge.get());
5511 EXPECT_FALSE(response->auth_challenge->is_proxy);
5512 EXPECT_EQ("www.google.com:80",
5513 response->auth_challenge->challenger.ToString());
5514 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5515 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235516
[email protected]49639fa2011-12-20 23:22:415517 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235518
[email protected]49639fa2011-12-20 23:22:415519 rv = trans->RestartWithAuth(
5520 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425521 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235522
5523 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425524 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235525
5526 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505527 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235528 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5529 EXPECT_EQ(100, response->headers->GetContentLength());
5530 }
5531
5532 // ------------------------------------------------------------------------
5533
5534 // Transaction 3: Resend a request in MyRealm's protection space --
5535 // succeed with preemptive authorization.
5536 {
[email protected]1c773ea12009-04-28 19:58:425537 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235538 request.method = "GET";
5539 request.url = GURL("http://www.google.com/x/y/z2");
5540 request.load_flags = 0;
5541
[email protected]262eec82013-03-19 21:01:365542 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505543 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275544
[email protected]f9ee6b52008-11-08 06:46:235545 MockWrite data_writes1[] = {
5546 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5547 "Host: www.google.com\r\n"
5548 "Connection: keep-alive\r\n"
5549 // The authorization for MyRealm1 gets sent preemptively
5550 // (since the url is in the same protection space)
5551 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5552 };
5553
5554 // Sever accepts the preemptive authorization
5555 MockRead data_reads1[] = {
5556 MockRead("HTTP/1.0 200 OK\r\n"),
5557 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065558 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235559 };
5560
[email protected]31a2bfe2010-02-09 08:03:395561 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5562 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075563 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235564
[email protected]49639fa2011-12-20 23:22:415565 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235566
[email protected]49639fa2011-12-20 23:22:415567 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425568 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235569
5570 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425571 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235572
[email protected]1c773ea12009-04-28 19:58:425573 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505574 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235575
5576 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5577 EXPECT_EQ(100, response->headers->GetContentLength());
5578 }
5579
5580 // ------------------------------------------------------------------------
5581
5582 // Transaction 4: request another URL in MyRealm (however the
5583 // url is not known to belong to the protection space, so no pre-auth).
5584 {
[email protected]1c773ea12009-04-28 19:58:425585 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235586 request.method = "GET";
5587 request.url = GURL("http://www.google.com/x/1");
5588 request.load_flags = 0;
5589
[email protected]262eec82013-03-19 21:01:365590 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275592
[email protected]f9ee6b52008-11-08 06:46:235593 MockWrite data_writes1[] = {
5594 MockWrite("GET /x/1 HTTP/1.1\r\n"
5595 "Host: www.google.com\r\n"
5596 "Connection: keep-alive\r\n\r\n"),
5597 };
5598
5599 MockRead data_reads1[] = {
5600 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5601 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5602 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065603 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235604 };
5605
5606 // Resend with authorization from MyRealm's cache.
5607 MockWrite data_writes2[] = {
5608 MockWrite("GET /x/1 HTTP/1.1\r\n"
5609 "Host: www.google.com\r\n"
5610 "Connection: keep-alive\r\n"
5611 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5612 };
5613
5614 // Sever accepts the authorization.
5615 MockRead data_reads2[] = {
5616 MockRead("HTTP/1.0 200 OK\r\n"),
5617 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065618 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235619 };
5620
[email protected]31a2bfe2010-02-09 08:03:395621 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5622 data_writes1, arraysize(data_writes1));
5623 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5624 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075625 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5626 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235627
[email protected]49639fa2011-12-20 23:22:415628 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235629
[email protected]49639fa2011-12-20 23:22:415630 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425631 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235632
5633 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425634 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235635
[email protected]0757e7702009-03-27 04:00:225636 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415637 TestCompletionCallback callback2;
5638 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425639 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225640 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425641 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225642 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5643
[email protected]1c773ea12009-04-28 19:58:425644 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505645 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235646 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5647 EXPECT_EQ(100, response->headers->GetContentLength());
5648 }
5649
5650 // ------------------------------------------------------------------------
5651
5652 // Transaction 5: request a URL in MyRealm, but the server rejects the
5653 // cached identity. Should invalidate and re-prompt.
5654 {
[email protected]1c773ea12009-04-28 19:58:425655 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235656 request.method = "GET";
5657 request.url = GURL("http://www.google.com/p/q/t");
5658 request.load_flags = 0;
5659
[email protected]262eec82013-03-19 21:01:365660 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505661 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275662
[email protected]f9ee6b52008-11-08 06:46:235663 MockWrite data_writes1[] = {
5664 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5665 "Host: www.google.com\r\n"
5666 "Connection: keep-alive\r\n\r\n"),
5667 };
5668
5669 MockRead data_reads1[] = {
5670 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5671 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5672 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065673 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235674 };
5675
5676 // Resend with authorization from cache for MyRealm.
5677 MockWrite data_writes2[] = {
5678 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5679 "Host: www.google.com\r\n"
5680 "Connection: keep-alive\r\n"
5681 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5682 };
5683
5684 // Sever rejects the authorization.
5685 MockRead data_reads2[] = {
5686 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5687 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5688 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065689 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235690 };
5691
5692 // At this point we should prompt for new credentials for MyRealm.
5693 // Restart with username=foo3, password=foo4.
5694 MockWrite data_writes3[] = {
5695 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5696 "Host: www.google.com\r\n"
5697 "Connection: keep-alive\r\n"
5698 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5699 };
5700
5701 // Sever accepts the authorization.
5702 MockRead data_reads3[] = {
5703 MockRead("HTTP/1.0 200 OK\r\n"),
5704 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065705 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235706 };
5707
[email protected]31a2bfe2010-02-09 08:03:395708 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5709 data_writes1, arraysize(data_writes1));
5710 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5711 data_writes2, arraysize(data_writes2));
5712 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5713 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075714 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5715 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5716 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235717
[email protected]49639fa2011-12-20 23:22:415718 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235719
[email protected]49639fa2011-12-20 23:22:415720 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425721 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235722
5723 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425724 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235725
[email protected]0757e7702009-03-27 04:00:225726 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415727 TestCompletionCallback callback2;
5728 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425729 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225730 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425731 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225732 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5733
[email protected]1c773ea12009-04-28 19:58:425734 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505735 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045736 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235737
[email protected]49639fa2011-12-20 23:22:415738 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235739
[email protected]49639fa2011-12-20 23:22:415740 rv = trans->RestartWithAuth(
5741 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425742 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235743
[email protected]0757e7702009-03-27 04:00:225744 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425745 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235746
5747 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505748 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235749 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5750 EXPECT_EQ(100, response->headers->GetContentLength());
5751 }
5752}
[email protected]89ceba9a2009-03-21 03:46:065753
[email protected]3c32c5f2010-05-18 15:18:125754// Tests that nonce count increments when multiple auth attempts
5755// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025756TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445757 HttpAuthHandlerDigest::Factory* digest_factory =
5758 new HttpAuthHandlerDigest::Factory();
5759 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5760 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5761 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075762 session_deps_.http_auth_handler_factory.reset(digest_factory);
5763 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125764
5765 // Transaction 1: authenticate (foo, bar) on MyRealm1
5766 {
[email protected]3c32c5f2010-05-18 15:18:125767 HttpRequestInfo request;
5768 request.method = "GET";
5769 request.url = GURL("http://www.google.com/x/y/z");
5770 request.load_flags = 0;
5771
[email protected]262eec82013-03-19 21:01:365772 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505773 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275774
[email protected]3c32c5f2010-05-18 15:18:125775 MockWrite data_writes1[] = {
5776 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5777 "Host: www.google.com\r\n"
5778 "Connection: keep-alive\r\n\r\n"),
5779 };
5780
5781 MockRead data_reads1[] = {
5782 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5783 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5784 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065785 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125786 };
5787
5788 // Resend with authorization (username=foo, password=bar)
5789 MockWrite data_writes2[] = {
5790 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5791 "Host: www.google.com\r\n"
5792 "Connection: keep-alive\r\n"
5793 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5794 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5795 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5796 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5797 };
5798
5799 // Sever accepts the authorization.
5800 MockRead data_reads2[] = {
5801 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065802 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125803 };
5804
5805 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5806 data_writes1, arraysize(data_writes1));
5807 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5808 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075809 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5810 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125811
[email protected]49639fa2011-12-20 23:22:415812 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125813
[email protected]49639fa2011-12-20 23:22:415814 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125815 EXPECT_EQ(ERR_IO_PENDING, rv);
5816
5817 rv = callback1.WaitForResult();
5818 EXPECT_EQ(OK, rv);
5819
5820 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505821 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045822 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125823
[email protected]49639fa2011-12-20 23:22:415824 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125825
[email protected]49639fa2011-12-20 23:22:415826 rv = trans->RestartWithAuth(
5827 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125828 EXPECT_EQ(ERR_IO_PENDING, rv);
5829
5830 rv = callback2.WaitForResult();
5831 EXPECT_EQ(OK, rv);
5832
5833 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505834 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125835 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5836 }
5837
5838 // ------------------------------------------------------------------------
5839
5840 // Transaction 2: Request another resource in digestive's protection space.
5841 // This will preemptively add an Authorization header which should have an
5842 // "nc" value of 2 (as compared to 1 in the first use.
5843 {
[email protected]3c32c5f2010-05-18 15:18:125844 HttpRequestInfo request;
5845 request.method = "GET";
5846 // Note that Transaction 1 was at /x/y/z, so this is in the same
5847 // protection space as digest.
5848 request.url = GURL("http://www.google.com/x/y/a/b");
5849 request.load_flags = 0;
5850
[email protected]262eec82013-03-19 21:01:365851 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275853
[email protected]3c32c5f2010-05-18 15:18:125854 MockWrite data_writes1[] = {
5855 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5856 "Host: www.google.com\r\n"
5857 "Connection: keep-alive\r\n"
5858 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5859 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5860 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5861 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5862 };
5863
5864 // Sever accepts the authorization.
5865 MockRead data_reads1[] = {
5866 MockRead("HTTP/1.0 200 OK\r\n"),
5867 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065868 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125869 };
5870
5871 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5872 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075873 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125874
[email protected]49639fa2011-12-20 23:22:415875 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125876
[email protected]49639fa2011-12-20 23:22:415877 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125878 EXPECT_EQ(ERR_IO_PENDING, rv);
5879
5880 rv = callback1.WaitForResult();
5881 EXPECT_EQ(OK, rv);
5882
5883 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505884 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125885 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5886 }
5887}
5888
[email protected]89ceba9a2009-03-21 03:46:065889// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025890TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065891 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075892 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405893 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075894 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]89ceba9a2009-03-21 03:46:065895
5896 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065897 trans->read_buf_ = new IOBuffer(15);
5898 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205899 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065900
5901 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145902 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575903 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085904 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575905 response->response_time = base::Time::Now();
5906 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065907
5908 { // Setup state for response_.vary_data
5909 HttpRequestInfo request;
5910 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5911 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275912 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435913 request.extra_headers.SetHeader("Foo", "1");
5914 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505915 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065916 }
5917
5918 // Cause the above state to be reset.
5919 trans->ResetStateForRestart();
5920
5921 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075922 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065923 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205924 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575925 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5926 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045927 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085928 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575929 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065930}
5931
[email protected]bacff652009-03-31 17:50:335932// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025933TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335934 HttpRequestInfo request;
5935 request.method = "GET";
5936 request.url = GURL("https://www.google.com/");
5937 request.load_flags = 0;
5938
[email protected]3fe8d2f82013-10-17 08:56:075939 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275940 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075941 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275942
[email protected]bacff652009-03-31 17:50:335943 MockWrite data_writes[] = {
5944 MockWrite("GET / HTTP/1.1\r\n"
5945 "Host: www.google.com\r\n"
5946 "Connection: keep-alive\r\n\r\n"),
5947 };
5948
5949 MockRead data_reads[] = {
5950 MockRead("HTTP/1.0 200 OK\r\n"),
5951 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5952 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065953 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335954 };
5955
[email protected]5ecc992a42009-11-11 01:41:595956 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395957 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5958 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065959 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5960 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335961
[email protected]bb88e1d32013-05-03 23:11:075962 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5963 session_deps_.socket_factory->AddSocketDataProvider(&data);
5964 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5965 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335966
[email protected]49639fa2011-12-20 23:22:415967 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335968
[email protected]49639fa2011-12-20 23:22:415969 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335970 EXPECT_EQ(ERR_IO_PENDING, rv);
5971
5972 rv = callback.WaitForResult();
5973 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5974
[email protected]49639fa2011-12-20 23:22:415975 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335976 EXPECT_EQ(ERR_IO_PENDING, rv);
5977
5978 rv = callback.WaitForResult();
5979 EXPECT_EQ(OK, rv);
5980
5981 const HttpResponseInfo* response = trans->GetResponseInfo();
5982
[email protected]fe2255a2011-09-20 19:37:505983 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335984 EXPECT_EQ(100, response->headers->GetContentLength());
5985}
5986
5987// Test HTTPS connections to a site with a bad certificate, going through a
5988// proxy
[email protected]23e482282013-06-14 16:08:025989TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075990 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335991
5992 HttpRequestInfo request;
5993 request.method = "GET";
5994 request.url = GURL("https://www.google.com/");
5995 request.load_flags = 0;
5996
5997 MockWrite proxy_writes[] = {
5998 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455999 "Host: www.google.com\r\n"
6000 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336001 };
6002
6003 MockRead proxy_reads[] = {
6004 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066005 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336006 };
6007
6008 MockWrite data_writes[] = {
6009 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456010 "Host: www.google.com\r\n"
6011 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336012 MockWrite("GET / HTTP/1.1\r\n"
6013 "Host: www.google.com\r\n"
6014 "Connection: keep-alive\r\n\r\n"),
6015 };
6016
6017 MockRead data_reads[] = {
6018 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6019 MockRead("HTTP/1.0 200 OK\r\n"),
6020 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6021 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066022 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336023 };
6024
[email protected]31a2bfe2010-02-09 08:03:396025 StaticSocketDataProvider ssl_bad_certificate(
6026 proxy_reads, arraysize(proxy_reads),
6027 proxy_writes, arraysize(proxy_writes));
6028 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6029 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066030 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6031 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336032
[email protected]bb88e1d32013-05-03 23:11:076033 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6034 session_deps_.socket_factory->AddSocketDataProvider(&data);
6035 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336037
[email protected]49639fa2011-12-20 23:22:416038 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336039
6040 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076041 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336042
[email protected]3fe8d2f82013-10-17 08:56:076043 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406044 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076045 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]bacff652009-03-31 17:50:336046
[email protected]49639fa2011-12-20 23:22:416047 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336048 EXPECT_EQ(ERR_IO_PENDING, rv);
6049
6050 rv = callback.WaitForResult();
6051 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6052
[email protected]49639fa2011-12-20 23:22:416053 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336054 EXPECT_EQ(ERR_IO_PENDING, rv);
6055
6056 rv = callback.WaitForResult();
6057 EXPECT_EQ(OK, rv);
6058
6059 const HttpResponseInfo* response = trans->GetResponseInfo();
6060
[email protected]fe2255a2011-09-20 19:37:506061 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336062 EXPECT_EQ(100, response->headers->GetContentLength());
6063 }
6064}
6065
[email protected]2df19bb2010-08-25 20:13:466066
6067// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026068TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076069 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206070 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6071 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076072 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466073
6074 HttpRequestInfo request;
6075 request.method = "GET";
6076 request.url = GURL("https://www.google.com/");
6077 request.load_flags = 0;
6078
6079 MockWrite data_writes[] = {
6080 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6081 "Host: www.google.com\r\n"
6082 "Proxy-Connection: keep-alive\r\n\r\n"),
6083 MockWrite("GET / HTTP/1.1\r\n"
6084 "Host: www.google.com\r\n"
6085 "Connection: keep-alive\r\n\r\n"),
6086 };
6087
6088 MockRead data_reads[] = {
6089 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6090 MockRead("HTTP/1.1 200 OK\r\n"),
6091 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6092 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066093 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466094 };
6095
6096 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6097 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066098 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6099 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466100
[email protected]bb88e1d32013-05-03 23:11:076101 session_deps_.socket_factory->AddSocketDataProvider(&data);
6102 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6103 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466104
[email protected]49639fa2011-12-20 23:22:416105 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466106
[email protected]3fe8d2f82013-10-17 08:56:076107 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466108 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466110
[email protected]49639fa2011-12-20 23:22:416111 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466112 EXPECT_EQ(ERR_IO_PENDING, rv);
6113
6114 rv = callback.WaitForResult();
6115 EXPECT_EQ(OK, rv);
6116 const HttpResponseInfo* response = trans->GetResponseInfo();
6117
[email protected]fe2255a2011-09-20 19:37:506118 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466119
6120 EXPECT_TRUE(response->headers->IsKeepAlive());
6121 EXPECT_EQ(200, response->headers->response_code());
6122 EXPECT_EQ(100, response->headers->GetContentLength());
6123 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206124
6125 LoadTimingInfo load_timing_info;
6126 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6127 TestLoadTimingNotReusedWithPac(load_timing_info,
6128 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466129}
6130
[email protected]511f6f52010-12-17 03:58:296131// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026132TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076133 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206134 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6135 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076136 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296137
6138 HttpRequestInfo request;
6139 request.method = "GET";
6140 request.url = GURL("https://www.google.com/");
6141 request.load_flags = 0;
6142
6143 MockWrite data_writes[] = {
6144 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6145 "Host: www.google.com\r\n"
6146 "Proxy-Connection: keep-alive\r\n\r\n"),
6147 };
6148
6149 MockRead data_reads[] = {
6150 MockRead("HTTP/1.1 302 Redirect\r\n"),
6151 MockRead("Location: http://login.example.com/\r\n"),
6152 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066153 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296154 };
6155
6156 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6157 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066158 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296159
[email protected]bb88e1d32013-05-03 23:11:076160 session_deps_.socket_factory->AddSocketDataProvider(&data);
6161 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296162
[email protected]49639fa2011-12-20 23:22:416163 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296164
[email protected]3fe8d2f82013-10-17 08:56:076165 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296166 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076167 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296168
[email protected]49639fa2011-12-20 23:22:416169 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296170 EXPECT_EQ(ERR_IO_PENDING, rv);
6171
6172 rv = callback.WaitForResult();
6173 EXPECT_EQ(OK, rv);
6174 const HttpResponseInfo* response = trans->GetResponseInfo();
6175
[email protected]fe2255a2011-09-20 19:37:506176 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296177
6178 EXPECT_EQ(302, response->headers->response_code());
6179 std::string url;
6180 EXPECT_TRUE(response->headers->IsRedirect(&url));
6181 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206182
6183 // In the case of redirects from proxies, HttpNetworkTransaction returns
6184 // timing for the proxy connection instead of the connection to the host,
6185 // and no send / receive times.
6186 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6187 LoadTimingInfo load_timing_info;
6188 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6189
6190 EXPECT_FALSE(load_timing_info.socket_reused);
6191 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6192
6193 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6194 EXPECT_LE(load_timing_info.proxy_resolve_start,
6195 load_timing_info.proxy_resolve_end);
6196 EXPECT_LE(load_timing_info.proxy_resolve_end,
6197 load_timing_info.connect_timing.connect_start);
6198 ExpectConnectTimingHasTimes(
6199 load_timing_info.connect_timing,
6200 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6201
6202 EXPECT_TRUE(load_timing_info.send_start.is_null());
6203 EXPECT_TRUE(load_timing_info.send_end.is_null());
6204 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296205}
6206
6207// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026208TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076209 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296210 ProxyService::CreateFixed("https://proxy:70"));
6211
6212 HttpRequestInfo request;
6213 request.method = "GET";
6214 request.url = GURL("https://www.google.com/");
6215 request.load_flags = 0;
6216
[email protected]9075f51c2013-08-15 17:53:546217 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6218 LOWEST));
[email protected]c10b20852013-05-15 21:29:206219 scoped_ptr<SpdyFrame> goaway(
6220 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296221 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066222 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:126223 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296224 };
6225
6226 static const char* const kExtraHeaders[] = {
6227 "location",
6228 "http://login.example.com/",
6229 };
[email protected]ff98d7f02012-03-22 21:44:196230 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026231 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296232 arraysize(kExtraHeaders)/2, 1));
6233 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066234 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6235 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:296236 };
6237
[email protected]dd54bd82012-07-19 23:44:576238 DelayedSocketData data(
6239 1, // wait for one write to finish before reading.
6240 data_reads, arraysize(data_reads),
6241 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066242 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026243 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296244
[email protected]bb88e1d32013-05-03 23:11:076245 session_deps_.socket_factory->AddSocketDataProvider(&data);
6246 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296247
[email protected]49639fa2011-12-20 23:22:416248 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296249
[email protected]3fe8d2f82013-10-17 08:56:076250 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296251 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076252 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296253
[email protected]49639fa2011-12-20 23:22:416254 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296255 EXPECT_EQ(ERR_IO_PENDING, rv);
6256
6257 rv = callback.WaitForResult();
6258 EXPECT_EQ(OK, rv);
6259 const HttpResponseInfo* response = trans->GetResponseInfo();
6260
[email protected]fe2255a2011-09-20 19:37:506261 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296262
6263 EXPECT_EQ(302, response->headers->response_code());
6264 std::string url;
6265 EXPECT_TRUE(response->headers->IsRedirect(&url));
6266 EXPECT_EQ("http://login.example.com/", url);
6267}
6268
[email protected]4eddbc732012-08-09 05:40:176269// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026270TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176271 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076272 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296273 ProxyService::CreateFixed("https://proxy:70"));
6274
6275 HttpRequestInfo request;
6276 request.method = "GET";
6277 request.url = GURL("https://www.google.com/");
6278 request.load_flags = 0;
6279
6280 MockWrite data_writes[] = {
6281 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6282 "Host: www.google.com\r\n"
6283 "Proxy-Connection: keep-alive\r\n\r\n"),
6284 };
6285
6286 MockRead data_reads[] = {
6287 MockRead("HTTP/1.1 404 Not Found\r\n"),
6288 MockRead("Content-Length: 23\r\n\r\n"),
6289 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066290 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296291 };
6292
6293 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6294 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066295 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296296
[email protected]bb88e1d32013-05-03 23:11:076297 session_deps_.socket_factory->AddSocketDataProvider(&data);
6298 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296299
[email protected]49639fa2011-12-20 23:22:416300 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296301
[email protected]3fe8d2f82013-10-17 08:56:076302 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296303 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296305
[email protected]49639fa2011-12-20 23:22:416306 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296307 EXPECT_EQ(ERR_IO_PENDING, rv);
6308
6309 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176310 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296311
[email protected]4eddbc732012-08-09 05:40:176312 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296313}
6314
[email protected]4eddbc732012-08-09 05:40:176315// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026316TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176317 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076318 session_deps_.proxy_service.reset(
6319 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296320
6321 HttpRequestInfo request;
6322 request.method = "GET";
6323 request.url = GURL("https://www.google.com/");
6324 request.load_flags = 0;
6325
[email protected]9075f51c2013-08-15 17:53:546326 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6327 LOWEST));
[email protected]c10b20852013-05-15 21:29:206328 scoped_ptr<SpdyFrame> rst(
6329 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296330 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066331 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176332 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296333 };
6334
6335 static const char* const kExtraHeaders[] = {
6336 "location",
6337 "http://login.example.com/",
6338 };
[email protected]ff98d7f02012-03-22 21:44:196339 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026340 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296341 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196342 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026343 spdy_util_.ConstructSpdyBodyFrame(
6344 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296345 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066346 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6347 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176348 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296349 };
6350
[email protected]dd54bd82012-07-19 23:44:576351 DelayedSocketData data(
6352 1, // wait for one write to finish before reading.
6353 data_reads, arraysize(data_reads),
6354 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066355 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026356 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296357
[email protected]bb88e1d32013-05-03 23:11:076358 session_deps_.socket_factory->AddSocketDataProvider(&data);
6359 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296360
[email protected]49639fa2011-12-20 23:22:416361 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296362
[email protected]3fe8d2f82013-10-17 08:56:076363 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296364 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076365 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296366
[email protected]49639fa2011-12-20 23:22:416367 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296368 EXPECT_EQ(ERR_IO_PENDING, rv);
6369
6370 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176371 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296372
[email protected]4eddbc732012-08-09 05:40:176373 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296374}
6375
[email protected]0c5fb722012-02-28 11:50:356376// Test the request-challenge-retry sequence for basic auth, through
6377// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026378TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356379 HttpRequestInfo request;
6380 request.method = "GET";
6381 request.url = GURL("https://www.google.com/");
6382 // when the no authentication data flag is set.
6383 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6384
6385 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076386 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206387 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296388 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076389 session_deps_.net_log = log.bound().net_log();
6390 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356391
6392 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:546393 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6394 LOWEST));
[email protected]c10b20852013-05-15 21:29:206395 scoped_ptr<SpdyFrame> rst(
6396 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356397
6398 // After calling trans->RestartWithAuth(), this is the request we should
6399 // be issuing -- the final header line contains the credentials.
6400 const char* const kAuthCredentials[] = {
6401 "proxy-authorization", "Basic Zm9vOmJhcg==",
6402 };
[email protected]fba2dbde2013-05-24 16:09:016403 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:546404 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:356405 // fetch https://www.google.com/ via HTTP
6406 const char get[] = "GET / HTTP/1.1\r\n"
6407 "Host: www.google.com\r\n"
6408 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196409 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026410 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356411
6412 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206413 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216414 CreateMockWrite(*rst, 4, ASYNC),
6415 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206416 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356417 };
6418
6419 // The proxy responds to the connect with a 407, using a persistent
6420 // connection.
[email protected]745aa9c2014-06-27 02:21:296421 const char* const kAuthStatus = "407";
[email protected]0c5fb722012-02-28 11:50:356422 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356423 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6424 };
[email protected]745aa9c2014-06-27 02:21:296425 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6426 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356427
[email protected]23e482282013-06-14 16:08:026428 scoped_ptr<SpdyFrame> conn_resp(
6429 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356430 const char resp[] = "HTTP/1.1 200 OK\r\n"
6431 "Content-Length: 5\r\n\r\n";
6432
[email protected]ff98d7f02012-03-22 21:44:196433 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026434 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196435 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026436 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356437 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206438 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6439 CreateMockRead(*conn_resp, 6, ASYNC),
6440 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6441 CreateMockRead(*wrapped_body, 10, ASYNC),
6442 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356443 };
6444
[email protected]dd54bd82012-07-19 23:44:576445 OrderedSocketData spdy_data(
6446 spdy_reads, arraysize(spdy_reads),
6447 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076448 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356449 // Negotiate SPDY to the proxy
6450 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026451 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076452 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356453 // Vanilla SSL to the server
6454 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076455 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356456
6457 TestCompletionCallback callback1;
6458
[email protected]262eec82013-03-19 21:01:366459 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506460 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356461
6462 int rv = trans->Start(&request, callback1.callback(), log.bound());
6463 EXPECT_EQ(ERR_IO_PENDING, rv);
6464
6465 rv = callback1.WaitForResult();
6466 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576467 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356468 log.GetEntries(&entries);
6469 size_t pos = ExpectLogContainsSomewhere(
6470 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6471 NetLog::PHASE_NONE);
6472 ExpectLogContainsSomewhere(
6473 entries, pos,
6474 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6475 NetLog::PHASE_NONE);
6476
6477 const HttpResponseInfo* response = trans->GetResponseInfo();
6478 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506479 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356480 EXPECT_EQ(407, response->headers->response_code());
6481 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6482 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6483 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6484
6485 TestCompletionCallback callback2;
6486
6487 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6488 callback2.callback());
6489 EXPECT_EQ(ERR_IO_PENDING, rv);
6490
6491 rv = callback2.WaitForResult();
6492 EXPECT_EQ(OK, rv);
6493
6494 response = trans->GetResponseInfo();
6495 ASSERT_TRUE(response != NULL);
6496
6497 EXPECT_TRUE(response->headers->IsKeepAlive());
6498 EXPECT_EQ(200, response->headers->response_code());
6499 EXPECT_EQ(5, response->headers->GetContentLength());
6500 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6501
6502 // The password prompt info should not be set.
6503 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6504
[email protected]029c83b62013-01-24 05:28:206505 LoadTimingInfo load_timing_info;
6506 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6507 TestLoadTimingNotReusedWithPac(load_timing_info,
6508 CONNECT_TIMING_HAS_SSL_TIMES);
6509
[email protected]0c5fb722012-02-28 11:50:356510 trans.reset();
6511 session->CloseAllConnections();
6512}
6513
[email protected]7c6f7ba2012-04-03 04:09:296514// Test that an explicitly trusted SPDY proxy can push a resource from an
6515// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026516TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296517 HttpRequestInfo request;
6518 HttpRequestInfo push_request;
6519
[email protected]7c6f7ba2012-04-03 04:09:296520 request.method = "GET";
6521 request.url = GURL("http://www.google.com/");
6522 push_request.method = "GET";
6523 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6524
[email protected]7c6f7ba2012-04-03 04:09:296525 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076526 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206527 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296528 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076529 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506530
6531 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076532 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506533
[email protected]bb88e1d32013-05-03 23:11:076534 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296535
[email protected]cdf8f7e72013-05-23 10:56:466536 scoped_ptr<SpdyFrame> stream1_syn(
6537 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296538
6539 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466540 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296541 };
6542
6543 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026544 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296545
6546 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026547 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296548
6549 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026550 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296551 0,
6552 2,
6553 1,
6554 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436555 const char kPushedData[] = "pushed";
6556 scoped_ptr<SpdyFrame> stream2_body(
6557 spdy_util_.ConstructSpdyBodyFrame(
6558 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296559
6560 MockRead spdy_reads[] = {
6561 CreateMockRead(*stream1_reply, 2, ASYNC),
6562 CreateMockRead(*stream2_syn, 3, ASYNC),
6563 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436564 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296565 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6566 };
6567
[email protected]dd54bd82012-07-19 23:44:576568 OrderedSocketData spdy_data(
6569 spdy_reads, arraysize(spdy_reads),
6570 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076571 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296572 // Negotiate SPDY to the proxy
6573 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026574 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076575 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296576
[email protected]262eec82013-03-19 21:01:366577 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506578 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296579 TestCompletionCallback callback;
6580 int rv = trans->Start(&request, callback.callback(), log.bound());
6581 EXPECT_EQ(ERR_IO_PENDING, rv);
6582
6583 rv = callback.WaitForResult();
6584 EXPECT_EQ(OK, rv);
6585 const HttpResponseInfo* response = trans->GetResponseInfo();
6586
[email protected]262eec82013-03-19 21:01:366587 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506588 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6589 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296590 EXPECT_EQ(ERR_IO_PENDING, rv);
6591
6592 rv = callback.WaitForResult();
6593 EXPECT_EQ(OK, rv);
6594 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6595
6596 ASSERT_TRUE(response != NULL);
6597 EXPECT_TRUE(response->headers->IsKeepAlive());
6598
6599 EXPECT_EQ(200, response->headers->response_code());
6600 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6601
6602 std::string response_data;
6603 rv = ReadTransaction(trans.get(), &response_data);
6604 EXPECT_EQ(OK, rv);
6605 EXPECT_EQ("hello!", response_data);
6606
[email protected]029c83b62013-01-24 05:28:206607 LoadTimingInfo load_timing_info;
6608 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6609 TestLoadTimingNotReusedWithPac(load_timing_info,
6610 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6611
[email protected]7c6f7ba2012-04-03 04:09:296612 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506613 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296614 EXPECT_EQ(200, push_response->headers->response_code());
6615
6616 rv = ReadTransaction(push_trans.get(), &response_data);
6617 EXPECT_EQ(OK, rv);
6618 EXPECT_EQ("pushed", response_data);
6619
[email protected]029c83b62013-01-24 05:28:206620 LoadTimingInfo push_load_timing_info;
6621 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6622 TestLoadTimingReusedWithPac(push_load_timing_info);
6623 // The transactions should share a socket ID, despite being for different
6624 // origins.
6625 EXPECT_EQ(load_timing_info.socket_log_id,
6626 push_load_timing_info.socket_log_id);
6627
[email protected]7c6f7ba2012-04-03 04:09:296628 trans.reset();
6629 push_trans.reset();
6630 session->CloseAllConnections();
6631}
6632
[email protected]8c843192012-04-05 07:15:006633// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026634TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006635 HttpRequestInfo request;
6636
6637 request.method = "GET";
6638 request.url = GURL("http://www.google.com/");
6639
[email protected]8c843192012-04-05 07:15:006640 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076641 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006642 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296643 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076644 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506645
6646 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076647 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506648
[email protected]bb88e1d32013-05-03 23:11:076649 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006650
[email protected]cdf8f7e72013-05-23 10:56:466651 scoped_ptr<SpdyFrame> stream1_syn(
6652 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006653
6654 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206655 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006656
6657 MockWrite spdy_writes[] = {
6658 CreateMockWrite(*stream1_syn, 1, ASYNC),
6659 CreateMockWrite(*push_rst, 4),
6660 };
6661
6662 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026663 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006664
6665 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026666 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006667
6668 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026669 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006670 0,
6671 2,
6672 1,
6673 "https://www.another-origin.com/foo.dat"));
6674
6675 MockRead spdy_reads[] = {
6676 CreateMockRead(*stream1_reply, 2, ASYNC),
6677 CreateMockRead(*stream2_syn, 3, ASYNC),
6678 CreateMockRead(*stream1_body, 5, ASYNC),
6679 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6680 };
6681
[email protected]dd54bd82012-07-19 23:44:576682 OrderedSocketData spdy_data(
6683 spdy_reads, arraysize(spdy_reads),
6684 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076685 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006686 // Negotiate SPDY to the proxy
6687 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026688 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076689 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006690
[email protected]262eec82013-03-19 21:01:366691 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506692 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006693 TestCompletionCallback callback;
6694 int rv = trans->Start(&request, callback.callback(), log.bound());
6695 EXPECT_EQ(ERR_IO_PENDING, rv);
6696
6697 rv = callback.WaitForResult();
6698 EXPECT_EQ(OK, rv);
6699 const HttpResponseInfo* response = trans->GetResponseInfo();
6700
6701 ASSERT_TRUE(response != NULL);
6702 EXPECT_TRUE(response->headers->IsKeepAlive());
6703
6704 EXPECT_EQ(200, response->headers->response_code());
6705 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6706
6707 std::string response_data;
6708 rv = ReadTransaction(trans.get(), &response_data);
6709 EXPECT_EQ(OK, rv);
6710 EXPECT_EQ("hello!", response_data);
6711
6712 trans.reset();
6713 session->CloseAllConnections();
6714}
6715
[email protected]2df19bb2010-08-25 20:13:466716// Test HTTPS connections to a site with a bad certificate, going through an
6717// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026718TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076719 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116720 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466721
6722 HttpRequestInfo request;
6723 request.method = "GET";
6724 request.url = GURL("https://www.google.com/");
6725 request.load_flags = 0;
6726
6727 // Attempt to fetch the URL from a server with a bad cert
6728 MockWrite bad_cert_writes[] = {
6729 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6730 "Host: www.google.com\r\n"
6731 "Proxy-Connection: keep-alive\r\n\r\n"),
6732 };
6733
6734 MockRead bad_cert_reads[] = {
6735 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066736 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466737 };
6738
6739 // Attempt to fetch the URL with a good cert
6740 MockWrite good_data_writes[] = {
6741 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6742 "Host: www.google.com\r\n"
6743 "Proxy-Connection: keep-alive\r\n\r\n"),
6744 MockWrite("GET / HTTP/1.1\r\n"
6745 "Host: www.google.com\r\n"
6746 "Connection: keep-alive\r\n\r\n"),
6747 };
6748
6749 MockRead good_cert_reads[] = {
6750 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6751 MockRead("HTTP/1.0 200 OK\r\n"),
6752 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6753 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066754 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466755 };
6756
6757 StaticSocketDataProvider ssl_bad_certificate(
6758 bad_cert_reads, arraysize(bad_cert_reads),
6759 bad_cert_writes, arraysize(bad_cert_writes));
6760 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6761 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066762 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6763 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466764
6765 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076766 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6767 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6768 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466769
6770 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076771 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6772 session_deps_.socket_factory->AddSocketDataProvider(&data);
6773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466774
[email protected]49639fa2011-12-20 23:22:416775 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466776
[email protected]3fe8d2f82013-10-17 08:56:076777 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466778 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076779 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466780
[email protected]49639fa2011-12-20 23:22:416781 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466782 EXPECT_EQ(ERR_IO_PENDING, rv);
6783
6784 rv = callback.WaitForResult();
6785 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6786
[email protected]49639fa2011-12-20 23:22:416787 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466788 EXPECT_EQ(ERR_IO_PENDING, rv);
6789
6790 rv = callback.WaitForResult();
6791 EXPECT_EQ(OK, rv);
6792
6793 const HttpResponseInfo* response = trans->GetResponseInfo();
6794
[email protected]fe2255a2011-09-20 19:37:506795 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466796 EXPECT_EQ(100, response->headers->GetContentLength());
6797}
6798
[email protected]23e482282013-06-14 16:08:026799TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426800 HttpRequestInfo request;
6801 request.method = "GET";
6802 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436803 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6804 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426805
[email protected]3fe8d2f82013-10-17 08:56:076806 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276807 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076808 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276809
[email protected]1c773ea12009-04-28 19:58:426810 MockWrite data_writes[] = {
6811 MockWrite("GET / HTTP/1.1\r\n"
6812 "Host: www.google.com\r\n"
6813 "Connection: keep-alive\r\n"
6814 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6815 };
6816
6817 // Lastly, the server responds with the actual content.
6818 MockRead data_reads[] = {
6819 MockRead("HTTP/1.0 200 OK\r\n"),
6820 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6821 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066822 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426823 };
6824
[email protected]31a2bfe2010-02-09 08:03:396825 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6826 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076827 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426828
[email protected]49639fa2011-12-20 23:22:416829 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426830
[email protected]49639fa2011-12-20 23:22:416831 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426832 EXPECT_EQ(ERR_IO_PENDING, rv);
6833
6834 rv = callback.WaitForResult();
6835 EXPECT_EQ(OK, rv);
6836}
6837
[email protected]23e482282013-06-14 16:08:026838TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296839 HttpRequestInfo request;
6840 request.method = "GET";
6841 request.url = GURL("https://www.google.com/");
6842 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6843 "Chromium Ultra Awesome X Edition");
6844
[email protected]bb88e1d32013-05-03 23:11:076845 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076846 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276847 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076848 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276849
[email protected]da81f132010-08-18 23:39:296850 MockWrite data_writes[] = {
6851 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6852 "Host: www.google.com\r\n"
6853 "Proxy-Connection: keep-alive\r\n"
6854 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6855 };
6856 MockRead data_reads[] = {
6857 // Return an error, so the transaction stops here (this test isn't
6858 // interested in the rest).
6859 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6860 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6861 MockRead("Proxy-Connection: close\r\n\r\n"),
6862 };
6863
6864 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6865 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076866 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296867
[email protected]49639fa2011-12-20 23:22:416868 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296869
[email protected]49639fa2011-12-20 23:22:416870 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296871 EXPECT_EQ(ERR_IO_PENDING, rv);
6872
6873 rv = callback.WaitForResult();
6874 EXPECT_EQ(OK, rv);
6875}
6876
[email protected]23e482282013-06-14 16:08:026877TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426878 HttpRequestInfo request;
6879 request.method = "GET";
6880 request.url = GURL("http://www.google.com/");
6881 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166882 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6883 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426884
[email protected]3fe8d2f82013-10-17 08:56:076885 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276886 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076887 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276888
[email protected]1c773ea12009-04-28 19:58:426889 MockWrite data_writes[] = {
6890 MockWrite("GET / HTTP/1.1\r\n"
6891 "Host: www.google.com\r\n"
6892 "Connection: keep-alive\r\n"
6893 "Referer: http://the.previous.site.com/\r\n\r\n"),
6894 };
6895
6896 // Lastly, the server responds with the actual content.
6897 MockRead data_reads[] = {
6898 MockRead("HTTP/1.0 200 OK\r\n"),
6899 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6900 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066901 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426902 };
6903
[email protected]31a2bfe2010-02-09 08:03:396904 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6905 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076906 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426907
[email protected]49639fa2011-12-20 23:22:416908 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426909
[email protected]49639fa2011-12-20 23:22:416910 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426911 EXPECT_EQ(ERR_IO_PENDING, rv);
6912
6913 rv = callback.WaitForResult();
6914 EXPECT_EQ(OK, rv);
6915}
6916
[email protected]23e482282013-06-14 16:08:026917TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426918 HttpRequestInfo request;
6919 request.method = "POST";
6920 request.url = GURL("http://www.google.com/");
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("POST / HTTP/1.1\r\n"
6928 "Host: www.google.com\r\n"
6929 "Connection: keep-alive\r\n"
6930 "Content-Length: 0\r\n\r\n"),
6931 };
6932
6933 // Lastly, the server responds with the actual content.
6934 MockRead data_reads[] = {
6935 MockRead("HTTP/1.0 200 OK\r\n"),
6936 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6937 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066938 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426939 };
6940
[email protected]31a2bfe2010-02-09 08:03:396941 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6942 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076943 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426944
[email protected]49639fa2011-12-20 23:22:416945 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426946
[email protected]49639fa2011-12-20 23:22:416947 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426948 EXPECT_EQ(ERR_IO_PENDING, rv);
6949
6950 rv = callback.WaitForResult();
6951 EXPECT_EQ(OK, rv);
6952}
6953
[email protected]23e482282013-06-14 16:08:026954TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426955 HttpRequestInfo request;
6956 request.method = "PUT";
6957 request.url = GURL("http://www.google.com/");
6958
[email protected]3fe8d2f82013-10-17 08:56:076959 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276960 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076961 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276962
[email protected]1c773ea12009-04-28 19:58:426963 MockWrite data_writes[] = {
6964 MockWrite("PUT / HTTP/1.1\r\n"
6965 "Host: www.google.com\r\n"
6966 "Connection: keep-alive\r\n"
6967 "Content-Length: 0\r\n\r\n"),
6968 };
6969
6970 // Lastly, the server responds with the actual content.
6971 MockRead data_reads[] = {
6972 MockRead("HTTP/1.0 200 OK\r\n"),
6973 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6974 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066975 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426976 };
6977
[email protected]31a2bfe2010-02-09 08:03:396978 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6979 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076980 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426981
[email protected]49639fa2011-12-20 23:22:416982 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426983
[email protected]49639fa2011-12-20 23:22:416984 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426985 EXPECT_EQ(ERR_IO_PENDING, rv);
6986
6987 rv = callback.WaitForResult();
6988 EXPECT_EQ(OK, rv);
6989}
6990
[email protected]23e482282013-06-14 16:08:026991TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426992 HttpRequestInfo request;
6993 request.method = "HEAD";
6994 request.url = GURL("http://www.google.com/");
6995
[email protected]3fe8d2f82013-10-17 08:56:076996 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276997 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076998 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276999
[email protected]1c773ea12009-04-28 19:58:427000 MockWrite data_writes[] = {
7001 MockWrite("HEAD / HTTP/1.1\r\n"
7002 "Host: www.google.com\r\n"
7003 "Connection: keep-alive\r\n"
7004 "Content-Length: 0\r\n\r\n"),
7005 };
7006
7007 // Lastly, the server responds with the actual content.
7008 MockRead data_reads[] = {
7009 MockRead("HTTP/1.0 200 OK\r\n"),
7010 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7011 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067012 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427013 };
7014
[email protected]31a2bfe2010-02-09 08:03:397015 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7016 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077017 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427018
[email protected]49639fa2011-12-20 23:22:417019 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427020
[email protected]49639fa2011-12-20 23:22:417021 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427022 EXPECT_EQ(ERR_IO_PENDING, rv);
7023
7024 rv = callback.WaitForResult();
7025 EXPECT_EQ(OK, rv);
7026}
7027
[email protected]23e482282013-06-14 16:08:027028TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427029 HttpRequestInfo request;
7030 request.method = "GET";
7031 request.url = GURL("http://www.google.com/");
7032 request.load_flags = LOAD_BYPASS_CACHE;
7033
[email protected]3fe8d2f82013-10-17 08:56:077034 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277035 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077036 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277037
[email protected]1c773ea12009-04-28 19:58:427038 MockWrite data_writes[] = {
7039 MockWrite("GET / HTTP/1.1\r\n"
7040 "Host: www.google.com\r\n"
7041 "Connection: keep-alive\r\n"
7042 "Pragma: no-cache\r\n"
7043 "Cache-Control: no-cache\r\n\r\n"),
7044 };
7045
7046 // Lastly, the server responds with the actual content.
7047 MockRead data_reads[] = {
7048 MockRead("HTTP/1.0 200 OK\r\n"),
7049 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7050 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067051 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427052 };
7053
[email protected]31a2bfe2010-02-09 08:03:397054 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7055 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077056 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427057
[email protected]49639fa2011-12-20 23:22:417058 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427059
[email protected]49639fa2011-12-20 23:22:417060 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427061 EXPECT_EQ(ERR_IO_PENDING, rv);
7062
7063 rv = callback.WaitForResult();
7064 EXPECT_EQ(OK, rv);
7065}
7066
[email protected]23e482282013-06-14 16:08:027067TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427068 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427069 HttpRequestInfo request;
7070 request.method = "GET";
7071 request.url = GURL("http://www.google.com/");
7072 request.load_flags = LOAD_VALIDATE_CACHE;
7073
[email protected]3fe8d2f82013-10-17 08:56:077074 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277075 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077076 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277077
[email protected]1c773ea12009-04-28 19:58:427078 MockWrite data_writes[] = {
7079 MockWrite("GET / HTTP/1.1\r\n"
7080 "Host: www.google.com\r\n"
7081 "Connection: keep-alive\r\n"
7082 "Cache-Control: max-age=0\r\n\r\n"),
7083 };
7084
7085 // Lastly, the server responds with the actual content.
7086 MockRead data_reads[] = {
7087 MockRead("HTTP/1.0 200 OK\r\n"),
7088 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7089 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067090 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427091 };
7092
[email protected]31a2bfe2010-02-09 08:03:397093 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7094 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077095 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427096
[email protected]49639fa2011-12-20 23:22:417097 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427098
[email protected]49639fa2011-12-20 23:22:417099 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427100 EXPECT_EQ(ERR_IO_PENDING, rv);
7101
7102 rv = callback.WaitForResult();
7103 EXPECT_EQ(OK, rv);
7104}
7105
[email protected]23e482282013-06-14 16:08:027106TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427107 HttpRequestInfo request;
7108 request.method = "GET";
7109 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437110 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427111
[email protected]3fe8d2f82013-10-17 08:56:077112 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277113 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077114 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277115
[email protected]1c773ea12009-04-28 19:58:427116 MockWrite data_writes[] = {
7117 MockWrite("GET / HTTP/1.1\r\n"
7118 "Host: www.google.com\r\n"
7119 "Connection: keep-alive\r\n"
7120 "FooHeader: Bar\r\n\r\n"),
7121 };
7122
7123 // Lastly, the server responds with the actual content.
7124 MockRead data_reads[] = {
7125 MockRead("HTTP/1.0 200 OK\r\n"),
7126 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7127 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067128 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427129 };
7130
[email protected]31a2bfe2010-02-09 08:03:397131 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7132 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077133 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427134
[email protected]49639fa2011-12-20 23:22:417135 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427136
[email protected]49639fa2011-12-20 23:22:417137 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427138 EXPECT_EQ(ERR_IO_PENDING, rv);
7139
7140 rv = callback.WaitForResult();
7141 EXPECT_EQ(OK, rv);
7142}
7143
[email protected]23e482282013-06-14 16:08:027144TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477145 HttpRequestInfo request;
7146 request.method = "GET";
7147 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437148 request.extra_headers.SetHeader("referer", "www.foo.com");
7149 request.extra_headers.SetHeader("hEllo", "Kitty");
7150 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477151
[email protected]3fe8d2f82013-10-17 08:56:077152 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277153 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077154 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277155
[email protected]270c6412010-03-29 22:02:477156 MockWrite data_writes[] = {
7157 MockWrite("GET / HTTP/1.1\r\n"
7158 "Host: www.google.com\r\n"
7159 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:167160 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:477161 "hEllo: Kitty\r\n"
7162 "FoO: bar\r\n\r\n"),
7163 };
7164
7165 // Lastly, the server responds with the actual content.
7166 MockRead data_reads[] = {
7167 MockRead("HTTP/1.0 200 OK\r\n"),
7168 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7169 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067170 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477171 };
7172
7173 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7174 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077175 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477176
[email protected]49639fa2011-12-20 23:22:417177 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477178
[email protected]49639fa2011-12-20 23:22:417179 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477180 EXPECT_EQ(ERR_IO_PENDING, rv);
7181
7182 rv = callback.WaitForResult();
7183 EXPECT_EQ(OK, rv);
7184}
7185
[email protected]23e482282013-06-14 16:08:027186TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277187 HttpRequestInfo request;
7188 request.method = "GET";
7189 request.url = GURL("http://www.google.com/");
7190 request.load_flags = 0;
7191
[email protected]bb88e1d32013-05-03 23:11:077192 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207193 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7194 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077195 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027196
[email protected]3fe8d2f82013-10-17 08:56:077197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027198 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027200
[email protected]3cd17242009-06-23 02:59:027201 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7202 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7203
7204 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067205 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027206 MockWrite("GET / HTTP/1.1\r\n"
7207 "Host: www.google.com\r\n"
7208 "Connection: keep-alive\r\n\r\n")
7209 };
7210
7211 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067212 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027213 MockRead("HTTP/1.0 200 OK\r\n"),
7214 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7215 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067216 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027217 };
7218
[email protected]31a2bfe2010-02-09 08:03:397219 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7220 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077221 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027222
[email protected]49639fa2011-12-20 23:22:417223 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027224
[email protected]49639fa2011-12-20 23:22:417225 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027226 EXPECT_EQ(ERR_IO_PENDING, rv);
7227
7228 rv = callback.WaitForResult();
7229 EXPECT_EQ(OK, rv);
7230
7231 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507232 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027233
[email protected]029c83b62013-01-24 05:28:207234 LoadTimingInfo load_timing_info;
7235 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7236 TestLoadTimingNotReusedWithPac(load_timing_info,
7237 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7238
[email protected]3cd17242009-06-23 02:59:027239 std::string response_text;
7240 rv = ReadTransaction(trans.get(), &response_text);
7241 EXPECT_EQ(OK, rv);
7242 EXPECT_EQ("Payload", response_text);
7243}
7244
[email protected]23e482282013-06-14 16:08:027245TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277246 HttpRequestInfo request;
7247 request.method = "GET";
7248 request.url = GURL("https://www.google.com/");
7249 request.load_flags = 0;
7250
[email protected]bb88e1d32013-05-03 23:11:077251 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207252 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7253 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077254 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027255
[email protected]3fe8d2f82013-10-17 08:56:077256 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027257 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077258 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027259
[email protected]3cd17242009-06-23 02:59:027260 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7261 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7262
7263 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067264 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:357265 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027266 MockWrite("GET / HTTP/1.1\r\n"
7267 "Host: www.google.com\r\n"
7268 "Connection: keep-alive\r\n\r\n")
7269 };
7270
7271 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017272 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7273 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357274 MockRead("HTTP/1.0 200 OK\r\n"),
7275 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7276 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067277 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357278 };
7279
[email protected]31a2bfe2010-02-09 08:03:397280 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7281 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077282 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357283
[email protected]8ddf8322012-02-23 18:08:067284 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357286
[email protected]49639fa2011-12-20 23:22:417287 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357288
[email protected]49639fa2011-12-20 23:22:417289 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357290 EXPECT_EQ(ERR_IO_PENDING, rv);
7291
7292 rv = callback.WaitForResult();
7293 EXPECT_EQ(OK, rv);
7294
[email protected]029c83b62013-01-24 05:28:207295 LoadTimingInfo load_timing_info;
7296 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7297 TestLoadTimingNotReusedWithPac(load_timing_info,
7298 CONNECT_TIMING_HAS_SSL_TIMES);
7299
[email protected]e0c27be2009-07-15 13:09:357300 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507301 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357302
7303 std::string response_text;
7304 rv = ReadTransaction(trans.get(), &response_text);
7305 EXPECT_EQ(OK, rv);
7306 EXPECT_EQ("Payload", response_text);
7307}
7308
[email protected]23e482282013-06-14 16:08:027309TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207310 HttpRequestInfo request;
7311 request.method = "GET";
7312 request.url = GURL("http://www.google.com/");
7313 request.load_flags = 0;
7314
[email protected]bb88e1d32013-05-03 23:11:077315 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207316 ProxyService::CreateFixed("socks4://myproxy:1080"));
7317 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077318 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207319
[email protected]3fe8d2f82013-10-17 08:56:077320 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207321 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077322 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]029c83b62013-01-24 05:28:207323
7324 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7325 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7326
7327 MockWrite data_writes[] = {
7328 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7329 MockWrite("GET / HTTP/1.1\r\n"
7330 "Host: www.google.com\r\n"
7331 "Connection: keep-alive\r\n\r\n")
7332 };
7333
7334 MockRead data_reads[] = {
7335 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7336 MockRead("HTTP/1.0 200 OK\r\n"),
7337 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7338 MockRead("Payload"),
7339 MockRead(SYNCHRONOUS, OK)
7340 };
7341
7342 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7343 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077344 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207345
7346 TestCompletionCallback callback;
7347
7348 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7349 EXPECT_EQ(ERR_IO_PENDING, rv);
7350
7351 rv = callback.WaitForResult();
7352 EXPECT_EQ(OK, rv);
7353
7354 const HttpResponseInfo* response = trans->GetResponseInfo();
7355 ASSERT_TRUE(response != NULL);
7356
7357 LoadTimingInfo load_timing_info;
7358 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7359 TestLoadTimingNotReused(load_timing_info,
7360 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7361
7362 std::string response_text;
7363 rv = ReadTransaction(trans.get(), &response_text);
7364 EXPECT_EQ(OK, rv);
7365 EXPECT_EQ("Payload", response_text);
7366}
7367
[email protected]23e482282013-06-14 16:08:027368TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277369 HttpRequestInfo request;
7370 request.method = "GET";
7371 request.url = GURL("http://www.google.com/");
7372 request.load_flags = 0;
7373
[email protected]bb88e1d32013-05-03 23:11:077374 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207375 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7376 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077377 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357378
[email protected]3fe8d2f82013-10-17 08:56:077379 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357380 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077381 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357382
[email protected]e0c27be2009-07-15 13:09:357383 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7384 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377385 const char kSOCKS5OkRequest[] = {
7386 0x05, // Version
7387 0x01, // Command (CONNECT)
7388 0x00, // Reserved.
7389 0x03, // Address type (DOMAINNAME).
7390 0x0E, // Length of domain (14)
7391 // Domain string:
7392 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7393 0x00, 0x50, // 16-bit port (80)
7394 };
[email protected]e0c27be2009-07-15 13:09:357395 const char kSOCKS5OkResponse[] =
7396 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7397
7398 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067399 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7400 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357401 MockWrite("GET / HTTP/1.1\r\n"
7402 "Host: www.google.com\r\n"
7403 "Connection: keep-alive\r\n\r\n")
7404 };
7405
7406 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017407 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7408 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357409 MockRead("HTTP/1.0 200 OK\r\n"),
7410 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7411 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067412 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357413 };
7414
[email protected]31a2bfe2010-02-09 08:03:397415 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7416 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077417 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357418
[email protected]49639fa2011-12-20 23:22:417419 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357420
[email protected]49639fa2011-12-20 23:22:417421 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357422 EXPECT_EQ(ERR_IO_PENDING, rv);
7423
7424 rv = callback.WaitForResult();
7425 EXPECT_EQ(OK, rv);
7426
7427 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507428 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357429
[email protected]029c83b62013-01-24 05:28:207430 LoadTimingInfo load_timing_info;
7431 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7432 TestLoadTimingNotReusedWithPac(load_timing_info,
7433 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7434
[email protected]e0c27be2009-07-15 13:09:357435 std::string response_text;
7436 rv = ReadTransaction(trans.get(), &response_text);
7437 EXPECT_EQ(OK, rv);
7438 EXPECT_EQ("Payload", response_text);
7439}
7440
[email protected]23e482282013-06-14 16:08:027441TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277442 HttpRequestInfo request;
7443 request.method = "GET";
7444 request.url = GURL("https://www.google.com/");
7445 request.load_flags = 0;
7446
[email protected]bb88e1d32013-05-03 23:11:077447 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207448 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7449 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077450 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357451
[email protected]3fe8d2f82013-10-17 08:56:077452 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357453 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357455
[email protected]e0c27be2009-07-15 13:09:357456 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7457 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377458 const unsigned char kSOCKS5OkRequest[] = {
7459 0x05, // Version
7460 0x01, // Command (CONNECT)
7461 0x00, // Reserved.
7462 0x03, // Address type (DOMAINNAME).
7463 0x0E, // Length of domain (14)
7464 // Domain string:
7465 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7466 0x01, 0xBB, // 16-bit port (443)
7467 };
7468
[email protected]e0c27be2009-07-15 13:09:357469 const char kSOCKS5OkResponse[] =
7470 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7471
7472 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067473 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7474 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357475 arraysize(kSOCKS5OkRequest)),
7476 MockWrite("GET / HTTP/1.1\r\n"
7477 "Host: www.google.com\r\n"
7478 "Connection: keep-alive\r\n\r\n")
7479 };
7480
7481 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017482 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7483 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027484 MockRead("HTTP/1.0 200 OK\r\n"),
7485 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7486 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067487 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027488 };
7489
[email protected]31a2bfe2010-02-09 08:03:397490 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7491 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077492 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027493
[email protected]8ddf8322012-02-23 18:08:067494 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077495 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027496
[email protected]49639fa2011-12-20 23:22:417497 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027498
[email protected]49639fa2011-12-20 23:22:417499 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027500 EXPECT_EQ(ERR_IO_PENDING, rv);
7501
7502 rv = callback.WaitForResult();
7503 EXPECT_EQ(OK, rv);
7504
7505 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507506 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027507
[email protected]029c83b62013-01-24 05:28:207508 LoadTimingInfo load_timing_info;
7509 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7510 TestLoadTimingNotReusedWithPac(load_timing_info,
7511 CONNECT_TIMING_HAS_SSL_TIMES);
7512
[email protected]3cd17242009-06-23 02:59:027513 std::string response_text;
7514 rv = ReadTransaction(trans.get(), &response_text);
7515 EXPECT_EQ(OK, rv);
7516 EXPECT_EQ("Payload", response_text);
7517}
7518
[email protected]448d4ca52012-03-04 04:12:237519namespace {
7520
[email protected]04e5be32009-06-26 20:00:317521// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067522
7523struct GroupNameTest {
7524 std::string proxy_server;
7525 std::string url;
7526 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187527 bool ssl;
[email protected]2d731a32010-04-29 01:04:067528};
7529
7530scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437531 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077532 SpdySessionDependencies* session_deps_) {
7533 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067534
[email protected]30d4c022013-07-18 22:58:167535 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537536 session->http_server_properties();
7537 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067538 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437539 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067540
7541 return session;
7542}
7543
7544int GroupNameTransactionHelper(
7545 const std::string& url,
7546 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067547 HttpRequestInfo request;
7548 request.method = "GET";
7549 request.url = GURL(url);
7550 request.load_flags = 0;
7551
[email protected]262eec82013-03-19 21:01:367552 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507553 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277554
[email protected]49639fa2011-12-20 23:22:417555 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067556
7557 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417558 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067559}
7560
[email protected]448d4ca52012-03-04 04:12:237561} // namespace
7562
[email protected]23e482282013-06-14 16:08:027563TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067564 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317565 {
[email protected]2d731a32010-04-29 01:04:067566 "", // unused
[email protected]04e5be32009-06-26 20:00:317567 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547568 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187569 false,
[email protected]2ff8b312010-04-26 22:20:547570 },
7571 {
[email protected]2d731a32010-04-29 01:04:067572 "", // unused
[email protected]2ff8b312010-04-26 22:20:547573 "http://[2001:1418:13:1::25]/direct",
7574 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187575 false,
[email protected]04e5be32009-06-26 20:00:317576 },
[email protected]04e5be32009-06-26 20:00:317577
7578 // SSL Tests
7579 {
[email protected]2d731a32010-04-29 01:04:067580 "", // unused
[email protected]04e5be32009-06-26 20:00:317581 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027582 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187583 true,
[email protected]04e5be32009-06-26 20:00:317584 },
7585 {
[email protected]2d731a32010-04-29 01:04:067586 "", // unused
7587 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027588 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187589 true,
[email protected]04e5be32009-06-26 20:00:317590 },
7591 {
[email protected]2d731a32010-04-29 01:04:067592 "", // unused
[email protected]2ff8b312010-04-26 22:20:547593 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027594 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187595 true,
[email protected]2ff8b312010-04-26 22:20:547596 },
[email protected]2d731a32010-04-29 01:04:067597 };
[email protected]2ff8b312010-04-26 22:20:547598
[email protected]d7599122014-05-24 03:37:237599 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067600
7601 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077602 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027603 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067604 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437605 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067606
7607 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287608 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7609 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137610 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347611 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447612 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7613 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027614 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7615 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447616 peer.SetClientSocketPoolManager(
7617 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067618
7619 EXPECT_EQ(ERR_IO_PENDING,
7620 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187621 if (tests[i].ssl)
7622 EXPECT_EQ(tests[i].expected_group_name,
7623 ssl_conn_pool->last_group_name_received());
7624 else
7625 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287626 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067627 }
7628
[email protected]2d731a32010-04-29 01:04:067629}
7630
[email protected]23e482282013-06-14 16:08:027631TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067632 const GroupNameTest tests[] = {
7633 {
7634 "http_proxy",
7635 "http://www.google.com/http_proxy_normal",
7636 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187637 false,
[email protected]2d731a32010-04-29 01:04:067638 },
7639
7640 // SSL Tests
7641 {
7642 "http_proxy",
7643 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027644 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187645 true,
[email protected]2d731a32010-04-29 01:04:067646 },
[email protected]af3490e2010-10-16 21:02:297647
[email protected]9faeded92010-04-29 20:03:057648 {
7649 "http_proxy",
7650 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027651 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187652 true,
[email protected]9faeded92010-04-29 20:03:057653 },
[email protected]45499252013-01-23 17:12:567654
7655 {
7656 "http_proxy",
7657 "ftp://ftp.google.com/http_proxy_normal",
7658 "ftp/ftp.google.com:21",
7659 false,
7660 },
[email protected]2d731a32010-04-29 01:04:067661 };
7662
[email protected]d7599122014-05-24 03:37:237663 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067664
7665 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077666 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027667 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067668 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437669 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067670
7671 HttpNetworkSessionPeer peer(session);
7672
[email protected]e60e47a2010-07-14 03:37:187673 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137674 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347675 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137676 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347677 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027678
[email protected]831e4a32013-11-14 02:14:447679 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7680 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027681 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7682 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447683 peer.SetClientSocketPoolManager(
7684 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067685
7686 EXPECT_EQ(ERR_IO_PENDING,
7687 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187688 if (tests[i].ssl)
7689 EXPECT_EQ(tests[i].expected_group_name,
7690 ssl_conn_pool->last_group_name_received());
7691 else
7692 EXPECT_EQ(tests[i].expected_group_name,
7693 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067694 }
[email protected]2d731a32010-04-29 01:04:067695}
7696
[email protected]23e482282013-06-14 16:08:027697TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067698 const GroupNameTest tests[] = {
7699 {
7700 "socks4://socks_proxy:1080",
7701 "http://www.google.com/socks4_direct",
7702 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187703 false,
[email protected]2d731a32010-04-29 01:04:067704 },
7705 {
7706 "socks5://socks_proxy:1080",
7707 "http://www.google.com/socks5_direct",
7708 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187709 false,
[email protected]2d731a32010-04-29 01:04:067710 },
7711
7712 // SSL Tests
7713 {
7714 "socks4://socks_proxy:1080",
7715 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027716 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187717 true,
[email protected]2d731a32010-04-29 01:04:067718 },
7719 {
7720 "socks5://socks_proxy:1080",
7721 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027722 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187723 true,
[email protected]2d731a32010-04-29 01:04:067724 },
[email protected]af3490e2010-10-16 21:02:297725
[email protected]9faeded92010-04-29 20:03:057726 {
7727 "socks4://socks_proxy:1080",
7728 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027729 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187730 true,
[email protected]9faeded92010-04-29 20:03:057731 },
[email protected]04e5be32009-06-26 20:00:317732 };
7733
[email protected]d7599122014-05-24 03:37:237734 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:547735
[email protected]04e5be32009-06-26 20:00:317736 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077737 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027738 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067739 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437740 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027741
[email protected]2d731a32010-04-29 01:04:067742 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317743
[email protected]e60e47a2010-07-14 03:37:187744 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137745 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347746 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137747 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347748 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027749
[email protected]831e4a32013-11-14 02:14:447750 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7751 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027752 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7753 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447754 peer.SetClientSocketPoolManager(
7755 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]04e5be32009-06-26 20:00:317756
[email protected]262eec82013-03-19 21:01:367757 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507758 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317759
[email protected]2d731a32010-04-29 01:04:067760 EXPECT_EQ(ERR_IO_PENDING,
7761 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187762 if (tests[i].ssl)
7763 EXPECT_EQ(tests[i].expected_group_name,
7764 ssl_conn_pool->last_group_name_received());
7765 else
7766 EXPECT_EQ(tests[i].expected_group_name,
7767 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317768 }
7769}
7770
[email protected]23e482282013-06-14 16:08:027771TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277772 HttpRequestInfo request;
7773 request.method = "GET";
7774 request.url = GURL("http://www.google.com/");
7775
[email protected]bb88e1d32013-05-03 23:11:077776 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007777 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327778
[email protected]69719062010-01-05 20:09:217779 // This simulates failure resolving all hostnames; that means we will fail
7780 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077781 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327782
[email protected]3fe8d2f82013-10-17 08:56:077783 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257784 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077785 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]9172a982009-06-06 00:30:257786
[email protected]49639fa2011-12-20 23:22:417787 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257788
[email protected]49639fa2011-12-20 23:22:417789 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257790 EXPECT_EQ(ERR_IO_PENDING, rv);
7791
[email protected]9172a982009-06-06 00:30:257792 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017793 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257794}
7795
[email protected]685af592010-05-11 19:31:247796// Base test to make sure that when the load flags for a request specify to
7797// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027798void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077799 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277800 // Issue a request, asking to bypass the cache(s).
7801 HttpRequestInfo request;
7802 request.method = "GET";
7803 request.load_flags = load_flags;
7804 request.url = GURL("http://www.google.com/");
7805
[email protected]a2c2fb92009-07-18 07:31:047806 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077807 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327808
[email protected]3fe8d2f82013-10-17 08:56:077809 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7810 scoped_ptr<HttpTransaction> trans(
7811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3b9cca42009-06-16 01:08:287812
[email protected]6e78dfb2011-07-28 21:34:477813 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287814 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297815 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077816 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107817 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7818 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417819 &addrlist,
7820 callback.callback(),
7821 NULL,
7822 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477823 EXPECT_EQ(ERR_IO_PENDING, rv);
7824 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287825 EXPECT_EQ(OK, rv);
7826
7827 // Verify that it was added to host cache, by doing a subsequent async lookup
7828 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077829 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107830 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7831 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417832 &addrlist,
7833 callback.callback(),
7834 NULL,
7835 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327836 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287837
7838 // Inject a failure the next time that "www.google.com" is resolved. This way
7839 // we can tell if the next lookup hit the cache, or the "network".
7840 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077841 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287842
7843 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7844 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067845 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397846 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077847 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287848
[email protected]3b9cca42009-06-16 01:08:287849 // Run the request.
[email protected]49639fa2011-12-20 23:22:417850 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287851 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417852 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287853
7854 // If we bypassed the cache, we would have gotten a failure while resolving
7855 // "www.google.com".
7856 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7857}
7858
[email protected]685af592010-05-11 19:31:247859// There are multiple load flags that should trigger the host cache bypass.
7860// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027861TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247862 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7863}
7864
[email protected]23e482282013-06-14 16:08:027865TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247866 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7867}
7868
[email protected]23e482282013-06-14 16:08:027869TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247870 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7871}
7872
[email protected]0877e3d2009-10-17 22:29:577873// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027874TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577875 HttpRequestInfo request;
7876 request.method = "GET";
7877 request.url = GURL("http://www.foo.com/");
7878 request.load_flags = 0;
7879
7880 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067881 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577882 };
[email protected]31a2bfe2010-02-09 08:03:397883 StaticSocketDataProvider data(NULL, 0,
7884 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077885 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077886 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577887
[email protected]49639fa2011-12-20 23:22:417888 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577889
7890 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077891 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577892
[email protected]49639fa2011-12-20 23:22:417893 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577894 EXPECT_EQ(ERR_IO_PENDING, rv);
7895
7896 rv = callback.WaitForResult();
7897 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7898}
7899
7900// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027901TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577902 HttpRequestInfo request;
7903 request.method = "GET";
7904 request.url = GURL("http://www.foo.com/");
7905 request.load_flags = 0;
7906
7907 MockRead data_reads[] = {
7908 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067909 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577910 };
7911
[email protected]31a2bfe2010-02-09 08:03:397912 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077913 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077914 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577915
[email protected]49639fa2011-12-20 23:22:417916 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577917
7918 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077919 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577920
[email protected]49639fa2011-12-20 23:22:417921 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577922 EXPECT_EQ(ERR_IO_PENDING, rv);
7923
7924 rv = callback.WaitForResult();
7925 EXPECT_EQ(OK, rv);
7926
7927 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507928 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577929
[email protected]90499482013-06-01 00:39:507930 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577931 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7932
7933 std::string response_data;
7934 rv = ReadTransaction(trans.get(), &response_data);
7935 EXPECT_EQ(OK, rv);
7936 EXPECT_EQ("", response_data);
7937}
7938
7939// Make sure that a dropped connection while draining the body for auth
7940// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027941TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577942 HttpRequestInfo request;
7943 request.method = "GET";
7944 request.url = GURL("http://www.google.com/");
7945 request.load_flags = 0;
7946
7947 MockWrite data_writes1[] = {
7948 MockWrite("GET / HTTP/1.1\r\n"
7949 "Host: www.google.com\r\n"
7950 "Connection: keep-alive\r\n\r\n"),
7951 };
7952
7953 MockRead data_reads1[] = {
7954 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7955 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7956 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7957 MockRead("Content-Length: 14\r\n\r\n"),
7958 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067959 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577960 };
7961
[email protected]31a2bfe2010-02-09 08:03:397962 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7963 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077964 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577965
7966 // After calling trans->RestartWithAuth(), this is the request we should
7967 // be issuing -- the final header line contains the credentials.
7968 MockWrite data_writes2[] = {
7969 MockWrite("GET / HTTP/1.1\r\n"
7970 "Host: www.google.com\r\n"
7971 "Connection: keep-alive\r\n"
7972 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7973 };
7974
7975 // Lastly, the server responds with the actual content.
7976 MockRead data_reads2[] = {
7977 MockRead("HTTP/1.1 200 OK\r\n"),
7978 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7979 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067980 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577981 };
7982
[email protected]31a2bfe2010-02-09 08:03:397983 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7984 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077985 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077986 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577987
[email protected]49639fa2011-12-20 23:22:417988 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577989
[email protected]262eec82013-03-19 21:01:367990 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507991 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507992
[email protected]49639fa2011-12-20 23:22:417993 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577994 EXPECT_EQ(ERR_IO_PENDING, rv);
7995
7996 rv = callback1.WaitForResult();
7997 EXPECT_EQ(OK, rv);
7998
7999 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508000 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048001 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578002
[email protected]49639fa2011-12-20 23:22:418003 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578004
[email protected]49639fa2011-12-20 23:22:418005 rv = trans->RestartWithAuth(
8006 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578007 EXPECT_EQ(ERR_IO_PENDING, rv);
8008
8009 rv = callback2.WaitForResult();
8010 EXPECT_EQ(OK, rv);
8011
8012 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508013 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578014 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8015 EXPECT_EQ(100, response->headers->GetContentLength());
8016}
8017
8018// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028019TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078020 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578021
8022 HttpRequestInfo request;
8023 request.method = "GET";
8024 request.url = GURL("https://www.google.com/");
8025 request.load_flags = 0;
8026
8027 MockRead proxy_reads[] = {
8028 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068029 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578030 };
8031
[email protected]31a2bfe2010-02-09 08:03:398032 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068033 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578034
[email protected]bb88e1d32013-05-03 23:11:078035 session_deps_.socket_factory->AddSocketDataProvider(&data);
8036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578037
[email protected]49639fa2011-12-20 23:22:418038 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578039
[email protected]bb88e1d32013-05-03 23:11:078040 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578041
[email protected]3fe8d2f82013-10-17 08:56:078042 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578043 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:578045
[email protected]49639fa2011-12-20 23:22:418046 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578047 EXPECT_EQ(ERR_IO_PENDING, rv);
8048
8049 rv = callback.WaitForResult();
8050 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8051}
8052
[email protected]23e482282013-06-14 16:08:028053TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468054 HttpRequestInfo request;
8055 request.method = "GET";
8056 request.url = GURL("http://www.google.com/");
8057 request.load_flags = 0;
8058
[email protected]3fe8d2f82013-10-17 08:56:078059 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278060 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078061 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:278062
[email protected]e22e1362009-11-23 21:31:128063 MockRead data_reads[] = {
8064 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068065 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128066 };
[email protected]9492e4a2010-02-24 00:58:468067
8068 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078069 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468070
[email protected]49639fa2011-12-20 23:22:418071 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468072
[email protected]49639fa2011-12-20 23:22:418073 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468074 EXPECT_EQ(ERR_IO_PENDING, rv);
8075
8076 EXPECT_EQ(OK, callback.WaitForResult());
8077
8078 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508079 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468080
[email protected]90499482013-06-01 00:39:508081 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468082 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8083
8084 std::string response_data;
8085 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238086 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128087}
8088
[email protected]23e482282013-06-14 16:08:028089TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158090 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528091 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338092 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218093 UploadFileElementReader::ScopedOverridingContentLengthForTests
8094 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338095
[email protected]b2d26cfd2012-12-11 10:36:068096 ScopedVector<UploadElementReader> element_readers;
8097 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368098 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8099 temp_file_path,
8100 0,
8101 kuint64max,
8102 base::Time()));
[email protected]96c77a72013-09-24 09:49:208103 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278104
8105 HttpRequestInfo request;
8106 request.method = "POST";
8107 request.url = GURL("http://www.google.com/upload");
8108 request.upload_data_stream = &upload_data_stream;
8109 request.load_flags = 0;
8110
[email protected]3fe8d2f82013-10-17 08:56:078111 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278112 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]95d88ffe2010-02-04 21:25:338114
8115 MockRead data_reads[] = {
8116 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8117 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068118 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338119 };
[email protected]31a2bfe2010-02-09 08:03:398120 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078121 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338122
[email protected]49639fa2011-12-20 23:22:418123 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338124
[email protected]49639fa2011-12-20 23:22:418125 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338126 EXPECT_EQ(ERR_IO_PENDING, rv);
8127
8128 rv = callback.WaitForResult();
8129 EXPECT_EQ(OK, rv);
8130
8131 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508132 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338133
[email protected]90499482013-06-01 00:39:508134 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338135 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8136
8137 std::string response_data;
8138 rv = ReadTransaction(trans.get(), &response_data);
8139 EXPECT_EQ(OK, rv);
8140 EXPECT_EQ("hello world", response_data);
8141
[email protected]dd3aa792013-07-16 19:10:238142 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338143}
8144
[email protected]23e482282013-06-14 16:08:028145TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158146 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528147 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368148 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308149 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368150 temp_file_content.length()));
8151 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
8152
[email protected]b2d26cfd2012-12-11 10:36:068153 ScopedVector<UploadElementReader> element_readers;
8154 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368155 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8156 temp_file,
8157 0,
8158 kuint64max,
8159 base::Time()));
[email protected]96c77a72013-09-24 09:49:208160 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278161
8162 HttpRequestInfo request;
8163 request.method = "POST";
8164 request.url = GURL("http://www.google.com/upload");
8165 request.upload_data_stream = &upload_data_stream;
8166 request.load_flags = 0;
8167
[email protected]999dd8c2013-11-12 06:45:548168 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078169 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278170 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]6624b4622010-03-29 19:58:368172
[email protected]999dd8c2013-11-12 06:45:548173 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078174 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368175
[email protected]49639fa2011-12-20 23:22:418176 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368177
[email protected]49639fa2011-12-20 23:22:418178 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368179 EXPECT_EQ(ERR_IO_PENDING, rv);
8180
8181 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548182 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368183
8184 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548185 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368186
[email protected]dd3aa792013-07-16 19:10:238187 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368188}
8189
[email protected]02cad5d2013-10-02 08:14:038190TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8191 class FakeUploadElementReader : public UploadElementReader {
8192 public:
8193 FakeUploadElementReader() {}
8194 virtual ~FakeUploadElementReader() {}
8195
8196 const CompletionCallback& callback() const { return callback_; }
8197
8198 // UploadElementReader overrides:
8199 virtual int Init(const CompletionCallback& callback) OVERRIDE {
8200 callback_ = callback;
8201 return ERR_IO_PENDING;
8202 }
8203 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
8204 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
8205 virtual int Read(IOBuffer* buf,
8206 int buf_length,
8207 const CompletionCallback& callback) OVERRIDE {
8208 return ERR_FAILED;
8209 }
8210
8211 private:
8212 CompletionCallback callback_;
8213 };
8214
8215 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8216 ScopedVector<UploadElementReader> element_readers;
8217 element_readers.push_back(fake_reader);
8218 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8219
8220 HttpRequestInfo request;
8221 request.method = "POST";
8222 request.url = GURL("http://www.google.com/upload");
8223 request.upload_data_stream = &upload_data_stream;
8224 request.load_flags = 0;
8225
[email protected]3fe8d2f82013-10-17 08:56:078226 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038227 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078228 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]02cad5d2013-10-02 08:14:038229
8230 StaticSocketDataProvider data;
8231 session_deps_.socket_factory->AddSocketDataProvider(&data);
8232
8233 TestCompletionCallback callback;
8234 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8235 EXPECT_EQ(ERR_IO_PENDING, rv);
8236 base::MessageLoop::current()->RunUntilIdle();
8237
8238 // Transaction is pending on request body initialization.
8239 ASSERT_FALSE(fake_reader->callback().is_null());
8240
8241 // Return Init()'s result after the transaction gets destroyed.
8242 trans.reset();
8243 fake_reader->callback().Run(OK); // Should not crash.
8244}
8245
[email protected]aeefc9e82010-02-19 16:18:278246// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028247TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278248
8249 HttpRequestInfo request;
8250 request.method = "GET";
8251 request.url = GURL("http://www.google.com/");
8252 request.load_flags = 0;
8253
8254 // First transaction will request a resource and receive a Basic challenge
8255 // with realm="first_realm".
8256 MockWrite data_writes1[] = {
8257 MockWrite("GET / HTTP/1.1\r\n"
8258 "Host: www.google.com\r\n"
8259 "Connection: keep-alive\r\n"
8260 "\r\n"),
8261 };
8262 MockRead data_reads1[] = {
8263 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8264 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8265 "\r\n"),
8266 };
8267
8268 // After calling trans->RestartWithAuth(), provide an Authentication header
8269 // for first_realm. The server will reject and provide a challenge with
8270 // second_realm.
8271 MockWrite data_writes2[] = {
8272 MockWrite("GET / HTTP/1.1\r\n"
8273 "Host: www.google.com\r\n"
8274 "Connection: keep-alive\r\n"
8275 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8276 "\r\n"),
8277 };
8278 MockRead data_reads2[] = {
8279 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8280 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8281 "\r\n"),
8282 };
8283
8284 // This again fails, and goes back to first_realm. Make sure that the
8285 // entry is removed from cache.
8286 MockWrite data_writes3[] = {
8287 MockWrite("GET / HTTP/1.1\r\n"
8288 "Host: www.google.com\r\n"
8289 "Connection: keep-alive\r\n"
8290 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8291 "\r\n"),
8292 };
8293 MockRead data_reads3[] = {
8294 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8295 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8296 "\r\n"),
8297 };
8298
8299 // Try one last time (with the correct password) and get the resource.
8300 MockWrite data_writes4[] = {
8301 MockWrite("GET / HTTP/1.1\r\n"
8302 "Host: www.google.com\r\n"
8303 "Connection: keep-alive\r\n"
8304 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8305 "\r\n"),
8306 };
8307 MockRead data_reads4[] = {
8308 MockRead("HTTP/1.1 200 OK\r\n"
8309 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508310 "Content-Length: 5\r\n"
8311 "\r\n"
8312 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278313 };
8314
8315 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8316 data_writes1, arraysize(data_writes1));
8317 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8318 data_writes2, arraysize(data_writes2));
8319 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8320 data_writes3, arraysize(data_writes3));
8321 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8322 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078323 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8324 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8325 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8326 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278327
[email protected]49639fa2011-12-20 23:22:418328 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278329
[email protected]3fe8d2f82013-10-17 08:56:078330 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508331 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078332 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0b0bf032010-09-21 18:08:508333
[email protected]aeefc9e82010-02-19 16:18:278334 // Issue the first request with Authorize headers. There should be a
8335 // password prompt for first_realm waiting to be filled in after the
8336 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418337 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278338 EXPECT_EQ(ERR_IO_PENDING, rv);
8339 rv = callback1.WaitForResult();
8340 EXPECT_EQ(OK, rv);
8341 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508342 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048343 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8344 ASSERT_FALSE(challenge == NULL);
8345 EXPECT_FALSE(challenge->is_proxy);
8346 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8347 EXPECT_EQ("first_realm", challenge->realm);
8348 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278349
8350 // Issue the second request with an incorrect password. There should be a
8351 // password prompt for second_realm waiting to be filled in after the
8352 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418353 TestCompletionCallback callback2;
8354 rv = trans->RestartWithAuth(
8355 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278356 EXPECT_EQ(ERR_IO_PENDING, rv);
8357 rv = callback2.WaitForResult();
8358 EXPECT_EQ(OK, rv);
8359 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508360 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048361 challenge = response->auth_challenge.get();
8362 ASSERT_FALSE(challenge == NULL);
8363 EXPECT_FALSE(challenge->is_proxy);
8364 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8365 EXPECT_EQ("second_realm", challenge->realm);
8366 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278367
8368 // Issue the third request with another incorrect password. There should be
8369 // a password prompt for first_realm waiting to be filled in. If the password
8370 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8371 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418372 TestCompletionCallback callback3;
8373 rv = trans->RestartWithAuth(
8374 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278375 EXPECT_EQ(ERR_IO_PENDING, rv);
8376 rv = callback3.WaitForResult();
8377 EXPECT_EQ(OK, rv);
8378 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508379 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048380 challenge = response->auth_challenge.get();
8381 ASSERT_FALSE(challenge == NULL);
8382 EXPECT_FALSE(challenge->is_proxy);
8383 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8384 EXPECT_EQ("first_realm", challenge->realm);
8385 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278386
8387 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418388 TestCompletionCallback callback4;
8389 rv = trans->RestartWithAuth(
8390 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278391 EXPECT_EQ(ERR_IO_PENDING, rv);
8392 rv = callback4.WaitForResult();
8393 EXPECT_EQ(OK, rv);
8394 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508395 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278396 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8397}
8398
[email protected]23e482282013-06-14 16:08:028399TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238400 session_deps_.next_protos = SpdyNextProtos();
8401 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428402
[email protected]8a0fc822013-06-27 20:52:438403 std::string alternate_protocol_http_header =
8404 GetAlternateProtocolHttpHeader();
8405
[email protected]564b4912010-03-09 16:30:428406 MockRead data_reads[] = {
8407 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438408 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428409 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068410 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428411 };
8412
8413 HttpRequestInfo request;
8414 request.method = "GET";
8415 request.url = GURL("http://www.google.com/");
8416 request.load_flags = 0;
8417
8418 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8419
[email protected]bb88e1d32013-05-03 23:11:078420 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428421
[email protected]49639fa2011-12-20 23:22:418422 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428423
[email protected]bb88e1d32013-05-03 23:11:078424 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368425 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508426 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428427
[email protected]49639fa2011-12-20 23:22:418428 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428429 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538430
[email protected]2fbaecf22010-07-22 22:20:358431 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558432 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538433 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428434 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538435 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428436
8437 EXPECT_EQ(OK, callback.WaitForResult());
8438
8439 const HttpResponseInfo* response = trans->GetResponseInfo();
8440 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508441 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428442 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538443 EXPECT_FALSE(response->was_fetched_via_spdy);
8444 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428445
8446 std::string response_data;
8447 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8448 EXPECT_EQ("hello world", response_data);
8449
[email protected]17291a022011-10-10 07:32:538450 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8451 const PortAlternateProtocolPair alternate =
8452 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8453 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:428454 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:438455 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:428456 EXPECT_TRUE(expected_alternate.Equals(alternate));
8457}
8458
[email protected]23e482282013-06-14 16:08:028459TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238460 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238461 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428462
8463 HttpRequestInfo request;
8464 request.method = "GET";
8465 request.url = GURL("http://www.google.com/");
8466 request.load_flags = 0;
8467
[email protected]d973e99a2012-02-17 21:02:368468 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428469 StaticSocketDataProvider first_data;
8470 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078471 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428472
8473 MockRead data_reads[] = {
8474 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8475 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068476 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428477 };
8478 StaticSocketDataProvider second_data(
8479 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078480 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428481
[email protected]bb88e1d32013-05-03 23:11:078482 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428483
[email protected]30d4c022013-07-18 22:58:168484 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538485 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118486 // Port must be < 1024, or the header will be ignored (since initial port was
8487 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538488 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118489 HostPortPair::FromURL(request.url),
8490 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438491 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428492
[email protected]262eec82013-03-19 21:01:368493 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418495 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428496
[email protected]49639fa2011-12-20 23:22:418497 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428498 EXPECT_EQ(ERR_IO_PENDING, rv);
8499 EXPECT_EQ(OK, callback.WaitForResult());
8500
8501 const HttpResponseInfo* response = trans->GetResponseInfo();
8502 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508503 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428504 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8505
8506 std::string response_data;
8507 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8508 EXPECT_EQ("hello world", response_data);
8509
[email protected]17291a022011-10-10 07:32:538510 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118511 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538512 const PortAlternateProtocolPair alternate =
8513 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118514 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538515 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428516}
8517
[email protected]23e482282013-06-14 16:08:028518TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238519 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118520 // Ensure that we're not allowed to redirect traffic via an alternate
8521 // protocol to an unrestricted (port >= 1024) when the original traffic was
8522 // on a restricted port (port < 1024). Ensure that we can redirect in all
8523 // other cases.
[email protected]d7599122014-05-24 03:37:238524 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118525
8526 HttpRequestInfo restricted_port_request;
8527 restricted_port_request.method = "GET";
8528 restricted_port_request.url = GURL("http://www.google.com:1023/");
8529 restricted_port_request.load_flags = 0;
8530
[email protected]d973e99a2012-02-17 21:02:368531 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118532 StaticSocketDataProvider first_data;
8533 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078534 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118535
8536 MockRead data_reads[] = {
8537 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8538 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068539 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118540 };
8541 StaticSocketDataProvider second_data(
8542 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078543 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118544
[email protected]bb88e1d32013-05-03 23:11:078545 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118546
[email protected]30d4c022013-07-18 22:58:168547 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538548 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118549 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538550 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118551 HostPortPair::FromURL(restricted_port_request.url),
8552 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438553 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118554
[email protected]262eec82013-03-19 21:01:368555 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508556 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418557 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118558
[email protected]49639fa2011-12-20 23:22:418559 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368560 &restricted_port_request,
8561 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118562 EXPECT_EQ(ERR_IO_PENDING, rv);
8563 // Invalid change to unrestricted port should fail.
8564 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198565}
[email protected]3912662a32011-10-04 00:51:118566
[email protected]23e482282013-06-14 16:08:028567TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198568 AlternateProtocolPortRestrictedPermitted) {
8569 // Ensure that we're allowed to redirect traffic via an alternate
8570 // protocol to an unrestricted (port >= 1024) when the original traffic was
8571 // on a restricted port (port < 1024) if we set
8572 // enable_user_alternate_protocol_ports.
8573
[email protected]d7599122014-05-24 03:37:238574 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078575 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198576
8577 HttpRequestInfo restricted_port_request;
8578 restricted_port_request.method = "GET";
8579 restricted_port_request.url = GURL("http://www.google.com:1023/");
8580 restricted_port_request.load_flags = 0;
8581
8582 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8583 StaticSocketDataProvider first_data;
8584 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078585 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198586
8587 MockRead data_reads[] = {
8588 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8589 MockRead("hello world"),
8590 MockRead(ASYNC, OK),
8591 };
8592 StaticSocketDataProvider second_data(
8593 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078594 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198595
[email protected]bb88e1d32013-05-03 23:11:078596 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198597
[email protected]30d4c022013-07-18 22:58:168598 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198599 session->http_server_properties();
8600 const int kUnrestrictedAlternatePort = 1024;
8601 http_server_properties->SetAlternateProtocol(
8602 HostPortPair::FromURL(restricted_port_request.url),
8603 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438604 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198605
[email protected]262eec82013-03-19 21:01:368606 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508607 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198608 TestCompletionCallback callback;
8609
8610 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368611 &restricted_port_request,
8612 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198613 // Change to unrestricted port should succeed.
8614 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118615}
8616
[email protected]23e482282013-06-14 16:08:028617TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238618 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118619 // Ensure that we're not allowed to redirect traffic via an alternate
8620 // protocol to an unrestricted (port >= 1024) when the original traffic was
8621 // on a restricted port (port < 1024). Ensure that we can redirect in all
8622 // other cases.
[email protected]d7599122014-05-24 03:37:238623 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118624
8625 HttpRequestInfo restricted_port_request;
8626 restricted_port_request.method = "GET";
8627 restricted_port_request.url = GURL("http://www.google.com:1023/");
8628 restricted_port_request.load_flags = 0;
8629
[email protected]d973e99a2012-02-17 21:02:368630 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118631 StaticSocketDataProvider first_data;
8632 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078633 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118634
8635 MockRead data_reads[] = {
8636 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8637 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068638 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118639 };
8640 StaticSocketDataProvider second_data(
8641 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078642 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118643
[email protected]bb88e1d32013-05-03 23:11:078644 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118645
[email protected]30d4c022013-07-18 22:58:168646 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538647 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118648 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538649 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118650 HostPortPair::FromURL(restricted_port_request.url),
8651 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438652 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118653
[email protected]262eec82013-03-19 21:01:368654 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508655 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418656 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118657
[email protected]49639fa2011-12-20 23:22:418658 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368659 &restricted_port_request,
8660 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118661 EXPECT_EQ(ERR_IO_PENDING, rv);
8662 // Valid change to restricted port should pass.
8663 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118664}
8665
[email protected]23e482282013-06-14 16:08:028666TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238667 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118668 // Ensure that we're not allowed to redirect traffic via an alternate
8669 // protocol to an unrestricted (port >= 1024) when the original traffic was
8670 // on a restricted port (port < 1024). Ensure that we can redirect in all
8671 // other cases.
[email protected]d7599122014-05-24 03:37:238672 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118673
8674 HttpRequestInfo unrestricted_port_request;
8675 unrestricted_port_request.method = "GET";
8676 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8677 unrestricted_port_request.load_flags = 0;
8678
[email protected]d973e99a2012-02-17 21:02:368679 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118680 StaticSocketDataProvider first_data;
8681 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078682 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118683
8684 MockRead data_reads[] = {
8685 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8686 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068687 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118688 };
8689 StaticSocketDataProvider second_data(
8690 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078691 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118692
[email protected]bb88e1d32013-05-03 23:11:078693 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118694
[email protected]30d4c022013-07-18 22:58:168695 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538696 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118697 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538698 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118699 HostPortPair::FromURL(unrestricted_port_request.url),
8700 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438701 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118702
[email protected]262eec82013-03-19 21:01:368703 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508704 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418705 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118706
[email protected]49639fa2011-12-20 23:22:418707 int rv = trans->Start(
8708 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118709 EXPECT_EQ(ERR_IO_PENDING, rv);
8710 // Valid change to restricted port should pass.
8711 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118712}
8713
[email protected]23e482282013-06-14 16:08:028714TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238715 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118716 // Ensure that we're not allowed to redirect traffic via an alternate
8717 // protocol to an unrestricted (port >= 1024) when the original traffic was
8718 // on a restricted port (port < 1024). Ensure that we can redirect in all
8719 // other cases.
[email protected]d7599122014-05-24 03:37:238720 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118721
8722 HttpRequestInfo unrestricted_port_request;
8723 unrestricted_port_request.method = "GET";
8724 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8725 unrestricted_port_request.load_flags = 0;
8726
[email protected]d973e99a2012-02-17 21:02:368727 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118728 StaticSocketDataProvider first_data;
8729 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078730 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118731
8732 MockRead data_reads[] = {
8733 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8734 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068735 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118736 };
8737 StaticSocketDataProvider second_data(
8738 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078739 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118740
[email protected]bb88e1d32013-05-03 23:11:078741 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118742
[email protected]30d4c022013-07-18 22:58:168743 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538744 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118745 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538746 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118747 HostPortPair::FromURL(unrestricted_port_request.url),
8748 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438749 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118750
[email protected]262eec82013-03-19 21:01:368751 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508752 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418753 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118754
[email protected]49639fa2011-12-20 23:22:418755 int rv = trans->Start(
8756 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118757 EXPECT_EQ(ERR_IO_PENDING, rv);
8758 // Valid change to an unrestricted port should pass.
8759 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118760}
8761
[email protected]d7599122014-05-24 03:37:238762TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028763 // Ensure that we're not allowed to redirect traffic via an alternate
8764 // protocol to an unsafe port, and that we resume the second
8765 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:238766 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:028767
8768 HttpRequestInfo request;
8769 request.method = "GET";
8770 request.url = GURL("http://www.google.com/");
8771 request.load_flags = 0;
8772
8773 // The alternate protocol request will error out before we attempt to connect,
8774 // so only the standard HTTP request will try to connect.
8775 MockRead data_reads[] = {
8776 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8777 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068778 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028779 };
8780 StaticSocketDataProvider data(
8781 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078782 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028783
[email protected]bb88e1d32013-05-03 23:11:078784 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028785
[email protected]30d4c022013-07-18 22:58:168786 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028787 session->http_server_properties();
8788 const int kUnsafePort = 7;
8789 http_server_properties->SetAlternateProtocol(
8790 HostPortPair::FromURL(request.url),
8791 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438792 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028793
[email protected]262eec82013-03-19 21:01:368794 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508795 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028796 TestCompletionCallback callback;
8797
8798 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8799 EXPECT_EQ(ERR_IO_PENDING, rv);
8800 // The HTTP request should succeed.
8801 EXPECT_EQ(OK, callback.WaitForResult());
8802
8803 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:238804 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:028805
8806 const HttpResponseInfo* response = trans->GetResponseInfo();
8807 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508808 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028809 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8810
8811 std::string response_data;
8812 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8813 EXPECT_EQ("hello world", response_data);
8814}
8815
[email protected]23e482282013-06-14 16:08:028816TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:238817 session_deps_.use_alternate_protocols = true;
8818 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:548819
8820 HttpRequestInfo request;
8821 request.method = "GET";
8822 request.url = GURL("http://www.google.com/");
8823 request.load_flags = 0;
8824
[email protected]8a0fc822013-06-27 20:52:438825 std::string alternate_protocol_http_header =
8826 GetAlternateProtocolHttpHeader();
8827
[email protected]2ff8b312010-04-26 22:20:548828 MockRead data_reads[] = {
8829 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438830 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548831 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178832 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8833 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548834 };
8835
8836 StaticSocketDataProvider first_transaction(
8837 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078838 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548839
[email protected]8ddf8322012-02-23 18:08:068840 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028841 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078842 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548843
[email protected]cdf8f7e72013-05-23 10:56:468844 scoped_ptr<SpdyFrame> req(
8845 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138846 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548847
[email protected]23e482282013-06-14 16:08:028848 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8849 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548850 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138851 CreateMockRead(*resp),
8852 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068853 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548854 };
8855
[email protected]dd54bd82012-07-19 23:44:578856 DelayedSocketData spdy_data(
8857 1, // wait for one write to finish before reading.
8858 spdy_reads, arraysize(spdy_reads),
8859 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078860 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548861
[email protected]d973e99a2012-02-17 21:02:368862 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558863 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8864 NULL, 0, NULL, 0);
8865 hanging_non_alternate_protocol_socket.set_connect_data(
8866 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078867 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558868 &hanging_non_alternate_protocol_socket);
8869
[email protected]49639fa2011-12-20 23:22:418870 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548871
[email protected]bb88e1d32013-05-03 23:11:078872 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368873 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508874 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548875
[email protected]49639fa2011-12-20 23:22:418876 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548877 EXPECT_EQ(ERR_IO_PENDING, rv);
8878 EXPECT_EQ(OK, callback.WaitForResult());
8879
8880 const HttpResponseInfo* response = trans->GetResponseInfo();
8881 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508882 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548883 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8884
8885 std::string response_data;
8886 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8887 EXPECT_EQ("hello world", response_data);
8888
[email protected]90499482013-06-01 00:39:508889 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548890
[email protected]49639fa2011-12-20 23:22:418891 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548892 EXPECT_EQ(ERR_IO_PENDING, rv);
8893 EXPECT_EQ(OK, callback.WaitForResult());
8894
8895 response = trans->GetResponseInfo();
8896 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508897 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548898 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538899 EXPECT_TRUE(response->was_fetched_via_spdy);
8900 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548901
8902 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8903 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548904}
8905
[email protected]23e482282013-06-14 16:08:028906TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:238907 session_deps_.use_alternate_protocols = true;
8908 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:558909
8910 HttpRequestInfo request;
8911 request.method = "GET";
8912 request.url = GURL("http://www.google.com/");
8913 request.load_flags = 0;
8914
[email protected]8a0fc822013-06-27 20:52:438915 std::string alternate_protocol_http_header =
8916 GetAlternateProtocolHttpHeader();
8917
[email protected]2d6728692011-03-12 01:39:558918 MockRead data_reads[] = {
8919 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438920 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558921 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178922 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068923 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558924 };
8925
8926 StaticSocketDataProvider first_transaction(
8927 data_reads, arraysize(data_reads), NULL, 0);
8928 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078929 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558930
[email protected]d973e99a2012-02-17 21:02:368931 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558932 StaticSocketDataProvider hanging_socket(
8933 NULL, 0, NULL, 0);
8934 hanging_socket.set_connect_data(never_finishing_connect);
8935 // Socket 2 and 3 are the hanging Alternate-Protocol and
8936 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078937 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8938 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558939
[email protected]8ddf8322012-02-23 18:08:068940 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028941 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078942 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558943
[email protected]cdf8f7e72013-05-23 10:56:468944 scoped_ptr<SpdyFrame> req1(
8945 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8946 scoped_ptr<SpdyFrame> req2(
8947 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558948 MockWrite spdy_writes[] = {
8949 CreateMockWrite(*req1),
8950 CreateMockWrite(*req2),
8951 };
[email protected]23e482282013-06-14 16:08:028952 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8953 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8954 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8955 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558956 MockRead spdy_reads[] = {
8957 CreateMockRead(*resp1),
8958 CreateMockRead(*data1),
8959 CreateMockRead(*resp2),
8960 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068961 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558962 };
8963
[email protected]dd54bd82012-07-19 23:44:578964 DelayedSocketData spdy_data(
8965 2, // wait for writes to finish before reading.
8966 spdy_reads, arraysize(spdy_reads),
8967 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558968 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078969 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558970
8971 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078972 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558973
[email protected]bb88e1d32013-05-03 23:11:078974 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418975 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508976 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558977
[email protected]49639fa2011-12-20 23:22:418978 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558979 EXPECT_EQ(ERR_IO_PENDING, rv);
8980 EXPECT_EQ(OK, callback1.WaitForResult());
8981
8982 const HttpResponseInfo* response = trans1.GetResponseInfo();
8983 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508984 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558985 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8986
8987 std::string response_data;
8988 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8989 EXPECT_EQ("hello world", response_data);
8990
[email protected]49639fa2011-12-20 23:22:418991 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508992 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418993 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558994 EXPECT_EQ(ERR_IO_PENDING, rv);
8995
[email protected]49639fa2011-12-20 23:22:418996 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508997 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418998 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558999 EXPECT_EQ(ERR_IO_PENDING, rv);
9000
9001 EXPECT_EQ(OK, callback2.WaitForResult());
9002 EXPECT_EQ(OK, callback3.WaitForResult());
9003
9004 response = trans2.GetResponseInfo();
9005 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509006 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559007 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9008 EXPECT_TRUE(response->was_fetched_via_spdy);
9009 EXPECT_TRUE(response->was_npn_negotiated);
9010 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9011 EXPECT_EQ("hello!", response_data);
9012
9013 response = trans3.GetResponseInfo();
9014 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509015 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559016 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9017 EXPECT_TRUE(response->was_fetched_via_spdy);
9018 EXPECT_TRUE(response->was_npn_negotiated);
9019 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9020 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559021}
9022
[email protected]23e482282013-06-14 16:08:029023TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239024 session_deps_.use_alternate_protocols = true;
9025 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559026
9027 HttpRequestInfo request;
9028 request.method = "GET";
9029 request.url = GURL("http://www.google.com/");
9030 request.load_flags = 0;
9031
[email protected]8a0fc822013-06-27 20:52:439032 std::string alternate_protocol_http_header =
9033 GetAlternateProtocolHttpHeader();
9034
[email protected]2d6728692011-03-12 01:39:559035 MockRead data_reads[] = {
9036 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439037 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559038 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179039 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069040 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559041 };
9042
9043 StaticSocketDataProvider first_transaction(
9044 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079045 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559046
[email protected]8ddf8322012-02-23 18:08:069047 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029048 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079049 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559050
[email protected]d973e99a2012-02-17 21:02:369051 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559052 StaticSocketDataProvider hanging_alternate_protocol_socket(
9053 NULL, 0, NULL, 0);
9054 hanging_alternate_protocol_socket.set_connect_data(
9055 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079056 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559057 &hanging_alternate_protocol_socket);
9058
9059 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079060 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559061
[email protected]49639fa2011-12-20 23:22:419062 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559063
[email protected]bb88e1d32013-05-03 23:11:079064 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369065 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559067
[email protected]49639fa2011-12-20 23:22:419068 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559069 EXPECT_EQ(ERR_IO_PENDING, rv);
9070 EXPECT_EQ(OK, callback.WaitForResult());
9071
9072 const HttpResponseInfo* response = trans->GetResponseInfo();
9073 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509074 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559075 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9076
9077 std::string response_data;
9078 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9079 EXPECT_EQ("hello world", response_data);
9080
[email protected]90499482013-06-01 00:39:509081 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559082
[email protected]49639fa2011-12-20 23:22:419083 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559084 EXPECT_EQ(ERR_IO_PENDING, rv);
9085 EXPECT_EQ(OK, callback.WaitForResult());
9086
9087 response = trans->GetResponseInfo();
9088 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509089 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559090 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9091 EXPECT_FALSE(response->was_fetched_via_spdy);
9092 EXPECT_FALSE(response->was_npn_negotiated);
9093
9094 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9095 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559096}
9097
[email protected]631f1322010-04-30 17:59:119098class CapturingProxyResolver : public ProxyResolver {
9099 public:
9100 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
9101 virtual ~CapturingProxyResolver() {}
9102
9103 virtual int GetProxyForURL(const GURL& url,
9104 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:319105 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:119106 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:169107 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:409108 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9109 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429110 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119111 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429112 return OK;
[email protected]631f1322010-04-30 17:59:119113 }
9114
[email protected]46fadfd2013-02-06 09:40:169115 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:119116 NOTREACHED();
9117 }
9118
[email protected]f2c971f2011-11-08 00:33:179119 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
9120 NOTREACHED();
9121 return LOAD_STATE_IDLE;
9122 }
9123
[email protected]46fadfd2013-02-06 09:40:169124 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:409125 NOTREACHED();
9126 }
9127
[email protected]24476402010-07-20 20:55:179128 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:169129 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:429130 return OK;
[email protected]631f1322010-04-30 17:59:119131 }
9132
[email protected]24476402010-07-20 20:55:179133 const std::vector<GURL>& resolved() const { return resolved_; }
9134
9135 private:
[email protected]631f1322010-04-30 17:59:119136 std::vector<GURL> resolved_;
9137
9138 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9139};
9140
[email protected]23e482282013-06-14 16:08:029141TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239142 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239143 session_deps_.use_alternate_protocols = true;
9144 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119145
9146 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429147 proxy_config.set_auto_detect(true);
9148 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119149
[email protected]631f1322010-04-30 17:59:119150 CapturingProxyResolver* capturing_proxy_resolver =
9151 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:079152 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:389153 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9154 NULL));
[email protected]029c83b62013-01-24 05:28:209155 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079156 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119157
9158 HttpRequestInfo request;
9159 request.method = "GET";
9160 request.url = GURL("http://www.google.com/");
9161 request.load_flags = 0;
9162
[email protected]8a0fc822013-06-27 20:52:439163 std::string alternate_protocol_http_header =
9164 GetAlternateProtocolHttpHeader();
9165
[email protected]631f1322010-04-30 17:59:119166 MockRead data_reads[] = {
9167 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439168 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119169 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179170 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069171 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119172 };
9173
9174 StaticSocketDataProvider first_transaction(
9175 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079176 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119177
[email protected]8ddf8322012-02-23 18:08:069178 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029179 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079180 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119181
[email protected]cdf8f7e72013-05-23 10:56:469182 scoped_ptr<SpdyFrame> req(
9183 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119184 MockWrite spdy_writes[] = {
9185 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9186 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:429187 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:469188 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:119189 };
9190
[email protected]d911f1b2010-05-05 22:39:429191 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9192
[email protected]23e482282013-06-14 16:08:029193 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9194 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119195 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069196 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:139197 CreateMockRead(*resp.get(), 4), // 2, 4
9198 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:069199 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:119200 };
9201
[email protected]dd54bd82012-07-19 23:44:579202 OrderedSocketData spdy_data(
9203 spdy_reads, arraysize(spdy_reads),
9204 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079205 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119206
[email protected]d973e99a2012-02-17 21:02:369207 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559208 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9209 NULL, 0, NULL, 0);
9210 hanging_non_alternate_protocol_socket.set_connect_data(
9211 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079212 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559213 &hanging_non_alternate_protocol_socket);
9214
[email protected]49639fa2011-12-20 23:22:419215 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119216
[email protected]bb88e1d32013-05-03 23:11:079217 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369218 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119220
[email protected]49639fa2011-12-20 23:22:419221 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119222 EXPECT_EQ(ERR_IO_PENDING, rv);
9223 EXPECT_EQ(OK, callback.WaitForResult());
9224
9225 const HttpResponseInfo* response = trans->GetResponseInfo();
9226 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509227 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119228 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539229 EXPECT_FALSE(response->was_fetched_via_spdy);
9230 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119231
9232 std::string response_data;
9233 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9234 EXPECT_EQ("hello world", response_data);
9235
[email protected]90499482013-06-01 00:39:509236 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119237
[email protected]49639fa2011-12-20 23:22:419238 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119239 EXPECT_EQ(ERR_IO_PENDING, rv);
9240 EXPECT_EQ(OK, callback.WaitForResult());
9241
9242 response = trans->GetResponseInfo();
9243 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509244 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119245 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539246 EXPECT_TRUE(response->was_fetched_via_spdy);
9247 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119248
9249 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9250 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559251 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:429252 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:119253 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:429254 EXPECT_EQ("https://www.google.com/",
9255 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119256
[email protected]029c83b62013-01-24 05:28:209257 LoadTimingInfo load_timing_info;
9258 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9259 TestLoadTimingNotReusedWithPac(load_timing_info,
9260 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119261}
[email protected]631f1322010-04-30 17:59:119262
[email protected]23e482282013-06-14 16:08:029263TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549264 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239265 session_deps_.use_alternate_protocols = true;
9266 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549267
9268 HttpRequestInfo request;
9269 request.method = "GET";
9270 request.url = GURL("http://www.google.com/");
9271 request.load_flags = 0;
9272
[email protected]8a0fc822013-06-27 20:52:439273 std::string alternate_protocol_http_header =
9274 GetAlternateProtocolHttpHeader();
9275
[email protected]2ff8b312010-04-26 22:20:549276 MockRead data_reads[] = {
9277 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439278 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549279 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069280 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549281 };
9282
9283 StaticSocketDataProvider first_transaction(
9284 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079285 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549286
[email protected]8ddf8322012-02-23 18:08:069287 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029288 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079289 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549290
[email protected]cdf8f7e72013-05-23 10:56:469291 scoped_ptr<SpdyFrame> req(
9292 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139293 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549294
[email protected]23e482282013-06-14 16:08:029295 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9296 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549297 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139298 CreateMockRead(*resp),
9299 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069300 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549301 };
9302
[email protected]dd54bd82012-07-19 23:44:579303 DelayedSocketData spdy_data(
9304 1, // wait for one write to finish before reading.
9305 spdy_reads, arraysize(spdy_reads),
9306 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079307 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549308
[email protected]83039bb2011-12-09 18:43:559309 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549310
[email protected]bb88e1d32013-05-03 23:11:079311 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549312
[email protected]262eec82013-03-19 21:01:369313 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509314 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549315
[email protected]49639fa2011-12-20 23:22:419316 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549317 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419318 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549319
9320 const HttpResponseInfo* response = trans->GetResponseInfo();
9321 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509322 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549323 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9324
9325 std::string response_data;
9326 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9327 EXPECT_EQ("hello world", response_data);
9328
9329 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389330 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409331 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539332 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279333 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269334 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389335
[email protected]90499482013-06-01 00:39:509336 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549337
[email protected]49639fa2011-12-20 23:22:419338 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549339 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419340 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549341
9342 response = trans->GetResponseInfo();
9343 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509344 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549345 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539346 EXPECT_TRUE(response->was_fetched_via_spdy);
9347 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549348
9349 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9350 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429351}
9352
[email protected]044de0642010-06-17 10:42:159353// GenerateAuthToken is a mighty big test.
9354// It tests all permutation of GenerateAuthToken behavior:
9355// - Synchronous and Asynchronous completion.
9356// - OK or error on completion.
9357// - Direct connection, non-authenticating proxy, and authenticating proxy.
9358// - HTTP or HTTPS backend (to include proxy tunneling).
9359// - Non-authenticating and authenticating backend.
9360//
[email protected]fe3b7dc2012-02-03 19:52:099361// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159362// problems generating an auth token for an authenticating proxy, we don't
9363// need to test all permutations of the backend server).
9364//
9365// The test proceeds by going over each of the configuration cases, and
9366// potentially running up to three rounds in each of the tests. The TestConfig
9367// specifies both the configuration for the test as well as the expectations
9368// for the results.
[email protected]23e482282013-06-14 16:08:029369TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509370 static const char kServer[] = "http://www.example.com";
9371 static const char kSecureServer[] = "https://www.example.com";
9372 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159373 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9374
9375 enum AuthTiming {
9376 AUTH_NONE,
9377 AUTH_SYNC,
9378 AUTH_ASYNC,
9379 };
9380
9381 const MockWrite kGet(
9382 "GET / HTTP/1.1\r\n"
9383 "Host: www.example.com\r\n"
9384 "Connection: keep-alive\r\n\r\n");
9385 const MockWrite kGetProxy(
9386 "GET http://www.example.com/ HTTP/1.1\r\n"
9387 "Host: www.example.com\r\n"
9388 "Proxy-Connection: keep-alive\r\n\r\n");
9389 const MockWrite kGetAuth(
9390 "GET / HTTP/1.1\r\n"
9391 "Host: www.example.com\r\n"
9392 "Connection: keep-alive\r\n"
9393 "Authorization: auth_token\r\n\r\n");
9394 const MockWrite kGetProxyAuth(
9395 "GET http://www.example.com/ HTTP/1.1\r\n"
9396 "Host: www.example.com\r\n"
9397 "Proxy-Connection: keep-alive\r\n"
9398 "Proxy-Authorization: auth_token\r\n\r\n");
9399 const MockWrite kGetAuthThroughProxy(
9400 "GET http://www.example.com/ HTTP/1.1\r\n"
9401 "Host: www.example.com\r\n"
9402 "Proxy-Connection: keep-alive\r\n"
9403 "Authorization: auth_token\r\n\r\n");
9404 const MockWrite kGetAuthWithProxyAuth(
9405 "GET http://www.example.com/ HTTP/1.1\r\n"
9406 "Host: www.example.com\r\n"
9407 "Proxy-Connection: keep-alive\r\n"
9408 "Proxy-Authorization: auth_token\r\n"
9409 "Authorization: auth_token\r\n\r\n");
9410 const MockWrite kConnect(
9411 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9412 "Host: www.example.com\r\n"
9413 "Proxy-Connection: keep-alive\r\n\r\n");
9414 const MockWrite kConnectProxyAuth(
9415 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9416 "Host: www.example.com\r\n"
9417 "Proxy-Connection: keep-alive\r\n"
9418 "Proxy-Authorization: auth_token\r\n\r\n");
9419
9420 const MockRead kSuccess(
9421 "HTTP/1.1 200 OK\r\n"
9422 "Content-Type: text/html; charset=iso-8859-1\r\n"
9423 "Content-Length: 3\r\n\r\n"
9424 "Yes");
9425 const MockRead kFailure(
9426 "Should not be called.");
9427 const MockRead kServerChallenge(
9428 "HTTP/1.1 401 Unauthorized\r\n"
9429 "WWW-Authenticate: Mock realm=server\r\n"
9430 "Content-Type: text/html; charset=iso-8859-1\r\n"
9431 "Content-Length: 14\r\n\r\n"
9432 "Unauthorized\r\n");
9433 const MockRead kProxyChallenge(
9434 "HTTP/1.1 407 Unauthorized\r\n"
9435 "Proxy-Authenticate: Mock realm=proxy\r\n"
9436 "Proxy-Connection: close\r\n"
9437 "Content-Type: text/html; charset=iso-8859-1\r\n"
9438 "Content-Length: 14\r\n\r\n"
9439 "Unauthorized\r\n");
9440 const MockRead kProxyConnected(
9441 "HTTP/1.1 200 Connection Established\r\n\r\n");
9442
9443 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9444 // no constructors, but the C++ compiler on Windows warns about
9445 // unspecified data in compound literals. So, moved to using constructors,
9446 // and TestRound's created with the default constructor should not be used.
9447 struct TestRound {
9448 TestRound()
9449 : expected_rv(ERR_UNEXPECTED),
9450 extra_write(NULL),
9451 extra_read(NULL) {
9452 }
9453 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9454 int expected_rv_arg)
9455 : write(write_arg),
9456 read(read_arg),
9457 expected_rv(expected_rv_arg),
9458 extra_write(NULL),
9459 extra_read(NULL) {
9460 }
9461 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9462 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019463 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159464 : write(write_arg),
9465 read(read_arg),
9466 expected_rv(expected_rv_arg),
9467 extra_write(extra_write_arg),
9468 extra_read(extra_read_arg) {
9469 }
9470 MockWrite write;
9471 MockRead read;
9472 int expected_rv;
9473 const MockWrite* extra_write;
9474 const MockRead* extra_read;
9475 };
9476
9477 static const int kNoSSL = 500;
9478
9479 struct TestConfig {
9480 const char* proxy_url;
9481 AuthTiming proxy_auth_timing;
9482 int proxy_auth_rv;
9483 const char* server_url;
9484 AuthTiming server_auth_timing;
9485 int server_auth_rv;
9486 int num_auth_rounds;
9487 int first_ssl_round;
9488 TestRound rounds[3];
9489 } test_configs[] = {
9490 // Non-authenticating HTTP server with a direct connection.
9491 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9492 { TestRound(kGet, kSuccess, OK)}},
9493 // Authenticating HTTP server with a direct connection.
9494 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9495 { TestRound(kGet, kServerChallenge, OK),
9496 TestRound(kGetAuth, kSuccess, OK)}},
9497 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9498 { TestRound(kGet, kServerChallenge, OK),
9499 TestRound(kGetAuth, kFailure, kAuthErr)}},
9500 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9501 { TestRound(kGet, kServerChallenge, OK),
9502 TestRound(kGetAuth, kSuccess, OK)}},
9503 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9504 { TestRound(kGet, kServerChallenge, OK),
9505 TestRound(kGetAuth, kFailure, kAuthErr)}},
9506 // Non-authenticating HTTP server through a non-authenticating proxy.
9507 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9508 { TestRound(kGetProxy, kSuccess, OK)}},
9509 // Authenticating HTTP server through a non-authenticating proxy.
9510 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9511 { TestRound(kGetProxy, kServerChallenge, OK),
9512 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9513 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9514 { TestRound(kGetProxy, kServerChallenge, OK),
9515 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9516 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9517 { TestRound(kGetProxy, kServerChallenge, OK),
9518 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9519 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9520 { TestRound(kGetProxy, kServerChallenge, OK),
9521 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9522 // Non-authenticating HTTP server through an authenticating proxy.
9523 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9524 { TestRound(kGetProxy, kProxyChallenge, OK),
9525 TestRound(kGetProxyAuth, kSuccess, OK)}},
9526 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9527 { TestRound(kGetProxy, kProxyChallenge, OK),
9528 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9529 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9530 { TestRound(kGetProxy, kProxyChallenge, OK),
9531 TestRound(kGetProxyAuth, kSuccess, OK)}},
9532 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9533 { TestRound(kGetProxy, kProxyChallenge, OK),
9534 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9535 // Authenticating HTTP server through an authenticating proxy.
9536 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9537 { TestRound(kGetProxy, kProxyChallenge, OK),
9538 TestRound(kGetProxyAuth, kServerChallenge, OK),
9539 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9540 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9541 { TestRound(kGetProxy, kProxyChallenge, OK),
9542 TestRound(kGetProxyAuth, kServerChallenge, OK),
9543 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9544 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9545 { TestRound(kGetProxy, kProxyChallenge, OK),
9546 TestRound(kGetProxyAuth, kServerChallenge, OK),
9547 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9548 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9549 { TestRound(kGetProxy, kProxyChallenge, OK),
9550 TestRound(kGetProxyAuth, kServerChallenge, OK),
9551 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9552 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9553 { TestRound(kGetProxy, kProxyChallenge, OK),
9554 TestRound(kGetProxyAuth, kServerChallenge, OK),
9555 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9556 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9557 { TestRound(kGetProxy, kProxyChallenge, OK),
9558 TestRound(kGetProxyAuth, kServerChallenge, OK),
9559 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9560 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9561 { TestRound(kGetProxy, kProxyChallenge, OK),
9562 TestRound(kGetProxyAuth, kServerChallenge, OK),
9563 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9564 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9565 { TestRound(kGetProxy, kProxyChallenge, OK),
9566 TestRound(kGetProxyAuth, kServerChallenge, OK),
9567 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9568 // Non-authenticating HTTPS server with a direct connection.
9569 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9570 { TestRound(kGet, kSuccess, OK)}},
9571 // Authenticating HTTPS server with a direct connection.
9572 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9573 { TestRound(kGet, kServerChallenge, OK),
9574 TestRound(kGetAuth, kSuccess, OK)}},
9575 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9576 { TestRound(kGet, kServerChallenge, OK),
9577 TestRound(kGetAuth, kFailure, kAuthErr)}},
9578 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9579 { TestRound(kGet, kServerChallenge, OK),
9580 TestRound(kGetAuth, kSuccess, OK)}},
9581 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9582 { TestRound(kGet, kServerChallenge, OK),
9583 TestRound(kGetAuth, kFailure, kAuthErr)}},
9584 // Non-authenticating HTTPS server with a non-authenticating proxy.
9585 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9586 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9587 // Authenticating HTTPS server through a non-authenticating proxy.
9588 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9589 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9590 TestRound(kGetAuth, kSuccess, OK)}},
9591 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9592 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9593 TestRound(kGetAuth, kFailure, kAuthErr)}},
9594 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9595 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9596 TestRound(kGetAuth, kSuccess, OK)}},
9597 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9598 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9599 TestRound(kGetAuth, kFailure, kAuthErr)}},
9600 // Non-Authenticating HTTPS server through an authenticating proxy.
9601 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9602 { TestRound(kConnect, kProxyChallenge, OK),
9603 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9604 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9605 { TestRound(kConnect, kProxyChallenge, OK),
9606 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9607 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9608 { TestRound(kConnect, kProxyChallenge, OK),
9609 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9610 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9611 { TestRound(kConnect, kProxyChallenge, OK),
9612 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9613 // Authenticating HTTPS server through an authenticating proxy.
9614 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9615 { TestRound(kConnect, kProxyChallenge, OK),
9616 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9617 &kGet, &kServerChallenge),
9618 TestRound(kGetAuth, kSuccess, OK)}},
9619 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9620 { TestRound(kConnect, kProxyChallenge, OK),
9621 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9622 &kGet, &kServerChallenge),
9623 TestRound(kGetAuth, kFailure, kAuthErr)}},
9624 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9625 { TestRound(kConnect, kProxyChallenge, OK),
9626 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9627 &kGet, &kServerChallenge),
9628 TestRound(kGetAuth, kSuccess, OK)}},
9629 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9630 { TestRound(kConnect, kProxyChallenge, OK),
9631 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9632 &kGet, &kServerChallenge),
9633 TestRound(kGetAuth, kFailure, kAuthErr)}},
9634 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9635 { TestRound(kConnect, kProxyChallenge, OK),
9636 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9637 &kGet, &kServerChallenge),
9638 TestRound(kGetAuth, kSuccess, OK)}},
9639 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9640 { TestRound(kConnect, kProxyChallenge, OK),
9641 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9642 &kGet, &kServerChallenge),
9643 TestRound(kGetAuth, kFailure, kAuthErr)}},
9644 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9645 { TestRound(kConnect, kProxyChallenge, OK),
9646 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9647 &kGet, &kServerChallenge),
9648 TestRound(kGetAuth, kSuccess, OK)}},
9649 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9650 { TestRound(kConnect, kProxyChallenge, OK),
9651 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9652 &kGet, &kServerChallenge),
9653 TestRound(kGetAuth, kFailure, kAuthErr)}},
9654 };
9655
[email protected]044de0642010-06-17 10:42:159656 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089657 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);
[email protected]044de0642010-06-17 10:42:159660 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269661
9662 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159663 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089664 for (int n = 0; n < 2; n++) {
9665 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9666 std::string auth_challenge = "Mock realm=proxy";
9667 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:249668 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9669 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:089670 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9671 origin, BoundNetLog());
9672 auth_handler->SetGenerateExpectation(
9673 test_config.proxy_auth_timing == AUTH_ASYNC,
9674 test_config.proxy_auth_rv);
9675 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9676 }
[email protected]044de0642010-06-17 10:42:159677 }
9678 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009679 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159680 std::string auth_challenge = "Mock realm=server";
9681 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:249682 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9683 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:159684 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9685 origin, BoundNetLog());
9686 auth_handler->SetGenerateExpectation(
9687 test_config.server_auth_timing == AUTH_ASYNC,
9688 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089689 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159690 }
9691 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079692 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129693 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159694 } else {
[email protected]bb88e1d32013-05-03 23:11:079695 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159696 }
9697
9698 HttpRequestInfo request;
9699 request.method = "GET";
9700 request.url = GURL(test_config.server_url);
9701 request.load_flags = 0;
9702
[email protected]bb88e1d32013-05-03 23:11:079703 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:079704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]044de0642010-06-17 10:42:159705
9706 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9707 const TestRound& read_write_round = test_config.rounds[round];
9708
9709 // Set up expected reads and writes.
9710 MockRead reads[2];
9711 reads[0] = read_write_round.read;
9712 size_t length_reads = 1;
9713 if (read_write_round.extra_read) {
9714 reads[1] = *read_write_round.extra_read;
9715 length_reads = 2;
9716 }
9717
9718 MockWrite writes[2];
9719 writes[0] = read_write_round.write;
9720 size_t length_writes = 1;
9721 if (read_write_round.extra_write) {
9722 writes[1] = *read_write_round.extra_write;
9723 length_writes = 2;
9724 }
9725 StaticSocketDataProvider data_provider(
9726 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079727 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159728
9729 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069730 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159731 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079732 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159733 &ssl_socket_data_provider);
9734
9735 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419736 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159737 int rv;
9738 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419739 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159740 } else {
[email protected]49639fa2011-12-20 23:22:419741 rv = trans.RestartWithAuth(
9742 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159743 }
9744 if (rv == ERR_IO_PENDING)
9745 rv = callback.WaitForResult();
9746
9747 // Compare results with expected data.
9748 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509749 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159750 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509751 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159752 } else {
9753 EXPECT_TRUE(response == NULL);
9754 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9755 continue;
9756 }
9757 if (round + 1 < test_config.num_auth_rounds) {
9758 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9759 } else {
9760 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9761 }
9762 }
[email protected]e5ae96a2010-04-14 20:12:459763 }
9764}
9765
[email protected]23e482282013-06-14 16:08:029766TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149767 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149768 HttpAuthHandlerMock::Factory* auth_factory(
9769 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079770 session_deps_.http_auth_handler_factory.reset(auth_factory);
9771 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9772 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9773 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149774
9775 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9776 auth_handler->set_connection_based(true);
9777 std::string auth_challenge = "Mock realm=server";
9778 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:249779 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9780 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:149781 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9782 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089783 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149784
[email protected]c871bce92010-07-15 21:51:149785 int rv = OK;
9786 const HttpResponseInfo* response = NULL;
9787 HttpRequestInfo request;
9788 request.method = "GET";
9789 request.url = origin;
9790 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279791
[email protected]bb88e1d32013-05-03 23:11:079792 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109793
9794 // Use a TCP Socket Pool with only one connection per group. This is used
9795 // to validate that the TCP socket is not released to the pool between
9796 // each round of multi-round authentication.
9797 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289798 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9799 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109800 50, // Max sockets for pool
9801 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289802 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079803 session_deps_.host_resolver.get(),
9804 session_deps_.socket_factory.get(),
9805 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449806 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9807 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029808 mock_pool_manager->SetTransportSocketPool(transport_pool);
[email protected]831e4a32013-11-14 02:14:449809 session_peer.SetClientSocketPoolManager(
9810 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]7ef4cbbb2011-02-06 11:19:109811
[email protected]262eec82013-03-19 21:01:369812 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419814 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149815
9816 const MockWrite kGet(
9817 "GET / HTTP/1.1\r\n"
9818 "Host: www.example.com\r\n"
9819 "Connection: keep-alive\r\n\r\n");
9820 const MockWrite kGetAuth(
9821 "GET / HTTP/1.1\r\n"
9822 "Host: www.example.com\r\n"
9823 "Connection: keep-alive\r\n"
9824 "Authorization: auth_token\r\n\r\n");
9825
9826 const MockRead kServerChallenge(
9827 "HTTP/1.1 401 Unauthorized\r\n"
9828 "WWW-Authenticate: Mock realm=server\r\n"
9829 "Content-Type: text/html; charset=iso-8859-1\r\n"
9830 "Content-Length: 14\r\n\r\n"
9831 "Unauthorized\r\n");
9832 const MockRead kSuccess(
9833 "HTTP/1.1 200 OK\r\n"
9834 "Content-Type: text/html; charset=iso-8859-1\r\n"
9835 "Content-Length: 3\r\n\r\n"
9836 "Yes");
9837
9838 MockWrite writes[] = {
9839 // First round
9840 kGet,
9841 // Second round
9842 kGetAuth,
9843 // Third round
9844 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309845 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109846 kGetAuth,
9847 // Competing request
9848 kGet,
[email protected]c871bce92010-07-15 21:51:149849 };
9850 MockRead reads[] = {
9851 // First round
9852 kServerChallenge,
9853 // Second round
9854 kServerChallenge,
9855 // Third round
[email protected]eca50e122010-09-11 14:03:309856 kServerChallenge,
9857 // Fourth round
[email protected]c871bce92010-07-15 21:51:149858 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109859 // Competing response
9860 kSuccess,
[email protected]c871bce92010-07-15 21:51:149861 };
9862 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9863 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079864 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149865
[email protected]7ef4cbbb2011-02-06 11:19:109866 const char* const kSocketGroup = "www.example.com:80";
9867
9868 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149869 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419870 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149871 if (rv == ERR_IO_PENDING)
9872 rv = callback.WaitForResult();
9873 EXPECT_EQ(OK, rv);
9874 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509875 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149876 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289877 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149878
[email protected]7ef4cbbb2011-02-06 11:19:109879 // In between rounds, another request comes in for the same domain.
9880 // It should not be able to grab the TCP socket that trans has already
9881 // claimed.
9882 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509883 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419884 TestCompletionCallback callback_compete;
9885 rv = trans_compete->Start(
9886 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109887 EXPECT_EQ(ERR_IO_PENDING, rv);
9888 // callback_compete.WaitForResult at this point would stall forever,
9889 // since the HttpNetworkTransaction does not release the request back to
9890 // the pool until after authentication completes.
9891
9892 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149893 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419894 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149895 if (rv == ERR_IO_PENDING)
9896 rv = callback.WaitForResult();
9897 EXPECT_EQ(OK, rv);
9898 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509899 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149900 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289901 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149902
[email protected]7ef4cbbb2011-02-06 11:19:109903 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149904 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419905 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149906 if (rv == ERR_IO_PENDING)
9907 rv = callback.WaitForResult();
9908 EXPECT_EQ(OK, rv);
9909 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509910 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149911 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289912 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309913
[email protected]7ef4cbbb2011-02-06 11:19:109914 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309915 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419916 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309917 if (rv == ERR_IO_PENDING)
9918 rv = callback.WaitForResult();
9919 EXPECT_EQ(OK, rv);
9920 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509921 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309922 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289923 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109924
9925 // Read the body since the fourth round was successful. This will also
9926 // release the socket back to the pool.
9927 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509928 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109929 if (rv == ERR_IO_PENDING)
9930 rv = callback.WaitForResult();
9931 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509932 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109933 EXPECT_EQ(0, rv);
9934 // There are still 0 idle sockets, since the trans_compete transaction
9935 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289936 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109937
9938 // The competing request can now finish. Wait for the headers and then
9939 // read the body.
9940 rv = callback_compete.WaitForResult();
9941 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509942 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109943 if (rv == ERR_IO_PENDING)
9944 rv = callback.WaitForResult();
9945 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509946 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109947 EXPECT_EQ(0, rv);
9948
9949 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289950 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149951}
9952
[email protected]65041fa2010-05-21 06:56:539953// This tests the case that a request is issued via http instead of spdy after
9954// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029955TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:239956 session_deps_.use_alternate_protocols = true;
9957 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:169958 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:239959 session_deps_.next_protos = next_protos;
9960
[email protected]65041fa2010-05-21 06:56:539961 HttpRequestInfo request;
9962 request.method = "GET";
9963 request.url = GURL("https://www.google.com/");
9964 request.load_flags = 0;
9965
9966 MockWrite data_writes[] = {
9967 MockWrite("GET / HTTP/1.1\r\n"
9968 "Host: www.google.com\r\n"
9969 "Connection: keep-alive\r\n\r\n"),
9970 };
9971
[email protected]8a0fc822013-06-27 20:52:439972 std::string alternate_protocol_http_header =
9973 GetAlternateProtocolHttpHeader();
9974
[email protected]65041fa2010-05-21 06:56:539975 MockRead data_reads[] = {
9976 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439977 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539978 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069979 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539980 };
9981
[email protected]8ddf8322012-02-23 18:08:069982 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539983 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9984 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469985 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539986
[email protected]bb88e1d32013-05-03 23:11:079987 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539988
9989 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9990 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079991 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539992
[email protected]49639fa2011-12-20 23:22:419993 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539994
[email protected]bb88e1d32013-05-03 23:11:079995 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369996 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539998
[email protected]49639fa2011-12-20 23:22:419999 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310000
10001 EXPECT_EQ(ERR_IO_PENDING, rv);
10002 EXPECT_EQ(OK, callback.WaitForResult());
10003
10004 const HttpResponseInfo* response = trans->GetResponseInfo();
10005 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010006 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310007 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10008
10009 std::string response_data;
10010 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10011 EXPECT_EQ("hello world", response_data);
10012
10013 EXPECT_FALSE(response->was_fetched_via_spdy);
10014 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310015}
[email protected]26ef6582010-06-24 02:30:4710016
[email protected]23e482282013-06-14 16:08:0210017TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710018 // Simulate the SSL handshake completing with an NPN negotiation
10019 // followed by an immediate server closing of the socket.
10020 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310021 session_deps_.use_alternate_protocols = true;
10022 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710023
10024 HttpRequestInfo request;
10025 request.method = "GET";
10026 request.url = GURL("https://www.google.com/");
10027 request.load_flags = 0;
10028
[email protected]8ddf8322012-02-23 18:08:0610029 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210030 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710031 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710032
[email protected]cdf8f7e72013-05-23 10:56:4610033 scoped_ptr<SpdyFrame> req(
10034 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:1310035 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:4710036
10037 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610038 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710039 };
10040
[email protected]dd54bd82012-07-19 23:44:5710041 DelayedSocketData spdy_data(
10042 0, // don't wait in this case, immediate hangup.
10043 spdy_reads, arraysize(spdy_reads),
10044 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710045 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710046
[email protected]49639fa2011-12-20 23:22:4110047 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710048
[email protected]bb88e1d32013-05-03 23:11:0710049 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610050 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010051 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710052
[email protected]49639fa2011-12-20 23:22:4110053 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710054 EXPECT_EQ(ERR_IO_PENDING, rv);
10055 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710056}
[email protected]65d34382010-07-01 18:12:2610057
[email protected]795cbf82013-07-22 09:37:2710058// A subclass of HttpAuthHandlerMock that records the request URL when
10059// it gets it. This is needed since the auth handler may get destroyed
10060// before we get a chance to query it.
10061class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10062 public:
10063 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10064
10065 virtual ~UrlRecordingHttpAuthHandlerMock() {}
10066
10067 protected:
10068 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10069 const HttpRequestInfo* request,
10070 const CompletionCallback& callback,
10071 std::string* auth_token) OVERRIDE {
10072 *url_ = request->url;
10073 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10074 credentials, request, callback, auth_token);
10075 }
10076
10077 private:
10078 GURL* url_;
10079};
10080
[email protected]23e482282013-06-14 16:08:0210081TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010082 // This test ensures that the URL passed into the proxy is upgraded
10083 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310084 session_deps_.use_alternate_protocols = true;
10085 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010086
[email protected]bb88e1d32013-05-03 23:11:0710087 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010088 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10089 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710090 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710091 GURL request_url;
10092 {
10093 HttpAuthHandlerMock::Factory* auth_factory =
10094 new HttpAuthHandlerMock::Factory();
10095 UrlRecordingHttpAuthHandlerMock* auth_handler =
10096 new UrlRecordingHttpAuthHandlerMock(&request_url);
10097 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10098 auth_factory->set_do_init_from_challenge(true);
10099 session_deps_.http_auth_handler_factory.reset(auth_factory);
10100 }
[email protected]f45c1ee2010-08-03 00:54:3010101
10102 HttpRequestInfo request;
10103 request.method = "GET";
10104 request.url = GURL("http://www.google.com");
10105 request.load_flags = 0;
10106
10107 // First round goes unauthenticated through the proxy.
10108 MockWrite data_writes_1[] = {
10109 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10110 "Host: www.google.com\r\n"
10111 "Proxy-Connection: keep-alive\r\n"
10112 "\r\n"),
10113 };
10114 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610115 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:3010116 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:2310117 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:3010118 "Proxy-Connection: close\r\n"
10119 "\r\n"),
10120 };
10121 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10122 data_writes_1, arraysize(data_writes_1));
10123
10124 // Second round tries to tunnel to www.google.com due to the
10125 // Alternate-Protocol announcement in the first round. It fails due
10126 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:5910127 // After the failure, a tunnel is established to www.google.com using
10128 // Proxy-Authorization headers. There is then a SPDY request round.
10129 //
[email protected]fe3b7dc2012-02-03 19:52:0910130 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10131 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10132 // does a Disconnect and Connect on the same socket, rather than trying
10133 // to obtain a new one.
10134 //
[email protected]394816e92010-08-03 07:38:5910135 // NOTE: Originally, the proxy response to the second CONNECT request
10136 // simply returned another 407 so the unit test could skip the SSL connection
10137 // establishment and SPDY framing issues. Alas, the
10138 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010139 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910140
[email protected]cdf8f7e72013-05-23 10:56:4610141 scoped_ptr<SpdyFrame> req(
10142 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210143 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10144 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010145
[email protected]394816e92010-08-03 07:38:5910146 MockWrite data_writes_2[] = {
10147 // First connection attempt without Proxy-Authorization.
10148 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10149 "Host: www.google.com\r\n"
10150 "Proxy-Connection: keep-alive\r\n"
10151 "\r\n"),
10152
10153 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:3010154 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10155 "Host: www.google.com\r\n"
10156 "Proxy-Connection: keep-alive\r\n"
10157 "Proxy-Authorization: auth_token\r\n"
10158 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010159
[email protected]394816e92010-08-03 07:38:5910160 // SPDY request
10161 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:3010162 };
[email protected]394816e92010-08-03 07:38:5910163 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10164 "Proxy-Authenticate: Mock\r\n"
10165 "Proxy-Connection: close\r\n"
10166 "\r\n");
10167 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10168 MockRead data_reads_2[] = {
10169 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:0610170 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10171 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:5910172 arraysize(kRejectConnectResponse) - 1, 1),
10173
10174 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:0610175 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:0910176 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:5910177
10178 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:0910179 CreateMockRead(*resp.get(), 6),
10180 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:0610181 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:5910182 };
[email protected]dd54bd82012-07-19 23:44:5710183 OrderedSocketData data_2(
10184 data_reads_2, arraysize(data_reads_2),
10185 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010186
[email protected]8ddf8322012-02-23 18:08:0610187 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210188 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:3010189
[email protected]d973e99a2012-02-17 21:02:3610190 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510191 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10192 NULL, 0, NULL, 0);
10193 hanging_non_alternate_protocol_socket.set_connect_data(
10194 never_finishing_connect);
10195
[email protected]bb88e1d32013-05-03 23:11:0710196 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10197 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10198 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10199 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510200 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710201 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010202
10203 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110204 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610205 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010206 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110207 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010208 EXPECT_EQ(ERR_IO_PENDING, rv);
10209 EXPECT_EQ(OK, callback_1.WaitForResult());
10210
10211 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110212 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610213 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110215 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010216 EXPECT_EQ(ERR_IO_PENDING, rv);
10217 EXPECT_EQ(OK, callback_2.WaitForResult());
10218 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010219 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010220 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10221
10222 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110223 TestCompletionCallback callback_3;
10224 rv = trans_2->RestartWithAuth(
10225 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010226 EXPECT_EQ(ERR_IO_PENDING, rv);
10227 EXPECT_EQ(OK, callback_3.WaitForResult());
10228
10229 // After all that work, these two lines (or actually, just the scheme) are
10230 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010231 EXPECT_EQ("https", request_url.scheme());
10232 EXPECT_EQ("www.google.com", request_url.host());
10233
[email protected]029c83b62013-01-24 05:28:2010234 LoadTimingInfo load_timing_info;
10235 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10236 TestLoadTimingNotReusedWithPac(load_timing_info,
10237 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810238}
10239
10240// Test that if we cancel the transaction as the connection is completing, that
10241// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210242TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810243 // Setup everything about the connection to complete synchronously, so that
10244 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10245 // for is the callback from the HttpStreamRequest.
10246 // Then cancel the transaction.
10247 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610248 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810249 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610250 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10251 MockRead(SYNCHRONOUS, "hello world"),
10252 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810253 };
10254
[email protected]8e6441ca2010-08-19 05:56:3810255 HttpRequestInfo request;
10256 request.method = "GET";
10257 request.url = GURL("http://www.google.com/");
10258 request.load_flags = 0;
10259
[email protected]bb88e1d32013-05-03 23:11:0710260 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710261 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710262 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0710263 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:2710264
[email protected]8e6441ca2010-08-19 05:56:3810265 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10266 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710267 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810268
[email protected]49639fa2011-12-20 23:22:4110269 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810270
[email protected]333bdf62012-06-08 22:57:2910271 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:4110272 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810273 EXPECT_EQ(ERR_IO_PENDING, rv);
10274 trans.reset(); // Cancel the transaction here.
10275
[email protected]2da659e2013-05-23 20:51:3410276 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010277}
10278
[email protected]ecab6e052014-05-16 14:58:1210279// Test that if a transaction is cancelled after receiving the headers, the
10280// stream is drained properly and added back to the socket pool. The main
10281// purpose of this test is to make sure that an HttpStreamParser can be read
10282// from after the HttpNetworkTransaction and the objects it owns have been
10283// deleted.
10284// See http://crbug.com/368418
10285TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10286 MockRead data_reads[] = {
10287 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10288 MockRead(ASYNC, "Content-Length: 2\r\n"),
10289 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10290 MockRead(ASYNC, "1"),
10291 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10292 // HttpNetworkTransaction has been deleted.
10293 MockRead(ASYNC, "2"),
10294 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10295 };
10296 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10297 session_deps_.socket_factory->AddSocketDataProvider(&data);
10298
10299 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10300
10301 {
10302 HttpRequestInfo request;
10303 request.method = "GET";
10304 request.url = GURL("http://www.google.com/");
10305 request.load_flags = 0;
10306
10307 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
10308 TestCompletionCallback callback;
10309
10310 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10311 EXPECT_EQ(ERR_IO_PENDING, rv);
10312 callback.WaitForResult();
10313
10314 const HttpResponseInfo* response = trans.GetResponseInfo();
10315 ASSERT_TRUE(response != NULL);
10316 EXPECT_TRUE(response->headers.get() != NULL);
10317 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10318
10319 // The transaction and HttpRequestInfo are deleted.
10320 }
10321
10322 // Let the HttpResponseBodyDrainer drain the socket.
10323 base::MessageLoop::current()->RunUntilIdle();
10324
10325 // Socket should now be idle, waiting to be reused.
10326 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
10327}
10328
[email protected]76a505b2010-08-25 06:23:0010329// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210330TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710331 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010332 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910333 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710334 session_deps_.net_log = log.bound().net_log();
10335 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010336
[email protected]76a505b2010-08-25 06:23:0010337 HttpRequestInfo request;
10338 request.method = "GET";
10339 request.url = GURL("http://www.google.com/");
10340
10341 MockWrite data_writes1[] = {
10342 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10343 "Host: www.google.com\r\n"
10344 "Proxy-Connection: keep-alive\r\n\r\n"),
10345 };
10346
10347 MockRead data_reads1[] = {
10348 MockRead("HTTP/1.1 200 OK\r\n"),
10349 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10350 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610351 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010352 };
10353
10354 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10355 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710356 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010357
[email protected]49639fa2011-12-20 23:22:4110358 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010359
[email protected]262eec82013-03-19 21:01:3610360 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010361 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710362 BeforeProxyHeadersSentHandler proxy_headers_handler;
10363 trans->SetBeforeProxyHeadersSentCallback(
10364 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10365 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010366
[email protected]49639fa2011-12-20 23:22:4110367 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010368 EXPECT_EQ(ERR_IO_PENDING, rv);
10369
10370 rv = callback1.WaitForResult();
10371 EXPECT_EQ(OK, rv);
10372
10373 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010374 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010375
10376 EXPECT_TRUE(response->headers->IsKeepAlive());
10377 EXPECT_EQ(200, response->headers->response_code());
10378 EXPECT_EQ(100, response->headers->GetContentLength());
10379 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510380 EXPECT_TRUE(
10381 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710382 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10383 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010384 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010385
10386 LoadTimingInfo load_timing_info;
10387 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10388 TestLoadTimingNotReusedWithPac(load_timing_info,
10389 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010390}
10391
10392// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210393TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710394 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010395 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910396 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710397 session_deps_.net_log = log.bound().net_log();
10398 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010399
[email protected]76a505b2010-08-25 06:23:0010400 HttpRequestInfo request;
10401 request.method = "GET";
10402 request.url = GURL("https://www.google.com/");
10403
10404 // Since we have proxy, should try to establish tunnel.
10405 MockWrite data_writes1[] = {
10406 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10407 "Host: www.google.com\r\n"
10408 "Proxy-Connection: keep-alive\r\n\r\n"),
10409
10410 MockWrite("GET / HTTP/1.1\r\n"
10411 "Host: www.google.com\r\n"
10412 "Connection: keep-alive\r\n\r\n"),
10413 };
10414
10415 MockRead data_reads1[] = {
10416 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10417
10418 MockRead("HTTP/1.1 200 OK\r\n"),
10419 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10420 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610421 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010422 };
10423
10424 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10425 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710426 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610427 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010429
[email protected]49639fa2011-12-20 23:22:4110430 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010431
[email protected]262eec82013-03-19 21:01:3610432 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010434
[email protected]49639fa2011-12-20 23:22:4110435 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010436 EXPECT_EQ(ERR_IO_PENDING, rv);
10437
10438 rv = callback1.WaitForResult();
10439 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710440 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010441 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010442 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010443 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010444 NetLog::PHASE_NONE);
10445 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010446 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010447 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10448 NetLog::PHASE_NONE);
10449
10450 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010451 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010452
10453 EXPECT_TRUE(response->headers->IsKeepAlive());
10454 EXPECT_EQ(200, response->headers->response_code());
10455 EXPECT_EQ(100, response->headers->GetContentLength());
10456 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10457 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510458 EXPECT_TRUE(
10459 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010460
10461 LoadTimingInfo load_timing_info;
10462 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10463 TestLoadTimingNotReusedWithPac(load_timing_info,
10464 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010465}
10466
10467// Test a basic HTTPS GET request through a proxy, but the server hangs up
10468// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210469TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710470 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910471 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710472 session_deps_.net_log = log.bound().net_log();
10473 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010474
[email protected]76a505b2010-08-25 06:23:0010475 HttpRequestInfo request;
10476 request.method = "GET";
10477 request.url = GURL("https://www.google.com/");
10478
10479 // Since we have proxy, should try to establish tunnel.
10480 MockWrite data_writes1[] = {
10481 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10482 "Host: www.google.com\r\n"
10483 "Proxy-Connection: keep-alive\r\n\r\n"),
10484
10485 MockWrite("GET / HTTP/1.1\r\n"
10486 "Host: www.google.com\r\n"
10487 "Connection: keep-alive\r\n\r\n"),
10488 };
10489
10490 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610491 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010492 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610493 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010494 };
10495
10496 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10497 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710498 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610499 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710500 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010501
[email protected]49639fa2011-12-20 23:22:4110502 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010503
[email protected]262eec82013-03-19 21:01:3610504 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010505 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010506
[email protected]49639fa2011-12-20 23:22:4110507 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010508 EXPECT_EQ(ERR_IO_PENDING, rv);
10509
10510 rv = callback1.WaitForResult();
10511 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710512 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010513 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010514 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010515 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010516 NetLog::PHASE_NONE);
10517 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010518 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010519 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10520 NetLog::PHASE_NONE);
10521}
10522
[email protected]749eefa82010-09-13 22:14:0310523// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210524TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610525 scoped_ptr<SpdyFrame> req(
10526 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310527 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10528
[email protected]23e482282013-06-14 16:08:0210529 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10530 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310531 MockRead spdy_reads[] = {
10532 CreateMockRead(*resp),
10533 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610534 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310535 };
10536
[email protected]dd54bd82012-07-19 23:44:5710537 DelayedSocketData spdy_data(
10538 1, // wait for one write to finish before reading.
10539 spdy_reads, arraysize(spdy_reads),
10540 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710541 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310542
[email protected]8ddf8322012-02-23 18:08:0610543 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210544 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710545 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310546
[email protected]bb88e1d32013-05-03 23:11:0710547 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310548
10549 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810550 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010551 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310552 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710553 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610554 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310555
10556 HttpRequestInfo request;
10557 request.method = "GET";
10558 request.url = GURL("https://www.google.com/");
10559 request.load_flags = 0;
10560
10561 // This is the important line that marks this as a preconnect.
10562 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10563
[email protected]262eec82013-03-19 21:01:3610564 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010565 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310566
[email protected]41d64e82013-07-03 22:44:2610567 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110568 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310569 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110570 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310571}
10572
[email protected]73b8dd222010-11-11 19:55:2410573// Given a net error, cause that error to be returned from the first Write()
10574// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210575void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710576 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710577 net::HttpRequestInfo request_info;
10578 request_info.url = GURL("https://www.example.com/");
10579 request_info.method = "GET";
10580 request_info.load_flags = net::LOAD_NORMAL;
10581
[email protected]8ddf8322012-02-23 18:08:0610582 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410583 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610584 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410585 };
10586 net::StaticSocketDataProvider data(NULL, 0,
10587 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710588 session_deps_.socket_factory->AddSocketDataProvider(&data);
10589 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410590
[email protected]bb88e1d32013-05-03 23:11:0710591 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610592 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410594
[email protected]49639fa2011-12-20 23:22:4110595 TestCompletionCallback callback;
10596 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410597 if (rv == net::ERR_IO_PENDING)
10598 rv = callback.WaitForResult();
10599 ASSERT_EQ(error, rv);
10600}
10601
[email protected]23e482282013-06-14 16:08:0210602TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410603 // Just check a grab bag of cert errors.
10604 static const int kErrors[] = {
10605 ERR_CERT_COMMON_NAME_INVALID,
10606 ERR_CERT_AUTHORITY_INVALID,
10607 ERR_CERT_DATE_INVALID,
10608 };
10609 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610610 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10611 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410612 }
10613}
10614
[email protected]bd0b6772011-01-11 19:59:3010615// Ensure that a client certificate is removed from the SSL client auth
10616// cache when:
10617// 1) No proxy is involved.
10618// 2) TLS False Start is disabled.
10619// 3) The initial TLS handshake requests a client certificate.
10620// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210621TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310622 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710623 net::HttpRequestInfo request_info;
10624 request_info.url = GURL("https://www.example.com/");
10625 request_info.method = "GET";
10626 request_info.load_flags = net::LOAD_NORMAL;
10627
[email protected]bd0b6772011-01-11 19:59:3010628 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110629 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010630
10631 // [ssl_]data1 contains the data for the first SSL handshake. When a
10632 // CertificateRequest is received for the first time, the handshake will
10633 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610634 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010635 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710636 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010637 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710638 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010639
10640 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10641 // False Start is not being used, the result of the SSL handshake will be
10642 // returned as part of the SSLClientSocket::Connect() call. This test
10643 // matches the result of a server sending a handshake_failure alert,
10644 // rather than a Finished message, because it requires a client
10645 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610646 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010647 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010649 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710650 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010651
10652 // [ssl_]data3 contains the data for the third SSL handshake. When a
10653 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710654 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10655 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010656 // of the HttpNetworkTransaction. Because this test failure is due to
10657 // requiring a client certificate, this fallback handshake should also
10658 // fail.
[email protected]8ddf8322012-02-23 18:08:0610659 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010660 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710661 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010662 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710663 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010664
[email protected]80c75f682012-05-26 16:22:1710665 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10666 // connection to a server fails during an SSL handshake,
10667 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10668 // connection was attempted with TLSv1. This is transparent to the caller
10669 // of the HttpNetworkTransaction. Because this test failure is due to
10670 // requiring a client certificate, this fallback handshake should also
10671 // fail.
10672 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10673 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710674 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710675 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710676 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710677
[email protected]7799de12013-05-30 05:52:5110678 // Need one more if TLSv1.2 is enabled.
10679 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10680 ssl_data5.cert_request_info = cert_request.get();
10681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10682 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10683 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10684
[email protected]bb88e1d32013-05-03 23:11:0710685 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610686 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010688
[email protected]bd0b6772011-01-11 19:59:3010689 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110690 TestCompletionCallback callback;
10691 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010692 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10693
10694 // Complete the SSL handshake, which should abort due to requiring a
10695 // client certificate.
10696 rv = callback.WaitForResult();
10697 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10698
10699 // Indicate that no certificate should be supplied. From the perspective
10700 // of SSLClientCertCache, NULL is just as meaningful as a real
10701 // certificate, so this is the same as supply a
10702 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110703 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010704 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10705
10706 // Ensure the certificate was added to the client auth cache before
10707 // allowing the connection to continue restarting.
10708 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110709 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10710 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010711 ASSERT_EQ(NULL, client_cert.get());
10712
10713 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710714 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10715 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010716 rv = callback.WaitForResult();
10717 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10718
10719 // Ensure that the client certificate is removed from the cache on a
10720 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110721 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10722 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010723}
10724
10725// Ensure that a client certificate is removed from the SSL client auth
10726// cache when:
10727// 1) No proxy is involved.
10728// 2) TLS False Start is enabled.
10729// 3) The initial TLS handshake requests a client certificate.
10730// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210731TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310732 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710733 net::HttpRequestInfo request_info;
10734 request_info.url = GURL("https://www.example.com/");
10735 request_info.method = "GET";
10736 request_info.load_flags = net::LOAD_NORMAL;
10737
[email protected]bd0b6772011-01-11 19:59:3010738 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110739 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010740
10741 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10742 // return successfully after reading up to the peer's Certificate message.
10743 // This is to allow the caller to call SSLClientSocket::Write(), which can
10744 // enqueue application data to be sent in the same packet as the
10745 // ChangeCipherSpec and Finished messages.
10746 // The actual handshake will be finished when SSLClientSocket::Read() is
10747 // called, which expects to process the peer's ChangeCipherSpec and
10748 // Finished messages. If there was an error negotiating with the peer,
10749 // such as due to the peer requiring a client certificate when none was
10750 // supplied, the alert sent by the peer won't be processed until Read() is
10751 // called.
10752
10753 // Like the non-False Start case, when a client certificate is requested by
10754 // the peer, the handshake is aborted during the Connect() call.
10755 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610756 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010757 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710758 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010759 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710760 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010761
10762 // When a client certificate is supplied, Connect() will not be aborted
10763 // when the peer requests the certificate. Instead, the handshake will
10764 // artificially succeed, allowing the caller to write the HTTP request to
10765 // the socket. The handshake messages are not processed until Read() is
10766 // called, which then detects that the handshake was aborted, due to the
10767 // peer sending a handshake_failure because it requires a client
10768 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610769 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010770 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710771 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010772 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610773 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010774 };
10775 net::StaticSocketDataProvider data2(
10776 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710777 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010778
10779 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710780 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10781 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610782 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010783 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710784 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010785 net::StaticSocketDataProvider data3(
10786 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710787 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010788
[email protected]80c75f682012-05-26 16:22:1710789 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10790 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10791 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10792 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710794 net::StaticSocketDataProvider data4(
10795 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710796 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710797
[email protected]7799de12013-05-30 05:52:5110798 // Need one more if TLSv1.2 is enabled.
10799 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10800 ssl_data5.cert_request_info = cert_request.get();
10801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10802 net::StaticSocketDataProvider data5(
10803 data2_reads, arraysize(data2_reads), NULL, 0);
10804 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10805
[email protected]bb88e1d32013-05-03 23:11:0710806 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610807 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010808 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010809
[email protected]bd0b6772011-01-11 19:59:3010810 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110811 TestCompletionCallback callback;
10812 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010813 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10814
10815 // Complete the SSL handshake, which should abort due to requiring a
10816 // client certificate.
10817 rv = callback.WaitForResult();
10818 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10819
10820 // Indicate that no certificate should be supplied. From the perspective
10821 // of SSLClientCertCache, NULL is just as meaningful as a real
10822 // certificate, so this is the same as supply a
10823 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110824 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010825 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10826
10827 // Ensure the certificate was added to the client auth cache before
10828 // allowing the connection to continue restarting.
10829 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110830 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10831 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010832 ASSERT_EQ(NULL, client_cert.get());
10833
[email protected]bd0b6772011-01-11 19:59:3010834 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710835 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10836 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010837 rv = callback.WaitForResult();
10838 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10839
10840 // Ensure that the client certificate is removed from the cache on a
10841 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110842 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10843 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010844}
10845
[email protected]8c405132011-01-11 22:03:1810846// Ensure that a client certificate is removed from the SSL client auth
10847// cache when:
10848// 1) An HTTPS proxy is involved.
10849// 3) The HTTPS proxy requests a client certificate.
10850// 4) The client supplies an invalid/unacceptable certificate for the
10851// proxy.
10852// The test is repeated twice, first for connecting to an HTTPS endpoint,
10853// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210854TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710855 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810856 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910857 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710858 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810859
10860 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110861 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1810862
10863 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10864 // [ssl_]data[1-3]. Rather than represending the endpoint
10865 // (www.example.com:443), they represent failures with the HTTPS proxy
10866 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610867 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810868 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710869 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810870 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710871 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810872
[email protected]8ddf8322012-02-23 18:08:0610873 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810874 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810876 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710877 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810878
[email protected]80c75f682012-05-26 16:22:1710879 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10880#if 0
[email protected]8ddf8322012-02-23 18:08:0610881 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810882 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710883 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810884 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710885 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710886#endif
[email protected]8c405132011-01-11 22:03:1810887
10888 net::HttpRequestInfo requests[2];
10889 requests[0].url = GURL("https://www.example.com/");
10890 requests[0].method = "GET";
10891 requests[0].load_flags = net::LOAD_NORMAL;
10892
10893 requests[1].url = GURL("http://www.example.com/");
10894 requests[1].method = "GET";
10895 requests[1].load_flags = net::LOAD_NORMAL;
10896
10897 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710898 session_deps_.socket_factory->ResetNextMockIndexes();
10899 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810900 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010901 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810902
10903 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110904 TestCompletionCallback callback;
10905 int rv = trans->Start(
10906 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810907 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10908
10909 // Complete the SSL handshake, which should abort due to requiring a
10910 // client certificate.
10911 rv = callback.WaitForResult();
10912 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10913
10914 // Indicate that no certificate should be supplied. From the perspective
10915 // of SSLClientCertCache, NULL is just as meaningful as a real
10916 // certificate, so this is the same as supply a
10917 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110918 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810919 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10920
10921 // Ensure the certificate was added to the client auth cache before
10922 // allowing the connection to continue restarting.
10923 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110924 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10925 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1810926 ASSERT_EQ(NULL, client_cert.get());
10927 // Ensure the certificate was NOT cached for the endpoint. This only
10928 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4110929 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10930 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810931
10932 // Restart the handshake. This will consume ssl_data2, which fails, and
10933 // then consume ssl_data3, which should also fail. The result code is
10934 // checked against what ssl_data3 should return.
10935 rv = callback.WaitForResult();
10936 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10937
10938 // Now that the new handshake has failed, ensure that the client
10939 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4110940 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10941 HostPortPair("proxy", 70), &client_cert));
10942 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10943 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810944 }
10945}
10946
[email protected]23e482282013-06-14 16:08:0210947// Unlike TEST/TEST_F, which are macros that expand to further macros,
10948// TEST_P is a macro that expands directly to code that stringizes the
10949// arguments. As a result, macros passed as parameters (such as prefix
10950// or test_case_name) will not be expanded by the preprocessor. To
10951// work around this, indirect the macro for TEST_P, so that the
10952// pre-processor will expand macros such as MAYBE_test_name before
10953// instantiating the test.
10954#define WRAPPED_TEST_P(test_case_name, test_name) \
10955 TEST_P(test_case_name, test_name)
10956
[email protected]45b170822012-05-04 21:18:1410957// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10958#if defined(OS_WIN)
10959#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10960#else
10961#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10962#endif
[email protected]23e482282013-06-14 16:08:0210963WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2310964 session_deps_.use_alternate_protocols = true;
10965 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4610966
10967 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710968 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10969 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610970 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10971 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610972
[email protected]8ddf8322012-02-23 18:08:0610973 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210974 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710975 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610976
[email protected]cdf8f7e72013-05-23 10:56:4610977 scoped_ptr<SpdyFrame> host1_req(
10978 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10979 scoped_ptr<SpdyFrame> host2_req(
10980 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610981 MockWrite spdy_writes[] = {
10982 CreateMockWrite(*host1_req, 1),
10983 CreateMockWrite(*host2_req, 4),
10984 };
[email protected]23e482282013-06-14 16:08:0210985 scoped_ptr<SpdyFrame> host1_resp(
10986 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10987 scoped_ptr<SpdyFrame> host1_resp_body(
10988 spdy_util_.ConstructSpdyBodyFrame(1, true));
10989 scoped_ptr<SpdyFrame> host2_resp(
10990 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10991 scoped_ptr<SpdyFrame> host2_resp_body(
10992 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610993 MockRead spdy_reads[] = {
10994 CreateMockRead(*host1_resp, 2),
10995 CreateMockRead(*host1_resp_body, 3),
10996 CreateMockRead(*host2_resp, 5),
10997 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610998 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610999 };
11000
[email protected]d2b5f092012-06-08 23:55:0211001 IPAddressNumber ip;
11002 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11003 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11004 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711005 OrderedSocketData spdy_data(
11006 connect,
11007 spdy_reads, arraysize(spdy_reads),
11008 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711009 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611010
[email protected]aa22b242011-11-16 18:58:2911011 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611012 HttpRequestInfo request1;
11013 request1.method = "GET";
11014 request1.url = GURL("https://www.google.com/");
11015 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011016 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611017
[email protected]49639fa2011-12-20 23:22:4111018 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611019 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111020 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611021
11022 const HttpResponseInfo* response = trans1.GetResponseInfo();
11023 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011024 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611025 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11026
11027 std::string response_data;
11028 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11029 EXPECT_EQ("hello!", response_data);
11030
11031 // Preload www.gmail.com into HostCache.
11032 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011033 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611034 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011035 rv = session_deps_.host_resolver->Resolve(resolve_info,
11036 DEFAULT_PRIORITY,
11037 &ignored,
11038 callback.callback(),
11039 NULL,
11040 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711041 EXPECT_EQ(ERR_IO_PENDING, rv);
11042 rv = callback.WaitForResult();
11043 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611044
11045 HttpRequestInfo request2;
11046 request2.method = "GET";
11047 request2.url = GURL("https://www.gmail.com/");
11048 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011049 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611050
[email protected]49639fa2011-12-20 23:22:4111051 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611052 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111053 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611054
11055 response = trans2.GetResponseInfo();
11056 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011057 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611058 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11059 EXPECT_TRUE(response->was_fetched_via_spdy);
11060 EXPECT_TRUE(response->was_npn_negotiated);
11061 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11062 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611063}
[email protected]45b170822012-05-04 21:18:1411064#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4611065
[email protected]23e482282013-06-14 16:08:0211066TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311067 session_deps_.use_alternate_protocols = true;
11068 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211069
11070 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711071 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11072 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211073 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11074 pool_peer.DisableDomainAuthenticationVerification();
11075
11076 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211077 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711078 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211079
[email protected]cdf8f7e72013-05-23 10:56:4611080 scoped_ptr<SpdyFrame> host1_req(
11081 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11082 scoped_ptr<SpdyFrame> host2_req(
11083 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211084 MockWrite spdy_writes[] = {
11085 CreateMockWrite(*host1_req, 1),
11086 CreateMockWrite(*host2_req, 4),
11087 };
[email protected]23e482282013-06-14 16:08:0211088 scoped_ptr<SpdyFrame> host1_resp(
11089 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11090 scoped_ptr<SpdyFrame> host1_resp_body(
11091 spdy_util_.ConstructSpdyBodyFrame(1, true));
11092 scoped_ptr<SpdyFrame> host2_resp(
11093 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11094 scoped_ptr<SpdyFrame> host2_resp_body(
11095 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211096 MockRead spdy_reads[] = {
11097 CreateMockRead(*host1_resp, 2),
11098 CreateMockRead(*host1_resp_body, 3),
11099 CreateMockRead(*host2_resp, 5),
11100 CreateMockRead(*host2_resp_body, 6),
11101 MockRead(ASYNC, 0, 7),
11102 };
11103
11104 IPAddressNumber ip;
11105 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11106 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11107 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711108 OrderedSocketData spdy_data(
11109 connect,
11110 spdy_reads, arraysize(spdy_reads),
11111 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711112 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211113
11114 TestCompletionCallback callback;
11115 HttpRequestInfo request1;
11116 request1.method = "GET";
11117 request1.url = GURL("https://www.google.com/");
11118 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011119 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211120
11121 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11122 EXPECT_EQ(ERR_IO_PENDING, rv);
11123 EXPECT_EQ(OK, callback.WaitForResult());
11124
11125 const HttpResponseInfo* response = trans1.GetResponseInfo();
11126 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011127 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211128 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11129
11130 std::string response_data;
11131 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11132 EXPECT_EQ("hello!", response_data);
11133
11134 HttpRequestInfo request2;
11135 request2.method = "GET";
11136 request2.url = GURL("https://www.gmail.com/");
11137 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011138 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211139
11140 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11141 EXPECT_EQ(ERR_IO_PENDING, rv);
11142 EXPECT_EQ(OK, callback.WaitForResult());
11143
11144 response = trans2.GetResponseInfo();
11145 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011146 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211147 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11148 EXPECT_TRUE(response->was_fetched_via_spdy);
11149 EXPECT_TRUE(response->was_npn_negotiated);
11150 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11151 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211152}
11153
[email protected]e3ceb682011-06-28 23:55:4611154class OneTimeCachingHostResolver : public net::HostResolver {
11155 public:
11156 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11157 : host_port_(host_port) {}
11158 virtual ~OneTimeCachingHostResolver() {}
11159
11160 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11161
11162 // HostResolver methods:
11163 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1011164 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4611165 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2911166 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4611167 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4011168 const BoundNetLog& net_log) OVERRIDE {
11169 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011170 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011171 }
11172
11173 virtual int ResolveFromCache(const RequestInfo& info,
11174 AddressList* addresses,
11175 const BoundNetLog& net_log) OVERRIDE {
11176 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11177 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911178 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611179 return rv;
11180 }
11181
[email protected]95a214c2011-08-04 21:50:4011182 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4611183 host_resolver_.CancelRequest(req);
11184 }
11185
[email protected]46da33be2011-07-19 21:58:0411186 MockCachingHostResolver* GetMockHostResolver() {
11187 return &host_resolver_;
11188 }
11189
[email protected]e3ceb682011-06-28 23:55:4611190 private:
11191 MockCachingHostResolver host_resolver_;
11192 const HostPortPair host_port_;
11193};
11194
[email protected]45b170822012-05-04 21:18:1411195// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11196#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711197#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11198 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411199#else
[email protected]bb88e1d32013-05-03 23:11:0711200#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11201 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411202#endif
[email protected]23e482282013-06-14 16:08:0211203WRAPPED_TEST_P(HttpNetworkTransactionTest,
11204 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211205// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11206// prefix doesn't work with parametrized tests).
11207#if defined(OS_WIN)
11208 return;
[email protected]88c7b4be2014-03-19 23:04:0111209#else
[email protected]d7599122014-05-24 03:37:2311210 session_deps_.use_alternate_protocols = true;
11211 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611212
11213 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611214 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411215 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711216 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611217 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611219 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11220 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611221
[email protected]8ddf8322012-02-23 18:08:0611222 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211223 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611225
[email protected]cdf8f7e72013-05-23 10:56:4611226 scoped_ptr<SpdyFrame> host1_req(
11227 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11228 scoped_ptr<SpdyFrame> host2_req(
11229 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611230 MockWrite spdy_writes[] = {
11231 CreateMockWrite(*host1_req, 1),
11232 CreateMockWrite(*host2_req, 4),
11233 };
[email protected]23e482282013-06-14 16:08:0211234 scoped_ptr<SpdyFrame> host1_resp(
11235 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11236 scoped_ptr<SpdyFrame> host1_resp_body(
11237 spdy_util_.ConstructSpdyBodyFrame(1, true));
11238 scoped_ptr<SpdyFrame> host2_resp(
11239 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11240 scoped_ptr<SpdyFrame> host2_resp_body(
11241 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611242 MockRead spdy_reads[] = {
11243 CreateMockRead(*host1_resp, 2),
11244 CreateMockRead(*host1_resp_body, 3),
11245 CreateMockRead(*host2_resp, 5),
11246 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611247 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611248 };
11249
[email protected]d2b5f092012-06-08 23:55:0211250 IPAddressNumber ip;
11251 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11252 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11253 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711254 OrderedSocketData spdy_data(
11255 connect,
11256 spdy_reads, arraysize(spdy_reads),
11257 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711258 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611259
[email protected]aa22b242011-11-16 18:58:2911260 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611261 HttpRequestInfo request1;
11262 request1.method = "GET";
11263 request1.url = GURL("https://www.google.com/");
11264 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011265 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611266
[email protected]49639fa2011-12-20 23:22:4111267 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611268 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111269 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611270
11271 const HttpResponseInfo* response = trans1.GetResponseInfo();
11272 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011273 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611274 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11275
11276 std::string response_data;
11277 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11278 EXPECT_EQ("hello!", response_data);
11279
11280 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011281 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611282 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011283 rv = host_resolver.Resolve(resolve_info,
11284 DEFAULT_PRIORITY,
11285 &ignored,
11286 callback.callback(),
11287 NULL,
11288 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711289 EXPECT_EQ(ERR_IO_PENDING, rv);
11290 rv = callback.WaitForResult();
11291 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611292
11293 HttpRequestInfo request2;
11294 request2.method = "GET";
11295 request2.url = GURL("https://www.gmail.com/");
11296 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011297 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611298
[email protected]49639fa2011-12-20 23:22:4111299 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611300 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111301 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611302
11303 response = trans2.GetResponseInfo();
11304 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011305 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611306 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11307 EXPECT_TRUE(response->was_fetched_via_spdy);
11308 EXPECT_TRUE(response->was_npn_negotiated);
11309 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11310 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111311#endif
[email protected]e3ceb682011-06-28 23:55:4611312}
[email protected]45b170822012-05-04 21:18:1411313#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611314
[email protected]23e482282013-06-14 16:08:0211315TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0411316 const std::string https_url = "https://www.google.com/";
11317 const std::string http_url = "http://www.google.com:443/";
11318
11319 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611320 scoped_ptr<SpdyFrame> req1(
11321 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411322
11323 MockWrite writes1[] = {
11324 CreateMockWrite(*req1, 0),
11325 };
11326
[email protected]23e482282013-06-14 16:08:0211327 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11328 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411329 MockRead reads1[] = {
11330 CreateMockRead(*resp1, 1),
11331 CreateMockRead(*body1, 2),
11332 MockRead(ASYNC, ERR_IO_PENDING, 3)
11333 };
11334
[email protected]dd54bd82012-07-19 23:44:5711335 DelayedSocketData data1(
11336 1, reads1, arraysize(reads1),
11337 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411338 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711339 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411340
11341 // HTTP GET for the HTTP URL
11342 MockWrite writes2[] = {
11343 MockWrite(ASYNC, 4,
11344 "GET / HTTP/1.1\r\n"
11345 "Host: www.google.com:443\r\n"
11346 "Connection: keep-alive\r\n\r\n"),
11347 };
11348
11349 MockRead reads2[] = {
11350 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11351 MockRead(ASYNC, 6, "hello"),
11352 MockRead(ASYNC, 7, OK),
11353 };
11354
[email protected]dd54bd82012-07-19 23:44:5711355 DelayedSocketData data2(
11356 1, reads2, arraysize(reads2),
11357 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411358
[email protected]8450d722012-07-02 19:14:0411359 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211360 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711361 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11362 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11363 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411364
[email protected]bb88e1d32013-05-03 23:11:0711365 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411366
11367 // Start the first transaction to set up the SpdySession
11368 HttpRequestInfo request1;
11369 request1.method = "GET";
11370 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411371 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011372 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411373 TestCompletionCallback callback1;
11374 EXPECT_EQ(ERR_IO_PENDING,
11375 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411376 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411377
11378 EXPECT_EQ(OK, callback1.WaitForResult());
11379 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11380
11381 // Now, start the HTTP request
11382 HttpRequestInfo request2;
11383 request2.method = "GET";
11384 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411385 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011386 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411387 TestCompletionCallback callback2;
11388 EXPECT_EQ(ERR_IO_PENDING,
11389 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411390 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411391
11392 EXPECT_EQ(OK, callback2.WaitForResult());
11393 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11394}
11395
[email protected]23e482282013-06-14 16:08:0211396TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0411397 const std::string https_url = "https://www.google.com/";
11398 const std::string http_url = "http://www.google.com:443/";
11399
11400 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5411401 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11402 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611403 scoped_ptr<SpdyFrame> req1(
11404 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0211405 scoped_ptr<SpdyFrame> wrapped_req1(
11406 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3911407
11408 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2911409 SpdyHeaderBlock req2_block;
11410 req2_block[spdy_util_.GetMethodKey()] = "GET";
11411 req2_block[spdy_util_.GetPathKey()] =
11412 spdy_util_.is_spdy2() ? http_url.c_str() : "/";
11413 req2_block[spdy_util_.GetHostKey()] = "www.google.com:443";
11414 req2_block[spdy_util_.GetSchemeKey()] = "http";
11415 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3911416 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2911417 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0411418
11419 MockWrite writes1[] = {
11420 CreateMockWrite(*connect, 0),
11421 CreateMockWrite(*wrapped_req1, 2),
11422 CreateMockWrite(*req2, 5),
11423 };
11424
[email protected]23e482282013-06-14 16:08:0211425 scoped_ptr<SpdyFrame> conn_resp(
11426 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11427 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11428 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11429 scoped_ptr<SpdyFrame> wrapped_resp1(
11430 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11431 scoped_ptr<SpdyFrame> wrapped_body1(
11432 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11433 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11434 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411435 MockRead reads1[] = {
11436 CreateMockRead(*conn_resp, 1),
11437 CreateMockRead(*wrapped_resp1, 3),
11438 CreateMockRead(*wrapped_body1, 4),
11439 CreateMockRead(*resp2, 6),
11440 CreateMockRead(*body2, 7),
11441 MockRead(ASYNC, ERR_IO_PENDING, 8)
11442 };
11443
[email protected]dd54bd82012-07-19 23:44:5711444 DeterministicSocketData data1(reads1, arraysize(reads1),
11445 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411446 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711447 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411448
[email protected]bb88e1d32013-05-03 23:11:0711449 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211450 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11451 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711452 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411453 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211454 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711455 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411456 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211457 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711458 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11459 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411460
11461 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711462 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411463
11464 // Start the first transaction to set up the SpdySession
11465 HttpRequestInfo request1;
11466 request1.method = "GET";
11467 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411468 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011469 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411470 TestCompletionCallback callback1;
11471 EXPECT_EQ(ERR_IO_PENDING,
11472 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411473 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711474 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411475
11476 EXPECT_EQ(OK, callback1.WaitForResult());
11477 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11478
[email protected]f6c63db52013-02-02 00:35:2211479 LoadTimingInfo load_timing_info1;
11480 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11481 TestLoadTimingNotReusedWithPac(load_timing_info1,
11482 CONNECT_TIMING_HAS_SSL_TIMES);
11483
[email protected]8450d722012-07-02 19:14:0411484 // Now, start the HTTP request
11485 HttpRequestInfo request2;
11486 request2.method = "GET";
11487 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411488 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011489 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411490 TestCompletionCallback callback2;
11491 EXPECT_EQ(ERR_IO_PENDING,
11492 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411493 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711494 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411495
11496 EXPECT_EQ(OK, callback2.WaitForResult());
11497 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211498
11499 LoadTimingInfo load_timing_info2;
11500 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11501 // The established SPDY sessions is considered reused by the HTTP request.
11502 TestLoadTimingReusedWithPac(load_timing_info2);
11503 // HTTP requests over a SPDY session should have a different connection
11504 // socket_log_id than requests over a tunnel.
11505 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411506}
11507
[email protected]23e482282013-06-14 16:08:0211508TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]d7599122014-05-24 03:37:2311509 session_deps_.force_spdy_always = true;
[email protected]8450d722012-07-02 19:14:0411510 const std::string https_url = "https://www.google.com/";
11511 const std::string http_url = "http://www.google.com:443/";
11512
11513 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611514 scoped_ptr<SpdyFrame> req1(
11515 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411516 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611517 scoped_ptr<SpdyFrame> req2(
11518 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411519
11520 MockWrite writes[] = {
11521 CreateMockWrite(*req1, 1),
11522 CreateMockWrite(*req2, 4),
11523 };
11524
[email protected]23e482282013-06-14 16:08:0211525 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11526 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11527 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11528 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411529 MockRead reads[] = {
11530 CreateMockRead(*resp1, 2),
11531 CreateMockRead(*body1, 3),
11532 CreateMockRead(*resp2, 5),
11533 CreateMockRead(*body2, 6),
11534 MockRead(ASYNC, ERR_IO_PENDING, 7)
11535 };
11536
[email protected]dd54bd82012-07-19 23:44:5711537 OrderedSocketData data(reads, arraysize(reads),
11538 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411539
[email protected]8450d722012-07-02 19:14:0411540 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211541 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711542 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11543 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411544
[email protected]bb88e1d32013-05-03 23:11:0711545 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411546
11547 // Start the first transaction to set up the SpdySession
11548 HttpRequestInfo request1;
11549 request1.method = "GET";
11550 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411551 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011552 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411553 TestCompletionCallback callback1;
11554 EXPECT_EQ(ERR_IO_PENDING,
11555 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411556 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411557
11558 EXPECT_EQ(OK, callback1.WaitForResult());
11559 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11560
11561 // Now, start the HTTP request
11562 HttpRequestInfo request2;
11563 request2.method = "GET";
11564 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411565 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011566 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411567 TestCompletionCallback callback2;
11568 EXPECT_EQ(ERR_IO_PENDING,
11569 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411570 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411571
11572 EXPECT_EQ(OK, callback2.WaitForResult());
11573 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11574}
11575
[email protected]2d88e7d2012-07-19 17:55:1711576// Test that in the case where we have a SPDY session to a SPDY proxy
11577// that we do not pool other origins that resolve to the same IP when
11578// the certificate does not match the new origin.
11579// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211580TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711581 const std::string url1 = "http://www.google.com/";
11582 const std::string url2 = "https://mail.google.com/";
11583 const std::string ip_addr = "1.2.3.4";
11584
11585 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211586 scoped_ptr<SpdyHeaderBlock> headers(
11587 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:2911588 scoped_ptr<SpdyFrame> req1(
11589 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1711590
11591 MockWrite writes1[] = {
11592 CreateMockWrite(*req1, 0),
11593 };
11594
[email protected]23e482282013-06-14 16:08:0211595 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11596 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711597 MockRead reads1[] = {
11598 CreateMockRead(*resp1, 1),
11599 CreateMockRead(*body1, 2),
11600 MockRead(ASYNC, OK, 3) // EOF
11601 };
11602
11603 scoped_ptr<DeterministicSocketData> data1(
11604 new DeterministicSocketData(reads1, arraysize(reads1),
11605 writes1, arraysize(writes1)));
11606 IPAddressNumber ip;
11607 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11608 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11609 MockConnect connect_data1(ASYNC, OK, peer_addr);
11610 data1->set_connect_data(connect_data1);
11611
11612 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611613 scoped_ptr<SpdyFrame> req2(
11614 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711615
11616 MockWrite writes2[] = {
11617 CreateMockWrite(*req2, 0),
11618 };
11619
[email protected]23e482282013-06-14 16:08:0211620 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11621 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711622 MockRead reads2[] = {
11623 CreateMockRead(*resp2, 1),
11624 CreateMockRead(*body2, 2),
11625 MockRead(ASYNC, OK, 3) // EOF
11626 };
11627
11628 scoped_ptr<DeterministicSocketData> data2(
11629 new DeterministicSocketData(reads2, arraysize(reads2),
11630 writes2, arraysize(writes2)));
11631 MockConnect connect_data2(ASYNC, OK);
11632 data2->set_connect_data(connect_data2);
11633
11634 // Set up a proxy config that sends HTTP requests to a proxy, and
11635 // all others direct.
11636 ProxyConfig proxy_config;
11637 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11638 CapturingProxyResolver* capturing_proxy_resolver =
11639 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711640 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711641 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11642 NULL));
11643
11644 // Load a valid cert. Note, that this does not need to
11645 // be valid for proxy because the MockSSLClientSocket does
11646 // not actually verify it. But SpdySession will use this
11647 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511648 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711649 scoped_refptr<X509Certificate> server_cert(
11650 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11651 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11652
11653 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211654 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711655 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711656 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11657 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11658 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711659
11660 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211661 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711662 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11663 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11664 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711665
[email protected]bb88e1d32013-05-03 23:11:0711666 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11667 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11668 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711669
11670 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711671 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711672
11673 // Start the first transaction to set up the SpdySession
11674 HttpRequestInfo request1;
11675 request1.method = "GET";
11676 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711677 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011678 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711679 TestCompletionCallback callback1;
11680 ASSERT_EQ(ERR_IO_PENDING,
11681 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11682 data1->RunFor(3);
11683
11684 ASSERT_TRUE(callback1.have_result());
11685 EXPECT_EQ(OK, callback1.WaitForResult());
11686 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11687
11688 // Now, start the HTTP request
11689 HttpRequestInfo request2;
11690 request2.method = "GET";
11691 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711692 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011693 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711694 TestCompletionCallback callback2;
11695 EXPECT_EQ(ERR_IO_PENDING,
11696 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411697 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711698 data2->RunFor(3);
11699
11700 ASSERT_TRUE(callback2.have_result());
11701 EXPECT_EQ(OK, callback2.WaitForResult());
11702 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11703}
11704
[email protected]85f97342013-04-17 06:12:2411705// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11706// error) in SPDY session, removes the socket from pool and closes the SPDY
11707// session. Verify that new url's from the same HttpNetworkSession (and a new
11708// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211709TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411710 const std::string https_url = "https://www.google.com/";
11711
11712 MockRead reads1[] = {
11713 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11714 };
11715
11716 scoped_ptr<DeterministicSocketData> data1(
11717 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11718 data1->SetStop(1);
11719
[email protected]cdf8f7e72013-05-23 10:56:4611720 scoped_ptr<SpdyFrame> req2(
11721 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411722 MockWrite writes2[] = {
11723 CreateMockWrite(*req2, 0),
11724 };
11725
[email protected]23e482282013-06-14 16:08:0211726 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11727 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411728 MockRead reads2[] = {
11729 CreateMockRead(*resp2, 1),
11730 CreateMockRead(*body2, 2),
11731 MockRead(ASYNC, OK, 3) // EOF
11732 };
11733
11734 scoped_ptr<DeterministicSocketData> data2(
11735 new DeterministicSocketData(reads2, arraysize(reads2),
11736 writes2, arraysize(writes2)));
11737
[email protected]85f97342013-04-17 06:12:2411738 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211739 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711740 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11741 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11742 data1.get());
[email protected]85f97342013-04-17 06:12:2411743
11744 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211745 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711746 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11747 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11748 data2.get());
[email protected]85f97342013-04-17 06:12:2411749
11750 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711751 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411752
11753 // Start the first transaction to set up the SpdySession and verify that
11754 // connection was closed.
11755 HttpRequestInfo request1;
11756 request1.method = "GET";
11757 request1.url = GURL(https_url);
11758 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011759 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411760 TestCompletionCallback callback1;
11761 EXPECT_EQ(ERR_IO_PENDING,
11762 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411763 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411764 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11765
11766 // Now, start the second request and make sure it succeeds.
11767 HttpRequestInfo request2;
11768 request2.method = "GET";
11769 request2.url = GURL(https_url);
11770 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011771 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411772 TestCompletionCallback callback2;
11773 EXPECT_EQ(ERR_IO_PENDING,
11774 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411775 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411776 data2->RunFor(3);
11777
11778 ASSERT_TRUE(callback2.have_result());
11779 EXPECT_EQ(OK, callback2.WaitForResult());
11780 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11781}
11782
[email protected]23e482282013-06-14 16:08:0211783TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2311784 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0311785 ClientSocketPoolManager::set_max_sockets_per_group(
11786 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11787 ClientSocketPoolManager::set_max_sockets_per_pool(
11788 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11789
11790 // Use two different hosts with different IPs so they don't get pooled.
11791 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11792 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11793 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11794
11795 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211796 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311797 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211798 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311799 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11800 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11801
[email protected]cdf8f7e72013-05-23 10:56:4611802 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311803 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11804 MockWrite spdy1_writes[] = {
11805 CreateMockWrite(*host1_req, 1),
11806 };
[email protected]23e482282013-06-14 16:08:0211807 scoped_ptr<SpdyFrame> host1_resp(
11808 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11809 scoped_ptr<SpdyFrame> host1_resp_body(
11810 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311811 MockRead spdy1_reads[] = {
11812 CreateMockRead(*host1_resp, 2),
11813 CreateMockRead(*host1_resp_body, 3),
11814 MockRead(ASYNC, ERR_IO_PENDING, 4),
11815 };
11816
11817 scoped_ptr<OrderedSocketData> spdy1_data(
11818 new OrderedSocketData(
11819 spdy1_reads, arraysize(spdy1_reads),
11820 spdy1_writes, arraysize(spdy1_writes)));
11821 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11822
[email protected]cdf8f7e72013-05-23 10:56:4611823 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311824 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11825 MockWrite spdy2_writes[] = {
11826 CreateMockWrite(*host2_req, 1),
11827 };
[email protected]23e482282013-06-14 16:08:0211828 scoped_ptr<SpdyFrame> host2_resp(
11829 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11830 scoped_ptr<SpdyFrame> host2_resp_body(
11831 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311832 MockRead spdy2_reads[] = {
11833 CreateMockRead(*host2_resp, 2),
11834 CreateMockRead(*host2_resp_body, 3),
11835 MockRead(ASYNC, ERR_IO_PENDING, 4),
11836 };
11837
11838 scoped_ptr<OrderedSocketData> spdy2_data(
11839 new OrderedSocketData(
11840 spdy2_reads, arraysize(spdy2_reads),
11841 spdy2_writes, arraysize(spdy2_writes)));
11842 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11843
11844 MockWrite http_write[] = {
11845 MockWrite("GET / HTTP/1.1\r\n"
11846 "Host: www.a.com\r\n"
11847 "Connection: keep-alive\r\n\r\n"),
11848 };
11849
11850 MockRead http_read[] = {
11851 MockRead("HTTP/1.1 200 OK\r\n"),
11852 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11853 MockRead("Content-Length: 6\r\n\r\n"),
11854 MockRead("hello!"),
11855 };
11856 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11857 http_write, arraysize(http_write));
11858 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11859
11860 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011861 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5311862 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311863 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611864 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311865
11866 TestCompletionCallback callback;
11867 HttpRequestInfo request1;
11868 request1.method = "GET";
11869 request1.url = GURL("https://www.a.com/");
11870 request1.load_flags = 0;
11871 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011872 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311873
11874 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11875 EXPECT_EQ(ERR_IO_PENDING, rv);
11876 EXPECT_EQ(OK, callback.WaitForResult());
11877
11878 const HttpResponseInfo* response = trans->GetResponseInfo();
11879 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011880 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311881 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11882 EXPECT_TRUE(response->was_fetched_via_spdy);
11883 EXPECT_TRUE(response->was_npn_negotiated);
11884
11885 std::string response_data;
11886 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11887 EXPECT_EQ("hello!", response_data);
11888 trans.reset();
11889 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611890 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311891
11892 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011893 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5311894 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311895 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611896 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311897 HttpRequestInfo request2;
11898 request2.method = "GET";
11899 request2.url = GURL("https://www.b.com/");
11900 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011901 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311902
11903 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11904 EXPECT_EQ(ERR_IO_PENDING, rv);
11905 EXPECT_EQ(OK, callback.WaitForResult());
11906
11907 response = trans->GetResponseInfo();
11908 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011909 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311910 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11911 EXPECT_TRUE(response->was_fetched_via_spdy);
11912 EXPECT_TRUE(response->was_npn_negotiated);
11913 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11914 EXPECT_EQ("hello!", response_data);
11915 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611916 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311917 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611918 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311919
11920 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011921 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5311922 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311923 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611924 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311925 HttpRequestInfo request3;
11926 request3.method = "GET";
11927 request3.url = GURL("http://www.a.com/");
11928 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011929 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311930
11931 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11932 EXPECT_EQ(ERR_IO_PENDING, rv);
11933 EXPECT_EQ(OK, callback.WaitForResult());
11934
11935 response = trans->GetResponseInfo();
11936 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011937 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311938 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11939 EXPECT_FALSE(response->was_fetched_via_spdy);
11940 EXPECT_FALSE(response->was_npn_negotiated);
11941 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11942 EXPECT_EQ("hello!", response_data);
11943 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611944 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311945 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611946 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311947}
11948
[email protected]79e1fd62013-06-20 06:50:0411949TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11950 HttpRequestInfo request;
11951 request.method = "GET";
11952 request.url = GURL("http://www.google.com/");
11953 request.load_flags = 0;
11954
[email protected]3fe8d2f82013-10-17 08:56:0711955 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411956 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711957 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411958
11959 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11960 StaticSocketDataProvider data;
11961 data.set_connect_data(mock_connect);
11962 session_deps_.socket_factory->AddSocketDataProvider(&data);
11963
11964 TestCompletionCallback callback;
11965
11966 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11967 EXPECT_EQ(ERR_IO_PENDING, rv);
11968
11969 rv = callback.WaitForResult();
11970 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11971
11972 EXPECT_EQ(NULL, trans->GetResponseInfo());
11973
11974 // We don't care whether this succeeds or fails, but it shouldn't crash.
11975 HttpRequestHeaders request_headers;
11976 trans->GetFullRequestHeaders(&request_headers);
11977}
11978
11979TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11980 HttpRequestInfo request;
11981 request.method = "GET";
11982 request.url = GURL("http://www.google.com/");
11983 request.load_flags = 0;
11984
[email protected]3fe8d2f82013-10-17 08:56:0711985 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411986 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711987 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411988
11989 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11990 StaticSocketDataProvider data;
11991 data.set_connect_data(mock_connect);
11992 session_deps_.socket_factory->AddSocketDataProvider(&data);
11993
11994 TestCompletionCallback callback;
11995
11996 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11997 EXPECT_EQ(ERR_IO_PENDING, rv);
11998
11999 rv = callback.WaitForResult();
12000 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12001
12002 EXPECT_EQ(NULL, trans->GetResponseInfo());
12003
12004 // We don't care whether this succeeds or fails, but it shouldn't crash.
12005 HttpRequestHeaders request_headers;
12006 trans->GetFullRequestHeaders(&request_headers);
12007}
12008
12009TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12010 HttpRequestInfo request;
12011 request.method = "GET";
12012 request.url = GURL("http://www.google.com/");
12013 request.load_flags = 0;
12014
[email protected]3fe8d2f82013-10-17 08:56:0712015 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412016 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712017 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412018
12019 MockWrite data_writes[] = {
12020 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12021 };
12022 MockRead data_reads[] = {
12023 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12024 };
12025
12026 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12027 data_writes, arraysize(data_writes));
12028 session_deps_.socket_factory->AddSocketDataProvider(&data);
12029
12030 TestCompletionCallback callback;
12031
12032 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12033 EXPECT_EQ(ERR_IO_PENDING, rv);
12034
12035 rv = callback.WaitForResult();
12036 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12037
12038 EXPECT_EQ(NULL, trans->GetResponseInfo());
12039
12040 HttpRequestHeaders request_headers;
12041 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12042 EXPECT_TRUE(request_headers.HasHeader("Host"));
12043}
12044
12045TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12046 HttpRequestInfo request;
12047 request.method = "GET";
12048 request.url = GURL("http://www.google.com/");
12049 request.load_flags = 0;
12050
[email protected]3fe8d2f82013-10-17 08:56:0712051 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412052 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712053 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412054
12055 MockWrite data_writes[] = {
12056 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12057 };
12058 MockRead data_reads[] = {
12059 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12060 };
12061
12062 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12063 data_writes, arraysize(data_writes));
12064 session_deps_.socket_factory->AddSocketDataProvider(&data);
12065
12066 TestCompletionCallback callback;
12067
12068 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12069 EXPECT_EQ(ERR_IO_PENDING, rv);
12070
12071 rv = callback.WaitForResult();
12072 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12073
12074 EXPECT_EQ(NULL, trans->GetResponseInfo());
12075
12076 HttpRequestHeaders request_headers;
12077 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12078 EXPECT_TRUE(request_headers.HasHeader("Host"));
12079}
12080
12081TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12082 HttpRequestInfo request;
12083 request.method = "GET";
12084 request.url = GURL("http://www.google.com/");
12085 request.load_flags = 0;
12086
[email protected]3fe8d2f82013-10-17 08:56:0712087 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412088 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712089 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412090
12091 MockWrite data_writes[] = {
12092 MockWrite("GET / HTTP/1.1\r\n"
12093 "Host: www.google.com\r\n"
12094 "Connection: keep-alive\r\n\r\n"),
12095 };
12096 MockRead data_reads[] = {
12097 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12098 };
12099
12100 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12101 data_writes, arraysize(data_writes));
12102 session_deps_.socket_factory->AddSocketDataProvider(&data);
12103
12104 TestCompletionCallback callback;
12105
12106 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12107 EXPECT_EQ(ERR_IO_PENDING, rv);
12108
12109 rv = callback.WaitForResult();
12110 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12111
12112 EXPECT_EQ(NULL, trans->GetResponseInfo());
12113
12114 HttpRequestHeaders request_headers;
12115 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12116 EXPECT_TRUE(request_headers.HasHeader("Host"));
12117}
12118
12119TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12120 HttpRequestInfo request;
12121 request.method = "GET";
12122 request.url = GURL("http://www.google.com/");
12123 request.load_flags = 0;
12124
[email protected]3fe8d2f82013-10-17 08:56:0712125 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412126 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712127 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412128
12129 MockWrite data_writes[] = {
12130 MockWrite("GET / HTTP/1.1\r\n"
12131 "Host: www.google.com\r\n"
12132 "Connection: keep-alive\r\n\r\n"),
12133 };
12134 MockRead data_reads[] = {
12135 MockRead(ASYNC, ERR_CONNECTION_RESET),
12136 };
12137
12138 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12139 data_writes, arraysize(data_writes));
12140 session_deps_.socket_factory->AddSocketDataProvider(&data);
12141
12142 TestCompletionCallback callback;
12143
12144 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12145 EXPECT_EQ(ERR_IO_PENDING, rv);
12146
12147 rv = callback.WaitForResult();
12148 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12149
12150 EXPECT_EQ(NULL, trans->GetResponseInfo());
12151
12152 HttpRequestHeaders request_headers;
12153 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12154 EXPECT_TRUE(request_headers.HasHeader("Host"));
12155}
12156
12157TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12158 HttpRequestInfo request;
12159 request.method = "GET";
12160 request.url = GURL("http://www.google.com/");
12161 request.load_flags = 0;
12162 request.extra_headers.SetHeader("X-Foo", "bar");
12163
[email protected]3fe8d2f82013-10-17 08:56:0712164 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412165 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712166 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412167
12168 MockWrite data_writes[] = {
12169 MockWrite("GET / HTTP/1.1\r\n"
12170 "Host: www.google.com\r\n"
12171 "Connection: keep-alive\r\n"
12172 "X-Foo: bar\r\n\r\n"),
12173 };
12174 MockRead data_reads[] = {
12175 MockRead("HTTP/1.1 200 OK\r\n"
12176 "Content-Length: 5\r\n\r\n"
12177 "hello"),
12178 MockRead(ASYNC, ERR_UNEXPECTED),
12179 };
12180
12181 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12182 data_writes, arraysize(data_writes));
12183 session_deps_.socket_factory->AddSocketDataProvider(&data);
12184
12185 TestCompletionCallback callback;
12186
12187 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12188 EXPECT_EQ(ERR_IO_PENDING, rv);
12189
12190 rv = callback.WaitForResult();
12191 EXPECT_EQ(OK, rv);
12192
12193 HttpRequestHeaders request_headers;
12194 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12195 std::string foo;
12196 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12197 EXPECT_EQ("bar", foo);
12198}
12199
[email protected]bf828982013-08-14 18:01:4712200namespace {
12201
[email protected]e86839fd2013-08-14 18:29:0312202// Fake HttpStreamBase that simply records calls to SetPriority().
12203class FakeStream : public HttpStreamBase,
12204 public base::SupportsWeakPtr<FakeStream> {
12205 public:
12206 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
12207 virtual ~FakeStream() {}
12208
12209 RequestPriority priority() const { return priority_; }
12210
12211 virtual int InitializeStream(const HttpRequestInfo* request_info,
12212 RequestPriority priority,
12213 const BoundNetLog& net_log,
12214 const CompletionCallback& callback) OVERRIDE {
12215 return ERR_IO_PENDING;
12216 }
12217
12218 virtual int SendRequest(const HttpRequestHeaders& request_headers,
12219 HttpResponseInfo* response,
12220 const CompletionCallback& callback) OVERRIDE {
12221 ADD_FAILURE();
12222 return ERR_UNEXPECTED;
12223 }
12224
12225 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
12226 ADD_FAILURE();
12227 return ERR_UNEXPECTED;
12228 }
12229
[email protected]e86839fd2013-08-14 18:29:0312230 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
12231 const CompletionCallback& callback) OVERRIDE {
12232 ADD_FAILURE();
12233 return ERR_UNEXPECTED;
12234 }
12235
12236 virtual void Close(bool not_reusable) OVERRIDE {}
12237
12238 virtual bool IsResponseBodyComplete() const OVERRIDE {
12239 ADD_FAILURE();
12240 return false;
12241 }
12242
12243 virtual bool CanFindEndOfResponse() const OVERRIDE {
12244 return false;
12245 }
12246
12247 virtual bool IsConnectionReused() const OVERRIDE {
12248 ADD_FAILURE();
12249 return false;
12250 }
12251
12252 virtual void SetConnectionReused() OVERRIDE {
12253 ADD_FAILURE();
12254 }
12255
12256 virtual bool IsConnectionReusable() const OVERRIDE {
12257 ADD_FAILURE();
12258 return false;
12259 }
12260
[email protected]bc92bc972013-12-13 08:32:5912261 virtual int64 GetTotalReceivedBytes() const OVERRIDE {
12262 ADD_FAILURE();
12263 return 0;
12264 }
12265
[email protected]e86839fd2013-08-14 18:29:0312266 virtual bool GetLoadTimingInfo(
12267 LoadTimingInfo* load_timing_info) const OVERRIDE {
12268 ADD_FAILURE();
12269 return false;
12270 }
12271
12272 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
12273 ADD_FAILURE();
12274 }
12275
12276 virtual void GetSSLCertRequestInfo(
12277 SSLCertRequestInfo* cert_request_info) OVERRIDE {
12278 ADD_FAILURE();
12279 }
12280
12281 virtual bool IsSpdyHttpStream() const OVERRIDE {
12282 ADD_FAILURE();
12283 return false;
12284 }
12285
12286 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
12287 ADD_FAILURE();
12288 }
12289
12290 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12291 priority_ = priority;
12292 }
12293
12294 private:
12295 RequestPriority priority_;
12296
12297 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12298};
12299
12300// Fake HttpStreamRequest that simply records calls to SetPriority()
12301// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712302class FakeStreamRequest : public HttpStreamRequest,
12303 public base::SupportsWeakPtr<FakeStreamRequest> {
12304 public:
[email protected]e86839fd2013-08-14 18:29:0312305 FakeStreamRequest(RequestPriority priority,
12306 HttpStreamRequest::Delegate* delegate)
12307 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412308 delegate_(delegate),
12309 websocket_stream_create_helper_(NULL) {}
12310
12311 FakeStreamRequest(RequestPriority priority,
12312 HttpStreamRequest::Delegate* delegate,
12313 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12314 : priority_(priority),
12315 delegate_(delegate),
12316 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312317
[email protected]bf828982013-08-14 18:01:4712318 virtual ~FakeStreamRequest() {}
12319
12320 RequestPriority priority() const { return priority_; }
12321
[email protected]831e4a32013-11-14 02:14:4412322 const WebSocketHandshakeStreamBase::CreateHelper*
12323 websocket_stream_create_helper() const {
12324 return websocket_stream_create_helper_;
12325 }
12326
[email protected]e86839fd2013-08-14 18:29:0312327 // Create a new FakeStream and pass it to the request's
12328 // delegate. Returns a weak pointer to the FakeStream.
12329 base::WeakPtr<FakeStream> FinishStreamRequest() {
12330 FakeStream* fake_stream = new FakeStream(priority_);
12331 // Do this before calling OnStreamReady() as OnStreamReady() may
12332 // immediately delete |fake_stream|.
12333 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12334 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12335 return weak_stream;
12336 }
12337
[email protected]bf828982013-08-14 18:01:4712338 virtual int RestartTunnelWithProxyAuth(
12339 const AuthCredentials& credentials) OVERRIDE {
12340 ADD_FAILURE();
12341 return ERR_UNEXPECTED;
12342 }
12343
12344 virtual LoadState GetLoadState() const OVERRIDE {
12345 ADD_FAILURE();
12346 return LoadState();
12347 }
12348
12349 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12350 priority_ = priority;
12351 }
12352
12353 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712354 return false;
12355 }
12356
12357 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712358 return kProtoUnknown;
12359 }
12360
12361 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712362 return false;
12363 }
12364
12365 private:
12366 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312367 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412368 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712369
12370 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12371};
12372
12373// Fake HttpStreamFactory that vends FakeStreamRequests.
12374class FakeStreamFactory : public HttpStreamFactory {
12375 public:
12376 FakeStreamFactory() {}
12377 virtual ~FakeStreamFactory() {}
12378
12379 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12380 // RequestStream() (which may be NULL if it was destroyed already).
12381 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12382 return last_stream_request_;
12383 }
12384
12385 virtual HttpStreamRequest* RequestStream(
12386 const HttpRequestInfo& info,
12387 RequestPriority priority,
12388 const SSLConfig& server_ssl_config,
12389 const SSLConfig& proxy_ssl_config,
12390 HttpStreamRequest::Delegate* delegate,
12391 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0312392 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712393 last_stream_request_ = fake_request->AsWeakPtr();
12394 return fake_request;
12395 }
12396
[email protected]a9cf2b92013-10-30 12:08:4912397 virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712398 const HttpRequestInfo& info,
12399 RequestPriority priority,
12400 const SSLConfig& server_ssl_config,
12401 const SSLConfig& proxy_ssl_config,
12402 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612403 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
[email protected]bf828982013-08-14 18:01:4712404 const BoundNetLog& net_log) OVERRIDE {
[email protected]831e4a32013-11-14 02:14:4412405 FakeStreamRequest* fake_request =
12406 new FakeStreamRequest(priority, delegate, create_helper);
12407 last_stream_request_ = fake_request->AsWeakPtr();
12408 return fake_request;
[email protected]bf828982013-08-14 18:01:4712409 }
12410
12411 virtual void PreconnectStreams(int num_streams,
12412 const HttpRequestInfo& info,
12413 RequestPriority priority,
12414 const SSLConfig& server_ssl_config,
12415 const SSLConfig& proxy_ssl_config) OVERRIDE {
12416 ADD_FAILURE();
12417 }
12418
[email protected]bf828982013-08-14 18:01:4712419 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
12420 ADD_FAILURE();
12421 return NULL;
12422 }
12423
12424 private:
12425 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12426
12427 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12428};
12429
[email protected]831e4a32013-11-14 02:14:4412430// TODO(yhirano): Split this class out into a net/websockets file, if it is
12431// worth doing.
12432class FakeWebSocketStreamCreateHelper :
12433 public WebSocketHandshakeStreamBase::CreateHelper {
12434 public:
12435 virtual WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112436 scoped_ptr<ClientSocketHandle> connection,
[email protected]831e4a32013-11-14 02:14:4412437 bool using_proxy) OVERRIDE {
12438 NOTREACHED();
12439 return NULL;
12440 }
12441
12442 virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12443 const base::WeakPtr<SpdySession>& session,
12444 bool use_relative_url) OVERRIDE {
12445 NOTREACHED();
12446 return NULL;
12447 };
12448
12449 virtual ~FakeWebSocketStreamCreateHelper() {}
12450
12451 virtual scoped_ptr<WebSocketStream> Upgrade() {
12452 NOTREACHED();
12453 return scoped_ptr<WebSocketStream>();
12454 }
12455};
12456
[email protected]bf828982013-08-14 18:01:4712457} // namespace
12458
12459// Make sure that HttpNetworkTransaction passes on its priority to its
12460// stream request on start.
12461TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12462 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12463 HttpNetworkSessionPeer peer(session);
12464 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412465 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712466
12467 HttpNetworkTransaction trans(LOW, session);
12468
12469 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12470
12471 HttpRequestInfo request;
12472 TestCompletionCallback callback;
12473 EXPECT_EQ(ERR_IO_PENDING,
12474 trans.Start(&request, callback.callback(), BoundNetLog()));
12475
12476 base::WeakPtr<FakeStreamRequest> fake_request =
12477 fake_factory->last_stream_request();
12478 ASSERT_TRUE(fake_request != NULL);
12479 EXPECT_EQ(LOW, fake_request->priority());
12480}
12481
12482// Make sure that HttpNetworkTransaction passes on its priority
12483// updates to its stream request.
12484TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12485 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12486 HttpNetworkSessionPeer peer(session);
12487 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412488 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712489
12490 HttpNetworkTransaction trans(LOW, session);
12491
12492 HttpRequestInfo request;
12493 TestCompletionCallback callback;
12494 EXPECT_EQ(ERR_IO_PENDING,
12495 trans.Start(&request, callback.callback(), BoundNetLog()));
12496
12497 base::WeakPtr<FakeStreamRequest> fake_request =
12498 fake_factory->last_stream_request();
12499 ASSERT_TRUE(fake_request != NULL);
12500 EXPECT_EQ(LOW, fake_request->priority());
12501
12502 trans.SetPriority(LOWEST);
12503 ASSERT_TRUE(fake_request != NULL);
12504 EXPECT_EQ(LOWEST, fake_request->priority());
12505}
12506
[email protected]e86839fd2013-08-14 18:29:0312507// Make sure that HttpNetworkTransaction passes on its priority
12508// updates to its stream.
12509TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12510 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12511 HttpNetworkSessionPeer peer(session);
12512 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412513 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312514
12515 HttpNetworkTransaction trans(LOW, session);
12516
12517 HttpRequestInfo request;
12518 TestCompletionCallback callback;
12519 EXPECT_EQ(ERR_IO_PENDING,
12520 trans.Start(&request, callback.callback(), BoundNetLog()));
12521
12522 base::WeakPtr<FakeStreamRequest> fake_request =
12523 fake_factory->last_stream_request();
12524 ASSERT_TRUE(fake_request != NULL);
12525 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12526 ASSERT_TRUE(fake_stream != NULL);
12527 EXPECT_EQ(LOW, fake_stream->priority());
12528
12529 trans.SetPriority(LOWEST);
12530 EXPECT_EQ(LOWEST, fake_stream->priority());
12531}
12532
[email protected]831e4a32013-11-14 02:14:4412533TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12534 // The same logic needs to be tested for both ws: and wss: schemes, but this
12535 // test is already parameterised on NextProto, so it uses a loop to verify
12536 // that the different schemes work.
12537 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12538 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12539 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12540 HttpNetworkSessionPeer peer(session);
12541 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12542 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312543 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412544 scoped_ptr<HttpStreamFactory>(fake_factory));
12545
12546 HttpNetworkTransaction trans(LOW, session);
12547 trans.SetWebSocketHandshakeStreamCreateHelper(
12548 &websocket_stream_create_helper);
12549
12550 HttpRequestInfo request;
12551 TestCompletionCallback callback;
12552 request.method = "GET";
12553 request.url = GURL(test_cases[i]);
12554
12555 EXPECT_EQ(ERR_IO_PENDING,
12556 trans.Start(&request, callback.callback(), BoundNetLog()));
12557
12558 base::WeakPtr<FakeStreamRequest> fake_request =
12559 fake_factory->last_stream_request();
12560 ASSERT_TRUE(fake_request != NULL);
12561 EXPECT_EQ(&websocket_stream_create_helper,
12562 fake_request->websocket_stream_create_helper());
12563 }
12564}
12565
[email protected]043b68c82013-08-22 23:41:5212566// Tests that when a used socket is returned to the SSL socket pool, it's closed
12567// if the transport socket pool is stalled on the global socket limit.
12568TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12569 ClientSocketPoolManager::set_max_sockets_per_group(
12570 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12571 ClientSocketPoolManager::set_max_sockets_per_pool(
12572 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12573
12574 // Set up SSL request.
12575
12576 HttpRequestInfo ssl_request;
12577 ssl_request.method = "GET";
12578 ssl_request.url = GURL("https://www.google.com/");
12579
12580 MockWrite ssl_writes[] = {
12581 MockWrite("GET / HTTP/1.1\r\n"
12582 "Host: www.google.com\r\n"
12583 "Connection: keep-alive\r\n\r\n"),
12584 };
12585 MockRead ssl_reads[] = {
12586 MockRead("HTTP/1.1 200 OK\r\n"),
12587 MockRead("Content-Length: 11\r\n\r\n"),
12588 MockRead("hello world"),
12589 MockRead(SYNCHRONOUS, OK),
12590 };
12591 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12592 ssl_writes, arraysize(ssl_writes));
12593 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12594
12595 SSLSocketDataProvider ssl(ASYNC, OK);
12596 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12597
12598 // Set up HTTP request.
12599
12600 HttpRequestInfo http_request;
12601 http_request.method = "GET";
12602 http_request.url = GURL("http://www.google.com/");
12603
12604 MockWrite http_writes[] = {
12605 MockWrite("GET / HTTP/1.1\r\n"
12606 "Host: www.google.com\r\n"
12607 "Connection: keep-alive\r\n\r\n"),
12608 };
12609 MockRead http_reads[] = {
12610 MockRead("HTTP/1.1 200 OK\r\n"),
12611 MockRead("Content-Length: 7\r\n\r\n"),
12612 MockRead("falafel"),
12613 MockRead(SYNCHRONOUS, OK),
12614 };
12615 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12616 http_writes, arraysize(http_writes));
12617 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12618
12619 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12620
12621 // Start the SSL request.
12622 TestCompletionCallback ssl_callback;
12623 scoped_ptr<HttpTransaction> ssl_trans(
12624 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12625 ASSERT_EQ(ERR_IO_PENDING,
12626 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12627 BoundNetLog()));
12628
12629 // Start the HTTP request. Pool should stall.
12630 TestCompletionCallback http_callback;
12631 scoped_ptr<HttpTransaction> http_trans(
12632 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12633 ASSERT_EQ(ERR_IO_PENDING,
12634 http_trans->Start(&http_request, http_callback.callback(),
12635 BoundNetLog()));
12636 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12637
12638 // Wait for response from SSL request.
12639 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12640 std::string response_data;
12641 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12642 EXPECT_EQ("hello world", response_data);
12643
12644 // The SSL socket should automatically be closed, so the HTTP request can
12645 // start.
12646 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12647 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12648
12649 // The HTTP request can now complete.
12650 ASSERT_EQ(OK, http_callback.WaitForResult());
12651 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12652 EXPECT_EQ("falafel", response_data);
12653
12654 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12655}
12656
12657// Tests that when a SSL connection is established but there's no corresponding
12658// request that needs it, the new socket is closed if the transport socket pool
12659// is stalled on the global socket limit.
12660TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12661 ClientSocketPoolManager::set_max_sockets_per_group(
12662 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12663 ClientSocketPoolManager::set_max_sockets_per_pool(
12664 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12665
12666 // Set up an ssl request.
12667
12668 HttpRequestInfo ssl_request;
12669 ssl_request.method = "GET";
12670 ssl_request.url = GURL("https://www.foopy.com/");
12671
12672 // No data will be sent on the SSL socket.
12673 StaticSocketDataProvider ssl_data;
12674 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12675
12676 SSLSocketDataProvider ssl(ASYNC, OK);
12677 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12678
12679 // Set up HTTP request.
12680
12681 HttpRequestInfo http_request;
12682 http_request.method = "GET";
12683 http_request.url = GURL("http://www.google.com/");
12684
12685 MockWrite http_writes[] = {
12686 MockWrite("GET / HTTP/1.1\r\n"
12687 "Host: www.google.com\r\n"
12688 "Connection: keep-alive\r\n\r\n"),
12689 };
12690 MockRead http_reads[] = {
12691 MockRead("HTTP/1.1 200 OK\r\n"),
12692 MockRead("Content-Length: 7\r\n\r\n"),
12693 MockRead("falafel"),
12694 MockRead(SYNCHRONOUS, OK),
12695 };
12696 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12697 http_writes, arraysize(http_writes));
12698 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12699
12700 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12701
12702 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12703 // cancelled when a normal transaction is cancelled.
12704 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12705 net::SSLConfig ssl_config;
12706 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12707 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12708 ssl_config, ssl_config);
12709 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12710
12711 // Start the HTTP request. Pool should stall.
12712 TestCompletionCallback http_callback;
12713 scoped_ptr<HttpTransaction> http_trans(
12714 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12715 ASSERT_EQ(ERR_IO_PENDING,
12716 http_trans->Start(&http_request, http_callback.callback(),
12717 BoundNetLog()));
12718 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12719
12720 // The SSL connection will automatically be closed once the connection is
12721 // established, to let the HTTP request start.
12722 ASSERT_EQ(OK, http_callback.WaitForResult());
12723 std::string response_data;
12724 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12725 EXPECT_EQ("falafel", response_data);
12726
12727 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12728}
12729
[email protected]02d74a02014-04-23 18:10:5412730TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
12731 ScopedVector<UploadElementReader> element_readers;
12732 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12733 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12734
12735 HttpRequestInfo request;
12736 request.method = "POST";
12737 request.url = GURL("http://www.foo.com/");
12738 request.upload_data_stream = &upload_data_stream;
12739 request.load_flags = 0;
12740
12741 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12742 scoped_ptr<HttpTransaction> trans(
12743 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12744 // Send headers successfully, but get an error while sending the body.
12745 MockWrite data_writes[] = {
12746 MockWrite("POST / HTTP/1.1\r\n"
12747 "Host: www.foo.com\r\n"
12748 "Connection: keep-alive\r\n"
12749 "Content-Length: 3\r\n\r\n"),
12750 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12751 };
12752
12753 MockRead data_reads[] = {
12754 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12755 MockRead("hello world"),
12756 MockRead(SYNCHRONOUS, OK),
12757 };
12758 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12759 arraysize(data_writes));
12760 session_deps_.socket_factory->AddSocketDataProvider(&data);
12761
12762 TestCompletionCallback callback;
12763
12764 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12765 EXPECT_EQ(ERR_IO_PENDING, rv);
12766
12767 rv = callback.WaitForResult();
12768 EXPECT_EQ(OK, rv);
12769
12770 const HttpResponseInfo* response = trans->GetResponseInfo();
12771 ASSERT_TRUE(response != NULL);
12772
12773 EXPECT_TRUE(response->headers.get() != NULL);
12774 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12775
12776 std::string response_data;
12777 rv = ReadTransaction(trans.get(), &response_data);
12778 EXPECT_EQ(OK, rv);
12779 EXPECT_EQ("hello world", response_data);
12780}
12781
12782// This test makes sure the retry logic doesn't trigger when reading an error
12783// response from a server that rejected a POST with a CONNECTION_RESET.
12784TEST_P(HttpNetworkTransactionTest,
12785 PostReadsErrorResponseAfterResetOnReusedSocket) {
12786 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12787 MockWrite data_writes[] = {
12788 MockWrite("GET / HTTP/1.1\r\n"
12789 "Host: www.foo.com\r\n"
12790 "Connection: keep-alive\r\n\r\n"),
12791 MockWrite("POST / HTTP/1.1\r\n"
12792 "Host: www.foo.com\r\n"
12793 "Connection: keep-alive\r\n"
12794 "Content-Length: 3\r\n\r\n"),
12795 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12796 };
12797
12798 MockRead data_reads[] = {
12799 MockRead("HTTP/1.1 200 Peachy\r\n"
12800 "Content-Length: 14\r\n\r\n"),
12801 MockRead("first response"),
12802 MockRead("HTTP/1.1 400 Not OK\r\n"
12803 "Content-Length: 15\r\n\r\n"),
12804 MockRead("second response"),
12805 MockRead(SYNCHRONOUS, OK),
12806 };
12807 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12808 arraysize(data_writes));
12809 session_deps_.socket_factory->AddSocketDataProvider(&data);
12810
12811 TestCompletionCallback callback;
12812 HttpRequestInfo request1;
12813 request1.method = "GET";
12814 request1.url = GURL("http://www.foo.com/");
12815 request1.load_flags = 0;
12816
12817 scoped_ptr<HttpTransaction> trans1(
12818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12819 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
12820 EXPECT_EQ(ERR_IO_PENDING, rv);
12821
12822 rv = callback.WaitForResult();
12823 EXPECT_EQ(OK, rv);
12824
12825 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12826 ASSERT_TRUE(response1 != NULL);
12827
12828 EXPECT_TRUE(response1->headers.get() != NULL);
12829 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
12830
12831 std::string response_data1;
12832 rv = ReadTransaction(trans1.get(), &response_data1);
12833 EXPECT_EQ(OK, rv);
12834 EXPECT_EQ("first response", response_data1);
12835 // Delete the transaction to release the socket back into the socket pool.
12836 trans1.reset();
12837
12838 ScopedVector<UploadElementReader> element_readers;
12839 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12840 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12841
12842 HttpRequestInfo request2;
12843 request2.method = "POST";
12844 request2.url = GURL("http://www.foo.com/");
12845 request2.upload_data_stream = &upload_data_stream;
12846 request2.load_flags = 0;
12847
12848 scoped_ptr<HttpTransaction> trans2(
12849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12850 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
12851 EXPECT_EQ(ERR_IO_PENDING, rv);
12852
12853 rv = callback.WaitForResult();
12854 EXPECT_EQ(OK, rv);
12855
12856 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
12857 ASSERT_TRUE(response2 != NULL);
12858
12859 EXPECT_TRUE(response2->headers.get() != NULL);
12860 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
12861
12862 std::string response_data2;
12863 rv = ReadTransaction(trans2.get(), &response_data2);
12864 EXPECT_EQ(OK, rv);
12865 EXPECT_EQ("second response", response_data2);
12866}
12867
12868TEST_P(HttpNetworkTransactionTest,
12869 PostReadsErrorResponseAfterResetPartialBodySent) {
12870 ScopedVector<UploadElementReader> element_readers;
12871 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12872 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12873
12874 HttpRequestInfo request;
12875 request.method = "POST";
12876 request.url = GURL("http://www.foo.com/");
12877 request.upload_data_stream = &upload_data_stream;
12878 request.load_flags = 0;
12879
12880 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12881 scoped_ptr<HttpTransaction> trans(
12882 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12883 // Send headers successfully, but get an error while sending the body.
12884 MockWrite data_writes[] = {
12885 MockWrite("POST / HTTP/1.1\r\n"
12886 "Host: www.foo.com\r\n"
12887 "Connection: keep-alive\r\n"
12888 "Content-Length: 3\r\n\r\n"
12889 "fo"),
12890 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12891 };
12892
12893 MockRead data_reads[] = {
12894 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12895 MockRead("hello world"),
12896 MockRead(SYNCHRONOUS, OK),
12897 };
12898 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12899 arraysize(data_writes));
12900 session_deps_.socket_factory->AddSocketDataProvider(&data);
12901
12902 TestCompletionCallback callback;
12903
12904 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12905 EXPECT_EQ(ERR_IO_PENDING, rv);
12906
12907 rv = callback.WaitForResult();
12908 EXPECT_EQ(OK, rv);
12909
12910 const HttpResponseInfo* response = trans->GetResponseInfo();
12911 ASSERT_TRUE(response != NULL);
12912
12913 EXPECT_TRUE(response->headers.get() != NULL);
12914 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12915
12916 std::string response_data;
12917 rv = ReadTransaction(trans.get(), &response_data);
12918 EXPECT_EQ(OK, rv);
12919 EXPECT_EQ("hello world", response_data);
12920}
12921
12922// This tests the more common case than the previous test, where headers and
12923// body are not merged into a single request.
12924TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
12925 ScopedVector<UploadElementReader> element_readers;
12926 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12927 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
12928
12929 HttpRequestInfo request;
12930 request.method = "POST";
12931 request.url = GURL("http://www.foo.com/");
12932 request.upload_data_stream = &upload_data_stream;
12933 request.load_flags = 0;
12934
12935 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12936 scoped_ptr<HttpTransaction> trans(
12937 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12938 // Send headers successfully, but get an error while sending the body.
12939 MockWrite data_writes[] = {
12940 MockWrite("POST / HTTP/1.1\r\n"
12941 "Host: www.foo.com\r\n"
12942 "Connection: keep-alive\r\n"
12943 "Transfer-Encoding: chunked\r\n\r\n"),
12944 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12945 };
12946
12947 MockRead data_reads[] = {
12948 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12949 MockRead("hello world"),
12950 MockRead(SYNCHRONOUS, OK),
12951 };
12952 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12953 arraysize(data_writes));
12954 session_deps_.socket_factory->AddSocketDataProvider(&data);
12955
12956 TestCompletionCallback callback;
12957
12958 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12959 EXPECT_EQ(ERR_IO_PENDING, rv);
12960 // Make sure the headers are sent before adding a chunk. This ensures that
12961 // they can't be merged with the body in a single send. Not currently
12962 // necessary since a chunked body is never merged with headers, but this makes
12963 // the test more future proof.
12964 base::RunLoop().RunUntilIdle();
12965
12966 upload_data_stream.AppendChunk("last chunk", 10, true);
12967
12968 rv = callback.WaitForResult();
12969 EXPECT_EQ(OK, rv);
12970
12971 const HttpResponseInfo* response = trans->GetResponseInfo();
12972 ASSERT_TRUE(response != NULL);
12973
12974 EXPECT_TRUE(response->headers.get() != NULL);
12975 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12976
12977 std::string response_data;
12978 rv = ReadTransaction(trans.get(), &response_data);
12979 EXPECT_EQ(OK, rv);
12980 EXPECT_EQ("hello world", response_data);
12981}
12982
12983TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
12984 ScopedVector<UploadElementReader> element_readers;
12985 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12986 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12987
12988 HttpRequestInfo request;
12989 request.method = "POST";
12990 request.url = GURL("http://www.foo.com/");
12991 request.upload_data_stream = &upload_data_stream;
12992 request.load_flags = 0;
12993
12994 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12995 scoped_ptr<HttpTransaction> trans(
12996 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12997
12998 MockWrite data_writes[] = {
12999 MockWrite("POST / HTTP/1.1\r\n"
13000 "Host: www.foo.com\r\n"
13001 "Connection: keep-alive\r\n"
13002 "Content-Length: 3\r\n\r\n"),
13003 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13004 };
13005
13006 MockRead data_reads[] = {
13007 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13008 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13009 MockRead("hello world"),
13010 MockRead(SYNCHRONOUS, OK),
13011 };
13012 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13013 arraysize(data_writes));
13014 session_deps_.socket_factory->AddSocketDataProvider(&data);
13015
13016 TestCompletionCallback callback;
13017
13018 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13019 EXPECT_EQ(ERR_IO_PENDING, rv);
13020
13021 rv = callback.WaitForResult();
13022 EXPECT_EQ(OK, rv);
13023
13024 const HttpResponseInfo* response = trans->GetResponseInfo();
13025 ASSERT_TRUE(response != NULL);
13026
13027 EXPECT_TRUE(response->headers.get() != NULL);
13028 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13029
13030 std::string response_data;
13031 rv = ReadTransaction(trans.get(), &response_data);
13032 EXPECT_EQ(OK, rv);
13033 EXPECT_EQ("hello world", response_data);
13034}
13035
13036TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13037 ScopedVector<UploadElementReader> element_readers;
13038 element_readers.push_back(new UploadBytesElementReader("foo", 3));
13039 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13040
13041 HttpRequestInfo request;
13042 request.method = "POST";
13043 request.url = GURL("http://www.foo.com/");
13044 request.upload_data_stream = &upload_data_stream;
13045 request.load_flags = 0;
13046
13047 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13048 scoped_ptr<HttpTransaction> trans(
13049 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13050 // Send headers successfully, but get an error while sending the body.
13051 MockWrite data_writes[] = {
13052 MockWrite("POST / HTTP/1.1\r\n"
13053 "Host: www.foo.com\r\n"
13054 "Connection: keep-alive\r\n"
13055 "Content-Length: 3\r\n\r\n"),
13056 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13057 };
13058
13059 MockRead data_reads[] = {
13060 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13061 MockRead("hello world"),
13062 MockRead(SYNCHRONOUS, OK),
13063 };
13064 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13065 arraysize(data_writes));
13066 session_deps_.socket_factory->AddSocketDataProvider(&data);
13067
13068 TestCompletionCallback callback;
13069
13070 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13071 EXPECT_EQ(ERR_IO_PENDING, rv);
13072
13073 rv = callback.WaitForResult();
13074 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13075
13076 const HttpResponseInfo* response = trans->GetResponseInfo();
13077 EXPECT_TRUE(response == NULL);
13078}
13079
13080TEST_P(HttpNetworkTransactionTest,
13081 PostIgnoresNonErrorResponseAfterResetAnd100) {
13082 ScopedVector<UploadElementReader> element_readers;
13083 element_readers.push_back(new UploadBytesElementReader("foo", 3));
13084 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13085
13086 HttpRequestInfo request;
13087 request.method = "POST";
13088 request.url = GURL("http://www.foo.com/");
13089 request.upload_data_stream = &upload_data_stream;
13090 request.load_flags = 0;
13091
13092 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13093 scoped_ptr<HttpTransaction> trans(
13094 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13095 // Send headers successfully, but get an error while sending the body.
13096 MockWrite data_writes[] = {
13097 MockWrite("POST / HTTP/1.1\r\n"
13098 "Host: www.foo.com\r\n"
13099 "Connection: keep-alive\r\n"
13100 "Content-Length: 3\r\n\r\n"),
13101 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13102 };
13103
13104 MockRead data_reads[] = {
13105 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13106 MockRead("HTTP/1.0 302 Redirect\r\n"),
13107 MockRead("Location: http://somewhere-else.com/\r\n"),
13108 MockRead("Content-Length: 0\r\n\r\n"),
13109 MockRead(SYNCHRONOUS, OK),
13110 };
13111 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13112 arraysize(data_writes));
13113 session_deps_.socket_factory->AddSocketDataProvider(&data);
13114
13115 TestCompletionCallback callback;
13116
13117 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13118 EXPECT_EQ(ERR_IO_PENDING, rv);
13119
13120 rv = callback.WaitForResult();
13121 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13122
13123 const HttpResponseInfo* response = trans->GetResponseInfo();
13124 EXPECT_TRUE(response == NULL);
13125}
13126
13127TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13128 ScopedVector<UploadElementReader> element_readers;
13129 element_readers.push_back(new UploadBytesElementReader("foo", 3));
13130 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13131
13132 HttpRequestInfo request;
13133 request.method = "POST";
13134 request.url = GURL("http://www.foo.com/");
13135 request.upload_data_stream = &upload_data_stream;
13136 request.load_flags = 0;
13137
13138 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13139 scoped_ptr<HttpTransaction> trans(
13140 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13141 // Send headers successfully, but get an error while sending the body.
13142 MockWrite data_writes[] = {
13143 MockWrite("POST / HTTP/1.1\r\n"
13144 "Host: www.foo.com\r\n"
13145 "Connection: keep-alive\r\n"
13146 "Content-Length: 3\r\n\r\n"),
13147 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13148 };
13149
13150 MockRead data_reads[] = {
13151 MockRead("HTTP 0.9 rocks!"),
13152 MockRead(SYNCHRONOUS, OK),
13153 };
13154 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13155 arraysize(data_writes));
13156 session_deps_.socket_factory->AddSocketDataProvider(&data);
13157
13158 TestCompletionCallback callback;
13159
13160 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13161 EXPECT_EQ(ERR_IO_PENDING, rv);
13162
13163 rv = callback.WaitForResult();
13164 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13165
13166 const HttpResponseInfo* response = trans->GetResponseInfo();
13167 EXPECT_TRUE(response == NULL);
13168}
13169
13170TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13171 ScopedVector<UploadElementReader> element_readers;
13172 element_readers.push_back(new UploadBytesElementReader("foo", 3));
13173 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13174
13175 HttpRequestInfo request;
13176 request.method = "POST";
13177 request.url = GURL("http://www.foo.com/");
13178 request.upload_data_stream = &upload_data_stream;
13179 request.load_flags = 0;
13180
13181 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13182 scoped_ptr<HttpTransaction> trans(
13183 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13184 // Send headers successfully, but get an error while sending the body.
13185 MockWrite data_writes[] = {
13186 MockWrite("POST / HTTP/1.1\r\n"
13187 "Host: www.foo.com\r\n"
13188 "Connection: keep-alive\r\n"
13189 "Content-Length: 3\r\n\r\n"),
13190 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13191 };
13192
13193 MockRead data_reads[] = {
13194 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13195 MockRead(SYNCHRONOUS, OK),
13196 };
13197 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13198 arraysize(data_writes));
13199 session_deps_.socket_factory->AddSocketDataProvider(&data);
13200
13201 TestCompletionCallback callback;
13202
13203 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13204 EXPECT_EQ(ERR_IO_PENDING, rv);
13205
13206 rv = callback.WaitForResult();
13207 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13208
13209 const HttpResponseInfo* response = trans->GetResponseInfo();
13210 EXPECT_TRUE(response == NULL);
13211}
13212
[email protected]89ceba9a2009-03-21 03:46:0613213} // namespace net