blob: f56b6e25e36c292aca58b88ab8f35e4a49463a76 [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,
[email protected]8e458552014-08-05 00:02:15588 false,
589 NULL) {
590}
[email protected]2227c692010-05-04 15:36:11591
[email protected]231d5a32008-09-13 00:45:27592//-----------------------------------------------------------------------------
593
[email protected]79cb5c12011-09-12 13:12:04594// Helper functions for validating that AuthChallengeInfo's are correctly
595// configured for common cases.
596bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
597 if (!auth_challenge)
598 return false;
599 EXPECT_FALSE(auth_challenge->is_proxy);
600 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
601 EXPECT_EQ("MyRealm1", auth_challenge->realm);
602 EXPECT_EQ("basic", auth_challenge->scheme);
603 return true;
604}
605
606bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
607 if (!auth_challenge)
608 return false;
609 EXPECT_TRUE(auth_challenge->is_proxy);
610 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
611 EXPECT_EQ("MyRealm1", auth_challenge->realm);
612 EXPECT_EQ("basic", auth_challenge->scheme);
613 return true;
614}
615
616bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
617 if (!auth_challenge)
618 return false;
619 EXPECT_FALSE(auth_challenge->is_proxy);
620 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
621 EXPECT_EQ("digestive", auth_challenge->realm);
622 EXPECT_EQ("digest", auth_challenge->scheme);
623 return true;
624}
625
626bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
627 if (!auth_challenge)
628 return false;
629 EXPECT_FALSE(auth_challenge->is_proxy);
630 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
631 EXPECT_EQ(std::string(), auth_challenge->realm);
632 EXPECT_EQ("ntlm", auth_challenge->scheme);
633 return true;
634}
635
[email protected]448d4ca52012-03-04 04:12:23636} // namespace
637
[email protected]23e482282013-06-14 16:08:02638TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07639 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40640 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07641 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]231d5a32008-09-13 00:45:27642}
643
[email protected]23e482282013-06-14 16:08:02644TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27645 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35646 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
647 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06648 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27649 };
[email protected]31a2bfe2010-02-09 08:03:39650 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
651 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42652 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27653 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
654 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19655 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
656 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27657}
658
659// Response with no status line.
[email protected]23e482282013-06-14 16:08:02660TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27661 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35662 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06663 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27664 };
[email protected]31a2bfe2010-02-09 08:03:39665 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
666 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42667 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27668 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
669 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19670 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
671 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27672}
673
674// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02675TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27676 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35677 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06678 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27679 };
[email protected]31a2bfe2010-02-09 08:03:39680 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
681 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42682 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27683 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
684 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19685 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
686 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27687}
688
689// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02690TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27691 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35692 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06693 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27694 };
[email protected]31a2bfe2010-02-09 08:03:39695 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
696 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42697 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27698 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
699 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19700 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
701 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27702}
703
704// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02705TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27706 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35707 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06708 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27709 };
[email protected]31a2bfe2010-02-09 08:03:39710 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
711 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42712 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25713 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
714 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19715 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
716 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27717}
718
719// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02720TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27721 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35722 MockRead("\n"),
723 MockRead("\n"),
724 MockRead("Q"),
725 MockRead("J"),
726 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06727 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27728 };
[email protected]31a2bfe2010-02-09 08:03:39729 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
730 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42731 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27732 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
733 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19734 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
735 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27736}
737
738// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02739TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27740 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35741 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06742 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27743 };
[email protected]31a2bfe2010-02-09 08:03:39744 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
745 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42746 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27747 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
748 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19749 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
750 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52751}
752
[email protected]f9d44aa2008-09-23 23:57:17753// Simulate a 204 response, lacking a Content-Length header, sent over a
754// persistent connection. The response should still terminate since a 204
755// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02756TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19757 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17758 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35759 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19760 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06761 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17762 };
[email protected]31a2bfe2010-02-09 08:03:39763 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
764 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42765 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17766 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
767 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19768 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
769 int64 response_size = reads_size - strlen(junk);
770 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17771}
772
[email protected]0877e3d2009-10-17 22:29:57773// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02774TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19775 std::string final_chunk = "0\r\n\r\n";
776 std::string extra_data = "HTTP/1.1 200 OK\r\n";
777 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57778 MockRead data_reads[] = {
779 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
780 MockRead("5\r\nHello\r\n"),
781 MockRead("1\r\n"),
782 MockRead(" \r\n"),
783 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19784 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06785 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57786 };
[email protected]31a2bfe2010-02-09 08:03:39787 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
788 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57789 EXPECT_EQ(OK, out.rv);
790 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
791 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19792 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
793 int64 response_size = reads_size - extra_data.size();
794 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57795}
796
[email protected]9fe44f52010-09-23 18:36:00797// Next tests deal with http://crbug.com/56344.
798
[email protected]23e482282013-06-14 16:08:02799TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00800 MultipleContentLengthHeadersNoTransferEncoding) {
801 MockRead data_reads[] = {
802 MockRead("HTTP/1.1 200 OK\r\n"),
803 MockRead("Content-Length: 10\r\n"),
804 MockRead("Content-Length: 5\r\n\r\n"),
805 };
806 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
807 arraysize(data_reads));
808 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
809}
810
[email protected]23e482282013-06-14 16:08:02811TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04812 DuplicateContentLengthHeadersNoTransferEncoding) {
813 MockRead data_reads[] = {
814 MockRead("HTTP/1.1 200 OK\r\n"),
815 MockRead("Content-Length: 5\r\n"),
816 MockRead("Content-Length: 5\r\n\r\n"),
817 MockRead("Hello"),
818 };
819 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
820 arraysize(data_reads));
821 EXPECT_EQ(OK, out.rv);
822 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
823 EXPECT_EQ("Hello", out.response_data);
824}
825
[email protected]23e482282013-06-14 16:08:02826TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04827 ComplexContentLengthHeadersNoTransferEncoding) {
828 // More than 2 dupes.
829 {
830 MockRead data_reads[] = {
831 MockRead("HTTP/1.1 200 OK\r\n"),
832 MockRead("Content-Length: 5\r\n"),
833 MockRead("Content-Length: 5\r\n"),
834 MockRead("Content-Length: 5\r\n\r\n"),
835 MockRead("Hello"),
836 };
837 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
838 arraysize(data_reads));
839 EXPECT_EQ(OK, out.rv);
840 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
841 EXPECT_EQ("Hello", out.response_data);
842 }
843 // HTTP/1.0
844 {
845 MockRead data_reads[] = {
846 MockRead("HTTP/1.0 200 OK\r\n"),
847 MockRead("Content-Length: 5\r\n"),
848 MockRead("Content-Length: 5\r\n"),
849 MockRead("Content-Length: 5\r\n\r\n"),
850 MockRead("Hello"),
851 };
852 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
853 arraysize(data_reads));
854 EXPECT_EQ(OK, out.rv);
855 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
856 EXPECT_EQ("Hello", out.response_data);
857 }
858 // 2 dupes and one mismatched.
859 {
860 MockRead data_reads[] = {
861 MockRead("HTTP/1.1 200 OK\r\n"),
862 MockRead("Content-Length: 10\r\n"),
863 MockRead("Content-Length: 10\r\n"),
864 MockRead("Content-Length: 5\r\n\r\n"),
865 };
866 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
867 arraysize(data_reads));
868 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
869 }
870}
871
[email protected]23e482282013-06-14 16:08:02872TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00873 MultipleContentLengthHeadersTransferEncoding) {
874 MockRead data_reads[] = {
875 MockRead("HTTP/1.1 200 OK\r\n"),
876 MockRead("Content-Length: 666\r\n"),
877 MockRead("Content-Length: 1337\r\n"),
878 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
879 MockRead("5\r\nHello\r\n"),
880 MockRead("1\r\n"),
881 MockRead(" \r\n"),
882 MockRead("5\r\nworld\r\n"),
883 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06884 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00885 };
886 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
887 arraysize(data_reads));
888 EXPECT_EQ(OK, out.rv);
889 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
890 EXPECT_EQ("Hello world", out.response_data);
891}
892
[email protected]1628fe92011-10-04 23:04:55893// Next tests deal with http://crbug.com/98895.
894
895// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02896TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55897 MockRead data_reads[] = {
898 MockRead("HTTP/1.1 200 OK\r\n"),
899 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
900 MockRead("Content-Length: 5\r\n\r\n"),
901 MockRead("Hello"),
902 };
903 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
904 arraysize(data_reads));
905 EXPECT_EQ(OK, out.rv);
906 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
907 EXPECT_EQ("Hello", out.response_data);
908}
909
[email protected]54a9c6e52012-03-21 20:10:59910// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02911TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59912 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55913 MockRead data_reads[] = {
914 MockRead("HTTP/1.1 200 OK\r\n"),
915 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
916 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
917 MockRead("Content-Length: 5\r\n\r\n"),
918 MockRead("Hello"),
919 };
920 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
921 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59922 EXPECT_EQ(OK, out.rv);
923 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
924 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55925}
926
927// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02928TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55929 MockRead data_reads[] = {
930 MockRead("HTTP/1.1 200 OK\r\n"),
931 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
932 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
933 MockRead("Content-Length: 5\r\n\r\n"),
934 MockRead("Hello"),
935 };
936 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
937 arraysize(data_reads));
938 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
939}
940
[email protected]54a9c6e52012-03-21 20:10:59941// Checks that two identical Location headers result in no error.
942// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02943TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55944 MockRead data_reads[] = {
945 MockRead("HTTP/1.1 302 Redirect\r\n"),
946 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59947 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55948 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06949 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55950 };
951
952 HttpRequestInfo request;
953 request.method = "GET";
954 request.url = GURL("http://redirect.com/");
955 request.load_flags = 0;
956
[email protected]3fe8d2f82013-10-17 08:56:07957 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55958 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07959 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]1628fe92011-10-04 23:04:55960
961 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07962 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55963
[email protected]49639fa2011-12-20 23:22:41964 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55965
[email protected]49639fa2011-12-20 23:22:41966 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55967 EXPECT_EQ(ERR_IO_PENDING, rv);
968
969 EXPECT_EQ(OK, callback.WaitForResult());
970
971 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50972 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55973 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
974 std::string url;
975 EXPECT_TRUE(response->headers->IsRedirect(&url));
976 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:15977 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:55978}
979
[email protected]1628fe92011-10-04 23:04:55980// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02981TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55982 MockRead data_reads[] = {
983 MockRead("HTTP/1.1 302 Redirect\r\n"),
984 MockRead("Location: http://good.com/\r\n"),
985 MockRead("Location: http://evil.com/\r\n"),
986 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06987 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55988 };
989 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
990 arraysize(data_reads));
991 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
992}
993
[email protected]ef0faf2e72009-03-05 23:27:23994// Do a request using the HEAD method. Verify that we don't try to read the
995// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02996TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42997 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23998 request.method = "HEAD";
999 request.url = GURL("http://www.google.com/");
1000 request.load_flags = 0;
1001
[email protected]3fe8d2f82013-10-17 08:56:071002 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271003 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071004 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]597a1ab2014-06-26 08:12:271005 BeforeProxyHeadersSentHandler proxy_headers_handler;
1006 trans->SetBeforeProxyHeadersSentCallback(
1007 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1008 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271009
[email protected]ef0faf2e72009-03-05 23:27:231010 MockWrite data_writes1[] = {
1011 MockWrite("HEAD / HTTP/1.1\r\n"
1012 "Host: www.google.com\r\n"
1013 "Connection: keep-alive\r\n"
1014 "Content-Length: 0\r\n\r\n"),
1015 };
1016 MockRead data_reads1[] = {
1017 MockRead("HTTP/1.1 404 Not Found\r\n"),
1018 MockRead("Server: Blah\r\n"),
1019 MockRead("Content-Length: 1234\r\n\r\n"),
1020
1021 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061022 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231023 };
1024
[email protected]31a2bfe2010-02-09 08:03:391025 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1026 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071027 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231028
[email protected]49639fa2011-12-20 23:22:411029 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231030
[email protected]49639fa2011-12-20 23:22:411031 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421032 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231033
1034 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421035 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231036
[email protected]1c773ea12009-04-28 19:58:421037 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501038 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231039
1040 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501041 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231042 EXPECT_EQ(1234, response->headers->GetContentLength());
1043 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151044 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271045 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231046
1047 std::string server_header;
1048 void* iter = NULL;
1049 bool has_server_header = response->headers->EnumerateHeader(
1050 &iter, "Server", &server_header);
1051 EXPECT_TRUE(has_server_header);
1052 EXPECT_EQ("Blah", server_header);
1053
1054 // Reading should give EOF right away, since there is no message body
1055 // (despite non-zero content-length).
1056 std::string response_data;
1057 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421058 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231059 EXPECT_EQ("", response_data);
1060}
1061
[email protected]23e482282013-06-14 16:08:021062TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071063 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521064
1065 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351066 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1067 MockRead("hello"),
1068 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1069 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061070 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521071 };
[email protected]31a2bfe2010-02-09 08:03:391072 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071073 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521074
[email protected]0b0bf032010-09-21 18:08:501075 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521076 "hello", "world"
1077 };
1078
1079 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421080 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521081 request.method = "GET";
1082 request.url = GURL("http://www.google.com/");
1083 request.load_flags = 0;
1084
[email protected]262eec82013-03-19 21:01:361085 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501086 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271087
[email protected]49639fa2011-12-20 23:22:411088 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521089
[email protected]49639fa2011-12-20 23:22:411090 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421091 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521092
1093 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421094 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521095
[email protected]1c773ea12009-04-28 19:58:421096 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501097 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521098
[email protected]90499482013-06-01 00:39:501099 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251100 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151101 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521102
1103 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571104 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421105 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251106 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521107 }
1108}
1109
[email protected]23e482282013-06-14 16:08:021110TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061111 ScopedVector<UploadElementReader> element_readers;
1112 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201113 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271114
[email protected]1c773ea12009-04-28 19:58:421115 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521116 request.method = "POST";
1117 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271118 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521119 request.load_flags = 0;
1120
[email protected]3fe8d2f82013-10-17 08:56:071121 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271122 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071123 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271124
initial.commit586acc5fe2008-07-26 22:42:521125 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351126 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1127 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1128 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061129 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521130 };
[email protected]31a2bfe2010-02-09 08:03:391131 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071132 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521133
[email protected]49639fa2011-12-20 23:22:411134 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521135
[email protected]49639fa2011-12-20 23:22:411136 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421137 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521138
1139 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421140 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521141
[email protected]1c773ea12009-04-28 19:58:421142 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501143 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521144
[email protected]90499482013-06-01 00:39:501145 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251146 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521147
1148 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571149 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421150 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251151 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521152}
1153
[email protected]3a2d3662009-03-27 03:49:141154// This test is almost the same as Ignores100 above, but the response contains
1155// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571156// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021157TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421158 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141159 request.method = "GET";
1160 request.url = GURL("http://www.foo.com/");
1161 request.load_flags = 0;
1162
[email protected]3fe8d2f82013-10-17 08:56:071163 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271164 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071165 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271166
[email protected]3a2d3662009-03-27 03:49:141167 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571168 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1169 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141170 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061171 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141172 };
[email protected]31a2bfe2010-02-09 08:03:391173 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071174 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141175
[email protected]49639fa2011-12-20 23:22:411176 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141177
[email protected]49639fa2011-12-20 23:22:411178 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421179 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141180
1181 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421182 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141183
[email protected]1c773ea12009-04-28 19:58:421184 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501185 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141186
[email protected]90499482013-06-01 00:39:501187 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141188 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1189
1190 std::string response_data;
1191 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421192 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141193 EXPECT_EQ("hello world", response_data);
1194}
1195
[email protected]23e482282013-06-14 16:08:021196TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381197 HttpRequestInfo request;
1198 request.method = "POST";
1199 request.url = GURL("http://www.foo.com/");
1200 request.load_flags = 0;
1201
[email protected]3fe8d2f82013-10-17 08:56:071202 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271203 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071204 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271205
[email protected]ee9410e72010-01-07 01:42:381206 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061207 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1208 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381209 };
[email protected]31a2bfe2010-02-09 08:03:391210 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071211 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381212
[email protected]49639fa2011-12-20 23:22:411213 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381214
[email protected]49639fa2011-12-20 23:22:411215 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381216 EXPECT_EQ(ERR_IO_PENDING, rv);
1217
1218 rv = callback.WaitForResult();
1219 EXPECT_EQ(OK, rv);
1220
1221 std::string response_data;
1222 rv = ReadTransaction(trans.get(), &response_data);
1223 EXPECT_EQ(OK, rv);
1224 EXPECT_EQ("", response_data);
1225}
1226
[email protected]23e482282013-06-14 16:08:021227TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381228 HttpRequestInfo request;
1229 request.method = "POST";
1230 request.url = GURL("http://www.foo.com/");
1231 request.load_flags = 0;
1232
[email protected]3fe8d2f82013-10-17 08:56:071233 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271234 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071235 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1236
[email protected]cb9bf6ca2011-01-28 13:15:271237
[email protected]ee9410e72010-01-07 01:42:381238 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061239 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381240 };
[email protected]31a2bfe2010-02-09 08:03:391241 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071242 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381243
[email protected]49639fa2011-12-20 23:22:411244 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381245
[email protected]49639fa2011-12-20 23:22:411246 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381247 EXPECT_EQ(ERR_IO_PENDING, rv);
1248
1249 rv = callback.WaitForResult();
1250 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1251}
1252
[email protected]23e482282013-06-14 16:08:021253void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511254 const MockWrite* write_failure,
1255 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421256 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521257 request.method = "GET";
1258 request.url = GURL("http://www.foo.com/");
1259 request.load_flags = 0;
1260
[email protected]58e32bb2013-01-21 18:23:251261 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071262 session_deps_.net_log = &net_log;
1263 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271264
[email protected]202965992011-12-07 23:04:511265 // Written data for successfully sending both requests.
1266 MockWrite data1_writes[] = {
1267 MockWrite("GET / HTTP/1.1\r\n"
1268 "Host: www.foo.com\r\n"
1269 "Connection: keep-alive\r\n\r\n"),
1270 MockWrite("GET / HTTP/1.1\r\n"
1271 "Host: www.foo.com\r\n"
1272 "Connection: keep-alive\r\n\r\n")
1273 };
1274
1275 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521276 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351277 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1278 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061279 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521280 };
[email protected]202965992011-12-07 23:04:511281
1282 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491283 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511284 data1_writes[1] = *write_failure;
1285 } else {
1286 ASSERT_TRUE(read_failure);
1287 data1_reads[2] = *read_failure;
1288 }
1289
1290 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1291 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071292 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521293
1294 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351295 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1296 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061297 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521298 };
[email protected]31a2bfe2010-02-09 08:03:391299 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071300 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521301
1302 const char* kExpectedResponseData[] = {
1303 "hello", "world"
1304 };
1305
[email protected]58e32bb2013-01-21 18:23:251306 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521307 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411308 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521309
[email protected]262eec82013-03-19 21:01:361310 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521312
[email protected]49639fa2011-12-20 23:22:411313 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421314 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521315
1316 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421317 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521318
[email protected]58e32bb2013-01-21 18:23:251319 LoadTimingInfo load_timing_info;
1320 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1321 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1322 if (i == 0) {
1323 first_socket_log_id = load_timing_info.socket_log_id;
1324 } else {
1325 // The second request should be using a new socket.
1326 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1327 }
1328
[email protected]1c773ea12009-04-28 19:58:421329 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501330 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521331
[email protected]90499482013-06-01 00:39:501332 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251333 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521334
1335 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571336 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421337 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251338 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521339 }
1340}
[email protected]3d2a59b2008-09-26 19:44:251341
[email protected]a34f61ee2014-03-18 20:59:491342void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1343 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101344 const MockRead* read_failure,
1345 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491346 HttpRequestInfo request;
1347 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101348 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491349 request.load_flags = 0;
1350
1351 CapturingNetLog net_log;
1352 session_deps_.net_log = &net_log;
1353 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1354
[email protected]09356c652014-03-25 15:36:101355 SSLSocketDataProvider ssl1(ASYNC, OK);
1356 SSLSocketDataProvider ssl2(ASYNC, OK);
1357 if (use_spdy) {
1358 ssl1.SetNextProto(GetParam());
1359 ssl2.SetNextProto(GetParam());
1360 }
1361 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491363
[email protected]09356c652014-03-25 15:36:101364 // SPDY versions of the request and response.
1365 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1366 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1367 scoped_ptr<SpdyFrame> spdy_response(
1368 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1369 scoped_ptr<SpdyFrame> spdy_data(
1370 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491371
[email protected]09356c652014-03-25 15:36:101372 // HTTP/1.1 versions of the request and response.
1373 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1374 "Host: www.foo.com\r\n"
1375 "Connection: keep-alive\r\n\r\n";
1376 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1377 const char kHttpData[] = "hello";
1378
1379 std::vector<MockRead> data1_reads;
1380 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491381 if (write_failure) {
1382 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101383 data1_writes.push_back(*write_failure);
1384 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491385 } else {
1386 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101387 if (use_spdy) {
1388 data1_writes.push_back(CreateMockWrite(*spdy_request));
1389 } else {
1390 data1_writes.push_back(MockWrite(kHttpRequest));
1391 }
1392 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491393 }
1394
[email protected]09356c652014-03-25 15:36:101395 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1396 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491397 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1398
[email protected]09356c652014-03-25 15:36:101399 std::vector<MockRead> data2_reads;
1400 std::vector<MockWrite> data2_writes;
1401
1402 if (use_spdy) {
1403 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1404
1405 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1406 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1407 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1408 } else {
1409 data2_writes.push_back(
1410 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1411
1412 data2_reads.push_back(
1413 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1414 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1415 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1416 }
1417 OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1418 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491419 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1420
1421 // Preconnect a socket.
1422 net::SSLConfig ssl_config;
1423 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231424 session->GetNextProtos(&ssl_config.next_protos);
[email protected]a34f61ee2014-03-18 20:59:491425 session->http_stream_factory()->PreconnectStreams(
1426 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1427 // Wait for the preconnect to complete.
1428 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1429 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101430 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491431
1432 // Make the request.
1433 TestCompletionCallback callback;
1434
1435 scoped_ptr<HttpTransaction> trans(
1436 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1437
1438 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1439 EXPECT_EQ(ERR_IO_PENDING, rv);
1440
1441 rv = callback.WaitForResult();
1442 EXPECT_EQ(OK, rv);
1443
1444 LoadTimingInfo load_timing_info;
1445 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101446 TestLoadTimingNotReused(
1447 load_timing_info,
1448 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491449
1450 const HttpResponseInfo* response = trans->GetResponseInfo();
1451 ASSERT_TRUE(response != NULL);
1452
1453 EXPECT_TRUE(response->headers.get() != NULL);
1454 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1455
1456 std::string response_data;
1457 rv = ReadTransaction(trans.get(), &response_data);
1458 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101459 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491460}
1461
[email protected]23e482282013-06-14 16:08:021462TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231463 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061464 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511465 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1466}
1467
[email protected]23e482282013-06-14 16:08:021468TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061469 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511470 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251471}
1472
[email protected]23e482282013-06-14 16:08:021473TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061474 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511475 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251476}
1477
[email protected]d58ceea82014-06-04 10:55:541478// Make sure that on a 408 response (Request Timeout), the request is retried,
1479// if the socket was a reused keep alive socket.
1480TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1481 MockRead read_failure(SYNCHRONOUS,
1482 "HTTP/1.1 408 Request Timeout\r\n"
1483 "Connection: Keep-Alive\r\n"
1484 "Content-Length: 6\r\n\r\n"
1485 "Pickle");
1486 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1487}
1488
[email protected]a34f61ee2014-03-18 20:59:491489TEST_P(HttpNetworkTransactionTest,
1490 PreconnectErrorNotConnectedOnWrite) {
1491 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101492 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491493}
1494
1495TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1496 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101497 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491498}
1499
1500TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1501 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101502 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1503}
1504
1505TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1506 MockRead read_failure(ASYNC, OK); // EOF
1507 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1508}
1509
[email protected]d58ceea82014-06-04 10:55:541510// Make sure that on a 408 response (Request Timeout), the request is retried,
1511// if the socket was a preconnected (UNUSED_IDLE) socket.
1512TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1513 MockRead read_failure(SYNCHRONOUS,
1514 "HTTP/1.1 408 Request Timeout\r\n"
1515 "Connection: Keep-Alive\r\n"
1516 "Content-Length: 6\r\n\r\n"
1517 "Pickle");
1518 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1519 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1520}
1521
[email protected]09356c652014-03-25 15:36:101522TEST_P(HttpNetworkTransactionTest,
1523 SpdyPreconnectErrorNotConnectedOnWrite) {
1524 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1525 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1526}
1527
1528TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1529 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1530 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1531}
1532
1533TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1534 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1535 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1536}
1537
1538TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1539 MockRead read_failure(ASYNC, OK); // EOF
1540 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491541}
1542
[email protected]23e482282013-06-14 16:08:021543TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421544 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251545 request.method = "GET";
1546 request.url = GURL("http://www.google.com/");
1547 request.load_flags = 0;
1548
[email protected]3fe8d2f82013-10-17 08:56:071549 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271550 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071551 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271552
[email protected]3d2a59b2008-09-26 19:44:251553 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061554 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351555 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1556 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061557 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251558 };
[email protected]31a2bfe2010-02-09 08:03:391559 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071560 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251561
[email protected]49639fa2011-12-20 23:22:411562 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251563
[email protected]49639fa2011-12-20 23:22:411564 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421565 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251566
1567 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421568 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251569
[email protected]1c773ea12009-04-28 19:58:421570 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251571 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251572}
1573
1574// What do various browsers do when the server closes a non-keepalive
1575// connection without sending any response header or body?
1576//
1577// IE7: error page
1578// Safari 3.1.2 (Windows): error page
1579// Firefox 3.0.1: blank page
1580// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421581// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1582// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021583TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251584 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061585 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351586 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1587 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061588 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251589 };
[email protected]31a2bfe2010-02-09 08:03:391590 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1591 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421592 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251593}
[email protected]038e9a32008-10-08 22:40:161594
[email protected]1826a402014-01-08 15:40:481595// Test that network access can be deferred and resumed.
1596TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1597 HttpRequestInfo request;
1598 request.method = "GET";
1599 request.url = GURL("http://www.google.com/");
1600 request.load_flags = 0;
1601
1602 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1603 scoped_ptr<HttpTransaction> trans(
1604 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1605
1606 // Defer on OnBeforeNetworkStart.
1607 BeforeNetworkStartHandler net_start_handler(true); // defer
1608 trans->SetBeforeNetworkStartCallback(
1609 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1610 base::Unretained(&net_start_handler)));
1611
1612 MockRead data_reads[] = {
1613 MockRead("HTTP/1.0 200 OK\r\n"),
1614 MockRead("Content-Length: 5\r\n\r\n"),
1615 MockRead("hello"),
1616 MockRead(SYNCHRONOUS, 0),
1617 };
1618 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1619 session_deps_.socket_factory->AddSocketDataProvider(&data);
1620
1621 TestCompletionCallback callback;
1622
1623 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1624 EXPECT_EQ(ERR_IO_PENDING, rv);
1625 base::MessageLoop::current()->RunUntilIdle();
1626
1627 // Should have deferred for network start.
1628 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1629 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1630 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1631
1632 trans->ResumeNetworkStart();
1633 rv = callback.WaitForResult();
1634 EXPECT_EQ(OK, rv);
1635 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1636
1637 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1638 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1639 if (rv == ERR_IO_PENDING)
1640 rv = callback.WaitForResult();
1641 EXPECT_EQ(5, rv);
1642 trans.reset();
1643}
1644
1645// Test that network use can be deferred and canceled.
1646TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1647 HttpRequestInfo request;
1648 request.method = "GET";
1649 request.url = GURL("http://www.google.com/");
1650 request.load_flags = 0;
1651
1652 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1653 scoped_ptr<HttpTransaction> trans(
1654 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1655
1656 // Defer on OnBeforeNetworkStart.
1657 BeforeNetworkStartHandler net_start_handler(true); // defer
1658 trans->SetBeforeNetworkStartCallback(
1659 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1660 base::Unretained(&net_start_handler)));
1661
1662 TestCompletionCallback callback;
1663
1664 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1665 EXPECT_EQ(ERR_IO_PENDING, rv);
1666 base::MessageLoop::current()->RunUntilIdle();
1667
1668 // Should have deferred for network start.
1669 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1670 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1671 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1672}
1673
[email protected]7a5378b2012-11-04 03:25:171674// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1675// tests. There was a bug causing HttpNetworkTransaction to hang in the
1676// destructor in such situations.
1677// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021678TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171679 HttpRequestInfo request;
1680 request.method = "GET";
1681 request.url = GURL("http://www.google.com/");
1682 request.load_flags = 0;
1683
[email protected]bb88e1d32013-05-03 23:11:071684 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361685 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501686 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171687
1688 MockRead data_reads[] = {
1689 MockRead("HTTP/1.0 200 OK\r\n"),
1690 MockRead("Connection: keep-alive\r\n"),
1691 MockRead("Content-Length: 100\r\n\r\n"),
1692 MockRead("hello"),
1693 MockRead(SYNCHRONOUS, 0),
1694 };
1695 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071696 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171697
1698 TestCompletionCallback callback;
1699
1700 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1701 EXPECT_EQ(ERR_IO_PENDING, rv);
1702
1703 rv = callback.WaitForResult();
1704 EXPECT_EQ(OK, rv);
1705
1706 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501707 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171708 if (rv == ERR_IO_PENDING)
1709 rv = callback.WaitForResult();
1710 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501711 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171712 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1713
1714 trans.reset();
[email protected]2da659e2013-05-23 20:51:341715 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171716 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1717}
1718
[email protected]23e482282013-06-14 16:08:021719TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171720 HttpRequestInfo request;
1721 request.method = "GET";
1722 request.url = GURL("http://www.google.com/");
1723 request.load_flags = 0;
1724
[email protected]bb88e1d32013-05-03 23:11:071725 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361726 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501727 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171728
1729 MockRead data_reads[] = {
1730 MockRead("HTTP/1.0 200 OK\r\n"),
1731 MockRead("Connection: keep-alive\r\n"),
1732 MockRead("Content-Length: 100\r\n\r\n"),
1733 MockRead(SYNCHRONOUS, 0),
1734 };
1735 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071736 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171737
1738 TestCompletionCallback callback;
1739
1740 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1741 EXPECT_EQ(ERR_IO_PENDING, rv);
1742
1743 rv = callback.WaitForResult();
1744 EXPECT_EQ(OK, rv);
1745
1746 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501747 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171748 if (rv == ERR_IO_PENDING)
1749 rv = callback.WaitForResult();
1750 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1751
1752 trans.reset();
[email protected]2da659e2013-05-23 20:51:341753 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171754 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1755}
1756
[email protected]0b0bf032010-09-21 18:08:501757// Test that we correctly reuse a keep-alive connection after not explicitly
1758// reading the body.
[email protected]23e482282013-06-14 16:08:021759TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131760 HttpRequestInfo request;
1761 request.method = "GET";
1762 request.url = GURL("http://www.foo.com/");
1763 request.load_flags = 0;
1764
[email protected]58e32bb2013-01-21 18:23:251765 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071766 session_deps_.net_log = &net_log;
1767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271768
[email protected]0b0bf032010-09-21 18:08:501769 // Note that because all these reads happen in the same
1770 // StaticSocketDataProvider, it shows that the same socket is being reused for
1771 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131772 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501773 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1774 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131775 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501776 MockRead("HTTP/1.1 302 Found\r\n"
1777 "Content-Length: 0\r\n\r\n"),
1778 MockRead("HTTP/1.1 302 Found\r\n"
1779 "Content-Length: 5\r\n\r\n"
1780 "hello"),
1781 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1782 "Content-Length: 0\r\n\r\n"),
1783 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1784 "Content-Length: 5\r\n\r\n"
1785 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131786 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1787 MockRead("hello"),
1788 };
1789 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071790 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131791
1792 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061793 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131794 };
1795 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071796 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131797
[email protected]0b0bf032010-09-21 18:08:501798 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1799 std::string response_lines[kNumUnreadBodies];
1800
[email protected]58e32bb2013-01-21 18:23:251801 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501802 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411803 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131804
[email protected]262eec82013-03-19 21:01:361805 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501806 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131807
[email protected]49639fa2011-12-20 23:22:411808 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131809 EXPECT_EQ(ERR_IO_PENDING, rv);
1810
1811 rv = callback.WaitForResult();
1812 EXPECT_EQ(OK, rv);
1813
[email protected]58e32bb2013-01-21 18:23:251814 LoadTimingInfo load_timing_info;
1815 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1816 if (i == 0) {
1817 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1818 first_socket_log_id = load_timing_info.socket_log_id;
1819 } else {
1820 TestLoadTimingReused(load_timing_info);
1821 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1822 }
1823
[email protected]fc31d6a42010-06-24 18:05:131824 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501825 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131826
[email protected]90499482013-06-01 00:39:501827 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501828 response_lines[i] = response->headers->GetStatusLine();
1829
1830 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131831 }
[email protected]0b0bf032010-09-21 18:08:501832
1833 const char* const kStatusLines[] = {
1834 "HTTP/1.1 204 No Content",
1835 "HTTP/1.1 205 Reset Content",
1836 "HTTP/1.1 304 Not Modified",
1837 "HTTP/1.1 302 Found",
1838 "HTTP/1.1 302 Found",
1839 "HTTP/1.1 301 Moved Permanently",
1840 "HTTP/1.1 301 Moved Permanently",
1841 };
1842
1843 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1844 forgot_to_update_kStatusLines);
1845
1846 for (int i = 0; i < kNumUnreadBodies; ++i)
1847 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1848
[email protected]49639fa2011-12-20 23:22:411849 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361850 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411852 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501853 EXPECT_EQ(ERR_IO_PENDING, rv);
1854 rv = callback.WaitForResult();
1855 EXPECT_EQ(OK, rv);
1856 const HttpResponseInfo* response = trans->GetResponseInfo();
1857 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501858 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501859 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1860 std::string response_data;
1861 rv = ReadTransaction(trans.get(), &response_data);
1862 EXPECT_EQ(OK, rv);
1863 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131864}
1865
[email protected]038e9a32008-10-08 22:40:161866// Test the request-challenge-retry sequence for basic auth.
1867// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021868TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421869 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161870 request.method = "GET";
1871 request.url = GURL("http://www.google.com/");
1872 request.load_flags = 0;
1873
[email protected]58e32bb2013-01-21 18:23:251874 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071875 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271877 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271879
[email protected]f9ee6b52008-11-08 06:46:231880 MockWrite data_writes1[] = {
1881 MockWrite("GET / HTTP/1.1\r\n"
1882 "Host: www.google.com\r\n"
1883 "Connection: keep-alive\r\n\r\n"),
1884 };
1885
[email protected]038e9a32008-10-08 22:40:161886 MockRead data_reads1[] = {
1887 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1888 // Give a couple authenticate options (only the middle one is actually
1889 // supported).
[email protected]22927ad2009-09-21 19:56:191890 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161891 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1892 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1893 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1894 // Large content-length -- won't matter, as connection will be reset.
1895 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061896 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161897 };
1898
1899 // After calling trans->RestartWithAuth(), this is the request we should
1900 // be issuing -- the final header line contains the credentials.
1901 MockWrite data_writes2[] = {
1902 MockWrite("GET / HTTP/1.1\r\n"
1903 "Host: www.google.com\r\n"
1904 "Connection: keep-alive\r\n"
1905 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1906 };
1907
1908 // Lastly, the server responds with the actual content.
1909 MockRead data_reads2[] = {
1910 MockRead("HTTP/1.0 200 OK\r\n"),
1911 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1912 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061913 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161914 };
1915
[email protected]31a2bfe2010-02-09 08:03:391916 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1917 data_writes1, arraysize(data_writes1));
1918 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1919 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071920 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1921 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161922
[email protected]49639fa2011-12-20 23:22:411923 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161924
[email protected]49639fa2011-12-20 23:22:411925 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421926 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161927
1928 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421929 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161930
[email protected]58e32bb2013-01-21 18:23:251931 LoadTimingInfo load_timing_info1;
1932 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1933 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1934
[email protected]b8015c42013-12-24 15:18:191935 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1936 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1937
[email protected]1c773ea12009-04-28 19:58:421938 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501939 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041940 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161941
[email protected]49639fa2011-12-20 23:22:411942 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161943
[email protected]49639fa2011-12-20 23:22:411944 rv = trans->RestartWithAuth(
1945 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421946 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161947
1948 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421949 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161950
[email protected]58e32bb2013-01-21 18:23:251951 LoadTimingInfo load_timing_info2;
1952 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1953 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1954 // The load timing after restart should have a new socket ID, and times after
1955 // those of the first load timing.
1956 EXPECT_LE(load_timing_info1.receive_headers_end,
1957 load_timing_info2.connect_timing.connect_start);
1958 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1959
[email protected]b8015c42013-12-24 15:18:191960 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1961 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1962
[email protected]038e9a32008-10-08 22:40:161963 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501964 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161965 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1966 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161967}
1968
[email protected]23e482282013-06-14 16:08:021969TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461970 HttpRequestInfo request;
1971 request.method = "GET";
1972 request.url = GURL("http://www.google.com/");
1973 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1974
[email protected]3fe8d2f82013-10-17 08:56:071975 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271976 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071977 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271978
[email protected]861fcd52009-08-26 02:33:461979 MockWrite data_writes[] = {
1980 MockWrite("GET / HTTP/1.1\r\n"
1981 "Host: www.google.com\r\n"
1982 "Connection: keep-alive\r\n\r\n"),
1983 };
1984
1985 MockRead data_reads[] = {
1986 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1987 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1988 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1989 // Large content-length -- won't matter, as connection will be reset.
1990 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061991 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461992 };
1993
[email protected]31a2bfe2010-02-09 08:03:391994 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1995 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071996 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411997 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461998
[email protected]49639fa2011-12-20 23:22:411999 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462000 EXPECT_EQ(ERR_IO_PENDING, rv);
2001
2002 rv = callback.WaitForResult();
2003 EXPECT_EQ(0, rv);
2004
[email protected]b8015c42013-12-24 15:18:192005 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2006 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2007
[email protected]861fcd52009-08-26 02:33:462008 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502009 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462010 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2011}
2012
[email protected]2d2697f92009-02-18 21:00:322013// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2014// connection.
[email protected]23e482282013-06-14 16:08:022015TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422016 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322017 request.method = "GET";
2018 request.url = GURL("http://www.google.com/");
2019 request.load_flags = 0;
2020
[email protected]58e32bb2013-01-21 18:23:252021 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072022 session_deps_.net_log = &log;
2023 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272024
[email protected]2d2697f92009-02-18 21:00:322025 MockWrite data_writes1[] = {
2026 MockWrite("GET / HTTP/1.1\r\n"
2027 "Host: www.google.com\r\n"
2028 "Connection: keep-alive\r\n\r\n"),
2029
2030 // After calling trans->RestartWithAuth(), this is the request we should
2031 // be issuing -- the final header line contains the credentials.
2032 MockWrite("GET / HTTP/1.1\r\n"
2033 "Host: www.google.com\r\n"
2034 "Connection: keep-alive\r\n"
2035 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2036 };
2037
2038 MockRead data_reads1[] = {
2039 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2040 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2041 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2042 MockRead("Content-Length: 14\r\n\r\n"),
2043 MockRead("Unauthorized\r\n"),
2044
2045 // Lastly, the server responds with the actual content.
2046 MockRead("HTTP/1.1 200 OK\r\n"),
2047 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502048 MockRead("Content-Length: 5\r\n\r\n"),
2049 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322050 };
2051
[email protected]2d0a4f92011-05-05 16:38:462052 // If there is a regression where we disconnect a Keep-Alive
2053 // connection during an auth roundtrip, we'll end up reading this.
2054 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062055 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462056 };
2057
[email protected]31a2bfe2010-02-09 08:03:392058 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2059 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462060 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2061 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072062 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2063 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322064
[email protected]49639fa2011-12-20 23:22:412065 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322066
[email protected]262eec82013-03-19 21:01:362067 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502068 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412069 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422070 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322071
2072 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422073 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322074
[email protected]58e32bb2013-01-21 18:23:252075 LoadTimingInfo load_timing_info1;
2076 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2077 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2078
[email protected]1c773ea12009-04-28 19:58:422079 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502080 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042081 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322082
[email protected]49639fa2011-12-20 23:22:412083 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322084
[email protected]49639fa2011-12-20 23:22:412085 rv = trans->RestartWithAuth(
2086 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422087 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322088
2089 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422090 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322091
[email protected]58e32bb2013-01-21 18:23:252092 LoadTimingInfo load_timing_info2;
2093 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2094 TestLoadTimingReused(load_timing_info2);
2095 // The load timing after restart should have the same socket ID, and times
2096 // those of the first load timing.
2097 EXPECT_LE(load_timing_info1.receive_headers_end,
2098 load_timing_info2.send_start);
2099 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2100
[email protected]2d2697f92009-02-18 21:00:322101 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502102 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322103 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502104 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192105
2106 std::string response_data;
2107 rv = ReadTransaction(trans.get(), &response_data);
2108 EXPECT_EQ(OK, rv);
2109 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2110 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322111}
2112
2113// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2114// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022115TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422116 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322117 request.method = "GET";
2118 request.url = GURL("http://www.google.com/");
2119 request.load_flags = 0;
2120
[email protected]bb88e1d32013-05-03 23:11:072121 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272122
[email protected]2d2697f92009-02-18 21:00:322123 MockWrite data_writes1[] = {
2124 MockWrite("GET / HTTP/1.1\r\n"
2125 "Host: www.google.com\r\n"
2126 "Connection: keep-alive\r\n\r\n"),
2127
2128 // After calling trans->RestartWithAuth(), this is the request we should
2129 // be issuing -- the final header line contains the credentials.
2130 MockWrite("GET / HTTP/1.1\r\n"
2131 "Host: www.google.com\r\n"
2132 "Connection: keep-alive\r\n"
2133 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2134 };
2135
[email protected]2d2697f92009-02-18 21:00:322136 MockRead data_reads1[] = {
2137 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2138 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312139 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322140
2141 // Lastly, the server responds with the actual content.
2142 MockRead("HTTP/1.1 200 OK\r\n"),
2143 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502144 MockRead("Content-Length: 5\r\n\r\n"),
2145 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322146 };
2147
[email protected]2d0a4f92011-05-05 16:38:462148 // An incorrect reconnect would cause this to be read.
2149 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062150 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462151 };
2152
[email protected]31a2bfe2010-02-09 08:03:392153 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2154 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462155 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2156 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072157 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2158 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322159
[email protected]49639fa2011-12-20 23:22:412160 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322161
[email protected]262eec82013-03-19 21:01:362162 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502163 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412164 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422165 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322166
2167 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422168 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322169
[email protected]1c773ea12009-04-28 19:58:422170 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502171 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042172 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322173
[email protected]49639fa2011-12-20 23:22:412174 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322175
[email protected]49639fa2011-12-20 23:22:412176 rv = trans->RestartWithAuth(
2177 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422178 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322179
2180 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422181 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322182
2183 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502184 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322185 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502186 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322187}
2188
2189// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2190// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022191TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422192 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322193 request.method = "GET";
2194 request.url = GURL("http://www.google.com/");
2195 request.load_flags = 0;
2196
[email protected]bb88e1d32013-05-03 23:11:072197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272198
[email protected]2d2697f92009-02-18 21:00:322199 MockWrite data_writes1[] = {
2200 MockWrite("GET / HTTP/1.1\r\n"
2201 "Host: www.google.com\r\n"
2202 "Connection: keep-alive\r\n\r\n"),
2203
2204 // After calling trans->RestartWithAuth(), this is the request we should
2205 // be issuing -- the final header line contains the credentials.
2206 MockWrite("GET / HTTP/1.1\r\n"
2207 "Host: www.google.com\r\n"
2208 "Connection: keep-alive\r\n"
2209 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2210 };
2211
2212 // Respond with 5 kb of response body.
2213 std::string large_body_string("Unauthorized");
2214 large_body_string.append(5 * 1024, ' ');
2215 large_body_string.append("\r\n");
2216
2217 MockRead data_reads1[] = {
2218 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2219 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2220 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2221 // 5134 = 12 + 5 * 1024 + 2
2222 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062223 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322224
2225 // Lastly, the server responds with the actual content.
2226 MockRead("HTTP/1.1 200 OK\r\n"),
2227 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502228 MockRead("Content-Length: 5\r\n\r\n"),
2229 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322230 };
2231
[email protected]2d0a4f92011-05-05 16:38:462232 // An incorrect reconnect would cause this to be read.
2233 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062234 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462235 };
2236
[email protected]31a2bfe2010-02-09 08:03:392237 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2238 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462239 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2240 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072241 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2242 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322243
[email protected]49639fa2011-12-20 23:22:412244 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322245
[email protected]262eec82013-03-19 21:01:362246 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412248 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422249 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322250
2251 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422252 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322253
[email protected]1c773ea12009-04-28 19:58:422254 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502255 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042256 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322257
[email protected]49639fa2011-12-20 23:22:412258 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322259
[email protected]49639fa2011-12-20 23:22:412260 rv = trans->RestartWithAuth(
2261 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422262 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322263
2264 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422265 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322266
2267 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502268 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322269 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502270 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322271}
2272
2273// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312274// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022275TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312276 HttpRequestInfo request;
2277 request.method = "GET";
2278 request.url = GURL("http://www.google.com/");
2279 request.load_flags = 0;
2280
[email protected]bb88e1d32013-05-03 23:11:072281 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272282
[email protected]11203f012009-11-12 23:02:312283 MockWrite data_writes1[] = {
2284 MockWrite("GET / HTTP/1.1\r\n"
2285 "Host: www.google.com\r\n"
2286 "Connection: keep-alive\r\n\r\n"),
2287 // This simulates the seemingly successful write to a closed connection
2288 // if the bug is not fixed.
2289 MockWrite("GET / HTTP/1.1\r\n"
2290 "Host: www.google.com\r\n"
2291 "Connection: keep-alive\r\n"
2292 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2293 };
2294
2295 MockRead data_reads1[] = {
2296 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2297 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2298 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2299 MockRead("Content-Length: 14\r\n\r\n"),
2300 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062301 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312302 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062303 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312304 };
2305
2306 // After calling trans->RestartWithAuth(), this is the request we should
2307 // be issuing -- the final header line contains the credentials.
2308 MockWrite data_writes2[] = {
2309 MockWrite("GET / HTTP/1.1\r\n"
2310 "Host: www.google.com\r\n"
2311 "Connection: keep-alive\r\n"
2312 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2313 };
2314
2315 // Lastly, the server responds with the actual content.
2316 MockRead data_reads2[] = {
2317 MockRead("HTTP/1.1 200 OK\r\n"),
2318 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502319 MockRead("Content-Length: 5\r\n\r\n"),
2320 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312321 };
2322
[email protected]31a2bfe2010-02-09 08:03:392323 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2324 data_writes1, arraysize(data_writes1));
2325 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2326 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2328 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312329
[email protected]49639fa2011-12-20 23:22:412330 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312331
[email protected]262eec82013-03-19 21:01:362332 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412334 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312335 EXPECT_EQ(ERR_IO_PENDING, rv);
2336
2337 rv = callback1.WaitForResult();
2338 EXPECT_EQ(OK, rv);
2339
2340 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502341 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042342 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312343
[email protected]49639fa2011-12-20 23:22:412344 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312345
[email protected]49639fa2011-12-20 23:22:412346 rv = trans->RestartWithAuth(
2347 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312348 EXPECT_EQ(ERR_IO_PENDING, rv);
2349
2350 rv = callback2.WaitForResult();
2351 EXPECT_EQ(OK, rv);
2352
2353 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502354 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312355 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502356 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312357}
2358
[email protected]394816e92010-08-03 07:38:592359// Test the request-challenge-retry sequence for basic auth, over a connection
2360// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022361TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:592362 HttpRequestInfo request;
2363 request.method = "GET";
2364 request.url = GURL("https://www.google.com/");
2365 // when the no authentication data flag is set.
2366 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2367
[email protected]cb9bf6ca2011-01-28 13:15:272368 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072369 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202370 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292371 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072372 session_deps_.net_log = log.bound().net_log();
2373 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272374
[email protected]394816e92010-08-03 07:38:592375 // Since we have proxy, should try to establish tunnel.
2376 MockWrite data_writes1[] = {
2377 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2378 "Host: www.google.com\r\n"
2379 "Proxy-Connection: keep-alive\r\n\r\n"),
2380
2381 // After calling trans->RestartWithAuth(), this is the request we should
2382 // be issuing -- the final header line contains the credentials.
2383 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2384 "Host: www.google.com\r\n"
2385 "Proxy-Connection: keep-alive\r\n"
2386 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2387
2388 MockWrite("GET / HTTP/1.1\r\n"
2389 "Host: www.google.com\r\n"
2390 "Connection: keep-alive\r\n\r\n"),
2391 };
2392
2393 // The proxy responds to the connect with a 407, using a persistent
2394 // connection.
2395 MockRead data_reads1[] = {
2396 // No credentials.
2397 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2398 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2399 MockRead("Proxy-Connection: close\r\n\r\n"),
2400
2401 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2402
2403 MockRead("HTTP/1.1 200 OK\r\n"),
2404 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502405 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062406 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592407 };
2408
2409 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2410 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072411 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062412 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072413 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592414
[email protected]49639fa2011-12-20 23:22:412415 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592416
[email protected]262eec82013-03-19 21:01:362417 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502418 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502419
[email protected]49639fa2011-12-20 23:22:412420 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592421 EXPECT_EQ(ERR_IO_PENDING, rv);
2422
2423 rv = callback1.WaitForResult();
2424 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572425 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402426 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592427 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402428 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592429 NetLog::PHASE_NONE);
2430 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402431 entries, pos,
[email protected]394816e92010-08-03 07:38:592432 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2433 NetLog::PHASE_NONE);
2434
2435 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502436 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502437 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592438 EXPECT_EQ(407, response->headers->response_code());
2439 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042440 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592441
[email protected]029c83b62013-01-24 05:28:202442 LoadTimingInfo load_timing_info;
2443 // CONNECT requests and responses are handled at the connect job level, so
2444 // the transaction does not yet have a connection.
2445 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2446
[email protected]49639fa2011-12-20 23:22:412447 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592448
[email protected]49639fa2011-12-20 23:22:412449 rv = trans->RestartWithAuth(
2450 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592451 EXPECT_EQ(ERR_IO_PENDING, rv);
2452
2453 rv = callback2.WaitForResult();
2454 EXPECT_EQ(OK, rv);
2455
2456 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502457 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592458
2459 EXPECT_TRUE(response->headers->IsKeepAlive());
2460 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502461 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592462 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2463
2464 // The password prompt info should not be set.
2465 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502466
[email protected]029c83b62013-01-24 05:28:202467 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2468 TestLoadTimingNotReusedWithPac(load_timing_info,
2469 CONNECT_TIMING_HAS_SSL_TIMES);
2470
[email protected]0b0bf032010-09-21 18:08:502471 trans.reset();
[email protected]102e27c2011-02-23 01:01:312472 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592473}
2474
[email protected]11203f012009-11-12 23:02:312475// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322476// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022477TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272478 HttpRequestInfo request;
2479 request.method = "GET";
2480 request.url = GURL("https://www.google.com/");
2481 // Ensure that proxy authentication is attempted even
2482 // when the no authentication data flag is set.
2483 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2484
[email protected]2d2697f92009-02-18 21:00:322485 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072486 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292487 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072488 session_deps_.net_log = log.bound().net_log();
2489 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322490
[email protected]262eec82013-03-19 21:01:362491 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502492 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322493
[email protected]2d2697f92009-02-18 21:00:322494 // Since we have proxy, should try to establish tunnel.
2495 MockWrite data_writes1[] = {
2496 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452497 "Host: www.google.com\r\n"
2498 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322499
2500 // After calling trans->RestartWithAuth(), this is the request we should
2501 // be issuing -- the final header line contains the credentials.
2502 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2503 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452504 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322505 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2506 };
2507
2508 // The proxy responds to the connect with a 407, using a persistent
2509 // connection.
2510 MockRead data_reads1[] = {
2511 // No credentials.
2512 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2513 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2514 MockRead("Content-Length: 10\r\n\r\n"),
2515 MockRead("0123456789"),
2516
2517 // Wrong credentials (wrong password).
2518 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2519 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2520 MockRead("Content-Length: 10\r\n\r\n"),
2521 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062522 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322523 };
2524
[email protected]31a2bfe2010-02-09 08:03:392525 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2526 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072527 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322528
[email protected]49639fa2011-12-20 23:22:412529 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322530
[email protected]49639fa2011-12-20 23:22:412531 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422532 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322533
2534 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422535 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572536 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402537 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392538 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402539 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392540 NetLog::PHASE_NONE);
2541 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402542 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392543 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2544 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322545
[email protected]1c773ea12009-04-28 19:58:422546 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502547 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502548 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322549 EXPECT_TRUE(response->headers->IsKeepAlive());
2550 EXPECT_EQ(407, response->headers->response_code());
2551 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422552 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042553 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322554
[email protected]49639fa2011-12-20 23:22:412555 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322556
2557 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412558 rv = trans->RestartWithAuth(
2559 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422560 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322561
2562 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422563 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322564
2565 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502566 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502567 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322568 EXPECT_TRUE(response->headers->IsKeepAlive());
2569 EXPECT_EQ(407, response->headers->response_code());
2570 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422571 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042572 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132573
[email protected]e60e47a2010-07-14 03:37:182574 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2575 // out of scope.
[email protected]102e27c2011-02-23 01:01:312576 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322577}
2578
[email protected]a8e9b162009-03-12 00:06:442579// Test that we don't read the response body when we fail to establish a tunnel,
2580// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022581TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272582 HttpRequestInfo request;
2583 request.method = "GET";
2584 request.url = GURL("https://www.google.com/");
2585 request.load_flags = 0;
2586
[email protected]a8e9b162009-03-12 00:06:442587 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072588 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442589
[email protected]bb88e1d32013-05-03 23:11:072590 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442591
[email protected]262eec82013-03-19 21:01:362592 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442594
[email protected]a8e9b162009-03-12 00:06:442595 // Since we have proxy, should try to establish tunnel.
2596 MockWrite data_writes[] = {
2597 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452598 "Host: www.google.com\r\n"
2599 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442600 };
2601
2602 // The proxy responds to the connect with a 407.
2603 MockRead data_reads[] = {
2604 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2605 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2606 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062607 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442608 };
2609
[email protected]31a2bfe2010-02-09 08:03:392610 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2611 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072612 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442613
[email protected]49639fa2011-12-20 23:22:412614 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442615
[email protected]49639fa2011-12-20 23:22:412616 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422617 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442618
2619 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422620 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442621
[email protected]1c773ea12009-04-28 19:58:422622 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502623 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442624
2625 EXPECT_TRUE(response->headers->IsKeepAlive());
2626 EXPECT_EQ(407, response->headers->response_code());
2627 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422628 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442629
2630 std::string response_data;
2631 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422632 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182633
2634 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312635 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442636}
2637
[email protected]8fdbcd22010-05-05 02:54:522638// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2639// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022640TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522641 HttpRequestInfo request;
2642 request.method = "GET";
2643 request.url = GURL("http://www.google.com/");
2644 request.load_flags = 0;
2645
[email protected]cb9bf6ca2011-01-28 13:15:272646 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072647 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272648 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:072649 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:272650
[email protected]8fdbcd22010-05-05 02:54:522651 MockWrite data_writes1[] = {
2652 MockWrite("GET / HTTP/1.1\r\n"
2653 "Host: www.google.com\r\n"
2654 "Connection: keep-alive\r\n\r\n"),
2655 };
2656
2657 MockRead data_reads1[] = {
2658 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2659 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2660 // Large content-length -- won't matter, as connection will be reset.
2661 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062662 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522663 };
2664
2665 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2666 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072667 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522668
[email protected]49639fa2011-12-20 23:22:412669 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522670
[email protected]49639fa2011-12-20 23:22:412671 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522672 EXPECT_EQ(ERR_IO_PENDING, rv);
2673
2674 rv = callback.WaitForResult();
2675 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2676}
2677
[email protected]7a67a8152010-11-05 18:31:102678// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2679// through a non-authenticating proxy. The request should fail with
2680// ERR_UNEXPECTED_PROXY_AUTH.
2681// Note that it is impossible to detect if an HTTP server returns a 407 through
2682// a non-authenticating proxy - there is nothing to indicate whether the
2683// response came from the proxy or the server, so it is treated as if the proxy
2684// issued the challenge.
[email protected]23e482282013-06-14 16:08:022685TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232686 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272687 HttpRequestInfo request;
2688 request.method = "GET";
2689 request.url = GURL("https://www.google.com/");
2690
[email protected]bb88e1d32013-05-03 23:11:072691 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292692 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072693 session_deps_.net_log = log.bound().net_log();
2694 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102695
[email protected]7a67a8152010-11-05 18:31:102696 // Since we have proxy, should try to establish tunnel.
2697 MockWrite data_writes1[] = {
2698 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2699 "Host: www.google.com\r\n"
2700 "Proxy-Connection: keep-alive\r\n\r\n"),
2701
2702 MockWrite("GET / HTTP/1.1\r\n"
2703 "Host: www.google.com\r\n"
2704 "Connection: keep-alive\r\n\r\n"),
2705 };
2706
2707 MockRead data_reads1[] = {
2708 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2709
2710 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2711 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2712 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062713 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102714 };
2715
2716 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2717 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072718 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062719 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102721
[email protected]49639fa2011-12-20 23:22:412722 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102723
[email protected]262eec82013-03-19 21:01:362724 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502725 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102726
[email protected]49639fa2011-12-20 23:22:412727 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102728 EXPECT_EQ(ERR_IO_PENDING, rv);
2729
2730 rv = callback1.WaitForResult();
2731 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572732 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402733 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102734 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402735 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102736 NetLog::PHASE_NONE);
2737 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402738 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102739 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2740 NetLog::PHASE_NONE);
2741}
[email protected]2df19bb2010-08-25 20:13:462742
[email protected]029c83b62013-01-24 05:28:202743// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022744TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202745 HttpRequestInfo request1;
2746 request1.method = "GET";
2747 request1.url = GURL("https://www.google.com/1");
2748
2749 HttpRequestInfo request2;
2750 request2.method = "GET";
2751 request2.url = GURL("https://www.google.com/2");
2752
2753 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072754 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202755 ProxyService::CreateFixed("PROXY myproxy:70"));
2756 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072757 session_deps_.net_log = log.bound().net_log();
2758 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202759
2760 // Since we have proxy, should try to establish tunnel.
2761 MockWrite data_writes1[] = {
2762 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2763 "Host: www.google.com\r\n"
2764 "Proxy-Connection: keep-alive\r\n\r\n"),
2765
2766 MockWrite("GET /1 HTTP/1.1\r\n"
2767 "Host: www.google.com\r\n"
2768 "Connection: keep-alive\r\n\r\n"),
2769
2770 MockWrite("GET /2 HTTP/1.1\r\n"
2771 "Host: www.google.com\r\n"
2772 "Connection: keep-alive\r\n\r\n"),
2773 };
2774
2775 // The proxy responds to the connect with a 407, using a persistent
2776 // connection.
2777 MockRead data_reads1[] = {
2778 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2779
2780 MockRead("HTTP/1.1 200 OK\r\n"),
2781 MockRead("Content-Length: 1\r\n\r\n"),
2782 MockRead(SYNCHRONOUS, "1"),
2783
2784 MockRead("HTTP/1.1 200 OK\r\n"),
2785 MockRead("Content-Length: 2\r\n\r\n"),
2786 MockRead(SYNCHRONOUS, "22"),
2787 };
2788
2789 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2790 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072791 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202792 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202794
2795 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362796 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502797 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202798
2799 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2800 EXPECT_EQ(ERR_IO_PENDING, rv);
2801
2802 rv = callback1.WaitForResult();
2803 EXPECT_EQ(OK, rv);
2804
2805 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2806 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502807 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202808 EXPECT_EQ(1, response1->headers->GetContentLength());
2809
2810 LoadTimingInfo load_timing_info1;
2811 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2812 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2813
2814 trans1.reset();
2815
2816 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362817 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202819
2820 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2821 EXPECT_EQ(ERR_IO_PENDING, rv);
2822
2823 rv = callback2.WaitForResult();
2824 EXPECT_EQ(OK, rv);
2825
2826 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2827 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502828 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202829 EXPECT_EQ(2, response2->headers->GetContentLength());
2830
2831 LoadTimingInfo load_timing_info2;
2832 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2833 TestLoadTimingReused(load_timing_info2);
2834
2835 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2836
2837 trans2.reset();
2838 session->CloseAllConnections();
2839}
2840
2841// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022842TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202843 HttpRequestInfo request1;
2844 request1.method = "GET";
2845 request1.url = GURL("https://www.google.com/1");
2846
2847 HttpRequestInfo request2;
2848 request2.method = "GET";
2849 request2.url = GURL("https://www.google.com/2");
2850
2851 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072852 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202853 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2854 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072855 session_deps_.net_log = log.bound().net_log();
2856 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202857
2858 // Since we have proxy, should try to establish tunnel.
2859 MockWrite data_writes1[] = {
2860 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2861 "Host: www.google.com\r\n"
2862 "Proxy-Connection: keep-alive\r\n\r\n"),
2863
2864 MockWrite("GET /1 HTTP/1.1\r\n"
2865 "Host: www.google.com\r\n"
2866 "Connection: keep-alive\r\n\r\n"),
2867
2868 MockWrite("GET /2 HTTP/1.1\r\n"
2869 "Host: www.google.com\r\n"
2870 "Connection: keep-alive\r\n\r\n"),
2871 };
2872
2873 // The proxy responds to the connect with a 407, using a persistent
2874 // connection.
2875 MockRead data_reads1[] = {
2876 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2877
2878 MockRead("HTTP/1.1 200 OK\r\n"),
2879 MockRead("Content-Length: 1\r\n\r\n"),
2880 MockRead(SYNCHRONOUS, "1"),
2881
2882 MockRead("HTTP/1.1 200 OK\r\n"),
2883 MockRead("Content-Length: 2\r\n\r\n"),
2884 MockRead(SYNCHRONOUS, "22"),
2885 };
2886
2887 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2888 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072889 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202890 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202892
2893 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362894 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502895 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202896
2897 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2898 EXPECT_EQ(ERR_IO_PENDING, rv);
2899
2900 rv = callback1.WaitForResult();
2901 EXPECT_EQ(OK, rv);
2902
2903 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2904 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502905 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202906 EXPECT_EQ(1, response1->headers->GetContentLength());
2907
2908 LoadTimingInfo load_timing_info1;
2909 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2910 TestLoadTimingNotReusedWithPac(load_timing_info1,
2911 CONNECT_TIMING_HAS_SSL_TIMES);
2912
2913 trans1.reset();
2914
2915 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362916 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502917 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202918
2919 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2920 EXPECT_EQ(ERR_IO_PENDING, rv);
2921
2922 rv = callback2.WaitForResult();
2923 EXPECT_EQ(OK, rv);
2924
2925 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2926 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502927 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202928 EXPECT_EQ(2, response2->headers->GetContentLength());
2929
2930 LoadTimingInfo load_timing_info2;
2931 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2932 TestLoadTimingReusedWithPac(load_timing_info2);
2933
2934 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2935
2936 trans2.reset();
2937 session->CloseAllConnections();
2938}
2939
[email protected]2df19bb2010-08-25 20:13:462940// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022941TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272942 HttpRequestInfo request;
2943 request.method = "GET";
2944 request.url = GURL("http://www.google.com/");
2945
[email protected]2df19bb2010-08-25 20:13:462946 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072947 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112948 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292949 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072950 session_deps_.net_log = log.bound().net_log();
2951 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462952
[email protected]2df19bb2010-08-25 20:13:462953 // Since we have proxy, should use full url
2954 MockWrite data_writes1[] = {
2955 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2956 "Host: www.google.com\r\n"
2957 "Proxy-Connection: keep-alive\r\n\r\n"),
2958 };
2959
2960 MockRead data_reads1[] = {
2961 MockRead("HTTP/1.1 200 OK\r\n"),
2962 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2963 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062964 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462965 };
2966
2967 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2968 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072969 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062970 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072971 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462972
[email protected]49639fa2011-12-20 23:22:412973 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462974
[email protected]262eec82013-03-19 21:01:362975 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502977
[email protected]49639fa2011-12-20 23:22:412978 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462979 EXPECT_EQ(ERR_IO_PENDING, rv);
2980
2981 rv = callback1.WaitForResult();
2982 EXPECT_EQ(OK, rv);
2983
[email protected]58e32bb2013-01-21 18:23:252984 LoadTimingInfo load_timing_info;
2985 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2986 TestLoadTimingNotReused(load_timing_info,
2987 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2988
[email protected]2df19bb2010-08-25 20:13:462989 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502990 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462991
2992 EXPECT_TRUE(response->headers->IsKeepAlive());
2993 EXPECT_EQ(200, response->headers->response_code());
2994 EXPECT_EQ(100, response->headers->GetContentLength());
2995 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2996
2997 // The password prompt info should not be set.
2998 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2999}
3000
[email protected]7642b5ae2010-09-01 20:55:173001// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023002TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273003 HttpRequestInfo request;
3004 request.method = "GET";
3005 request.url = GURL("http://www.google.com/");
3006 request.load_flags = 0;
3007
[email protected]7642b5ae2010-09-01 20:55:173008 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073009 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113010 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293011 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073012 session_deps_.net_log = log.bound().net_log();
3013 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173014
[email protected]7642b5ae2010-09-01 20:55:173015 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463016 scoped_ptr<SpdyFrame> req(
3017 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:173018 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
3019
[email protected]23e482282013-06-14 16:08:023020 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3021 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173022 MockRead spdy_reads[] = {
3023 CreateMockRead(*resp),
3024 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:063025 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:173026 };
3027
[email protected]dd54bd82012-07-19 23:44:573028 DelayedSocketData spdy_data(
3029 1, // wait for one write to finish before reading.
3030 spdy_reads, arraysize(spdy_reads),
3031 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073032 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173033
[email protected]8ddf8322012-02-23 18:08:063034 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023035 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173037
[email protected]49639fa2011-12-20 23:22:413038 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173039
[email protected]262eec82013-03-19 21:01:363040 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503041 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503042
[email protected]49639fa2011-12-20 23:22:413043 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173044 EXPECT_EQ(ERR_IO_PENDING, rv);
3045
3046 rv = callback1.WaitForResult();
3047 EXPECT_EQ(OK, rv);
3048
[email protected]58e32bb2013-01-21 18:23:253049 LoadTimingInfo load_timing_info;
3050 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3051 TestLoadTimingNotReused(load_timing_info,
3052 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3053
[email protected]7642b5ae2010-09-01 20:55:173054 const HttpResponseInfo* response = trans->GetResponseInfo();
3055 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503056 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173057 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3058
3059 std::string response_data;
3060 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233061 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173062}
3063
[email protected]1c173852014-06-19 12:51:503064// Verifies that a session which races and wins against the owning transaction
3065// (completing prior to host resolution), doesn't fail the transaction.
3066// Regression test for crbug.com/334413.
3067TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3068 HttpRequestInfo request;
3069 request.method = "GET";
3070 request.url = GURL("http://www.google.com/");
3071 request.load_flags = 0;
3072
3073 // Configure SPDY proxy server "proxy:70".
3074 session_deps_.proxy_service.reset(
3075 ProxyService::CreateFixed("https://proxy:70"));
3076 CapturingBoundNetLog log;
3077 session_deps_.net_log = log.bound().net_log();
3078 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3079
3080 // Fetch http://www.google.com/ through the SPDY proxy.
3081 scoped_ptr<SpdyFrame> req(
3082 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3083 MockWrite spdy_writes[] = {CreateMockWrite(*req)};
3084
3085 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3086 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3087 MockRead spdy_reads[] = {
3088 CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
3089 };
3090
3091 DelayedSocketData spdy_data(
3092 1, // wait for one write to finish before reading.
3093 spdy_reads,
3094 arraysize(spdy_reads),
3095 spdy_writes,
3096 arraysize(spdy_writes));
3097 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3098
3099 SSLSocketDataProvider ssl(ASYNC, OK);
3100 ssl.SetNextProto(GetParam());
3101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3102
3103 TestCompletionCallback callback1;
3104
3105 scoped_ptr<HttpTransaction> trans(
3106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3107
3108 // Stall the hostname resolution begun by the transaction.
3109 session_deps_.host_resolver->set_synchronous_mode(false);
3110 session_deps_.host_resolver->set_ondemand_mode(true);
3111
3112 int rv = trans->Start(&request, callback1.callback(), log.bound());
3113 EXPECT_EQ(ERR_IO_PENDING, rv);
3114
3115 // Race a session to the proxy, which completes first.
3116 session_deps_.host_resolver->set_ondemand_mode(false);
3117 SpdySessionKey key(
3118 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3119 base::WeakPtr<SpdySession> spdy_session =
3120 CreateSecureSpdySession(session, key, log.bound());
3121
3122 // Unstall the resolution begun by the transaction.
3123 session_deps_.host_resolver->set_ondemand_mode(true);
3124 session_deps_.host_resolver->ResolveAllPending();
3125
3126 EXPECT_FALSE(callback1.have_result());
3127 rv = callback1.WaitForResult();
3128 EXPECT_EQ(OK, rv);
3129
3130 const HttpResponseInfo* response = trans->GetResponseInfo();
3131 ASSERT_TRUE(response != NULL);
3132 ASSERT_TRUE(response->headers.get() != NULL);
3133 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3134
3135 std::string response_data;
3136 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3137 EXPECT_EQ(kUploadData, response_data);
3138}
3139
[email protected]dc7bd1c52010-11-12 00:01:133140// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023141TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273142 HttpRequestInfo request;
3143 request.method = "GET";
3144 request.url = GURL("http://www.google.com/");
3145 request.load_flags = 0;
3146
[email protected]79cb5c12011-09-12 13:12:043147 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073148 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043149 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293150 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073151 session_deps_.net_log = log.bound().net_log();
3152 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133153
[email protected]dc7bd1c52010-11-12 00:01:133154 // The first request will be a bare GET, the second request will be a
3155 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193156 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463157 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133158 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463159 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133160 };
[email protected]ff98d7f02012-03-22 21:44:193161 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463162 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3163 arraysize(kExtraAuthorizationHeaders) / 2,
3164 false,
3165 3,
3166 LOWEST,
3167 false));
[email protected]dc7bd1c52010-11-12 00:01:133168 MockWrite spdy_writes[] = {
3169 CreateMockWrite(*req_get, 1),
3170 CreateMockWrite(*req_get_authorization, 4),
3171 };
3172
3173 // The first response is a 407 proxy authentication challenge, and the second
3174 // response will be a 200 response since the second request includes a valid
3175 // Authorization header.
3176 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463177 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133178 };
[email protected]ff98d7f02012-03-22 21:44:193179 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023180 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133181 "407 Proxy Authentication Required",
3182 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3183 1));
[email protected]ff98d7f02012-03-22 21:44:193184 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023185 spdy_util_.ConstructSpdyBodyFrame(1, true));
3186 scoped_ptr<SpdyFrame> resp_data(
3187 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3188 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133189 MockRead spdy_reads[] = {
3190 CreateMockRead(*resp_authentication, 2),
3191 CreateMockRead(*body_authentication, 3),
3192 CreateMockRead(*resp_data, 5),
3193 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:063194 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:133195 };
3196
[email protected]dd54bd82012-07-19 23:44:573197 OrderedSocketData data(
3198 spdy_reads, arraysize(spdy_reads),
3199 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073200 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133201
[email protected]8ddf8322012-02-23 18:08:063202 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023203 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133205
[email protected]49639fa2011-12-20 23:22:413206 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133207
[email protected]262eec82013-03-19 21:01:363208 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133210
[email protected]49639fa2011-12-20 23:22:413211 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133212 EXPECT_EQ(ERR_IO_PENDING, rv);
3213
3214 rv = callback1.WaitForResult();
3215 EXPECT_EQ(OK, rv);
3216
3217 const HttpResponseInfo* const response = trans->GetResponseInfo();
3218
3219 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503220 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133221 EXPECT_EQ(407, response->headers->response_code());
3222 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043223 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133224
[email protected]49639fa2011-12-20 23:22:413225 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133226
[email protected]49639fa2011-12-20 23:22:413227 rv = trans->RestartWithAuth(
3228 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133229 EXPECT_EQ(ERR_IO_PENDING, rv);
3230
3231 rv = callback2.WaitForResult();
3232 EXPECT_EQ(OK, rv);
3233
3234 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3235
3236 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503237 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133238 EXPECT_EQ(200, response_restart->headers->response_code());
3239 // The password prompt info should not be set.
3240 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3241}
3242
[email protected]d9da5fe2010-10-13 22:37:163243// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023244TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273245 HttpRequestInfo request;
3246 request.method = "GET";
3247 request.url = GURL("https://www.google.com/");
3248 request.load_flags = 0;
3249
[email protected]d9da5fe2010-10-13 22:37:163250 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073251 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113252 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293253 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073254 session_deps_.net_log = log.bound().net_log();
3255 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163256
[email protected]262eec82013-03-19 21:01:363257 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503258 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163259
[email protected]d9da5fe2010-10-13 22:37:163260 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543261 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3262 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163263 // fetch https://www.google.com/ via HTTP
3264
3265 const char get[] = "GET / HTTP/1.1\r\n"
3266 "Host: www.google.com\r\n"
3267 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193268 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023269 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3270 scoped_ptr<SpdyFrame> conn_resp(
3271 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163272 const char resp[] = "HTTP/1.1 200 OK\r\n"
3273 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193274 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023275 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193276 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023277 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193278 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203279 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043280
3281 MockWrite spdy_writes[] = {
3282 CreateMockWrite(*connect, 1),
3283 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:463284 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:043285 };
3286
[email protected]d9da5fe2010-10-13 22:37:163287 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063288 CreateMockRead(*conn_resp, 2, ASYNC),
3289 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3290 CreateMockRead(*wrapped_body, 6, ASYNC),
3291 CreateMockRead(*wrapped_body, 7, ASYNC),
3292 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163293 };
3294
[email protected]dd54bd82012-07-19 23:44:573295 OrderedSocketData spdy_data(
3296 spdy_reads, arraysize(spdy_reads),
3297 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073298 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163299
[email protected]8ddf8322012-02-23 18:08:063300 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023301 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063303 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163304 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463305 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073306 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163307
[email protected]49639fa2011-12-20 23:22:413308 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163309
[email protected]49639fa2011-12-20 23:22:413310 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163311 EXPECT_EQ(ERR_IO_PENDING, rv);
3312
3313 rv = callback1.WaitForResult();
3314 EXPECT_EQ(OK, rv);
3315
[email protected]58e32bb2013-01-21 18:23:253316 LoadTimingInfo load_timing_info;
3317 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3318 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3319
[email protected]d9da5fe2010-10-13 22:37:163320 const HttpResponseInfo* response = trans->GetResponseInfo();
3321 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503322 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163323 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3324
3325 std::string response_data;
3326 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3327 EXPECT_EQ("1234567890", response_data);
3328}
3329
3330// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023331TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273332 HttpRequestInfo request;
3333 request.method = "GET";
3334 request.url = GURL("https://www.google.com/");
3335 request.load_flags = 0;
3336
[email protected]d9da5fe2010-10-13 22:37:163337 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073338 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113339 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293340 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073341 session_deps_.net_log = log.bound().net_log();
3342 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163343
[email protected]262eec82013-03-19 21:01:363344 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163346
[email protected]d9da5fe2010-10-13 22:37:163347 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543348 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3349 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163350 // fetch https://www.google.com/ via SPDY
3351 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463352 scoped_ptr<SpdyFrame> get(
3353 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023354 scoped_ptr<SpdyFrame> wrapped_get(
3355 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3356 scoped_ptr<SpdyFrame> conn_resp(
3357 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3358 scoped_ptr<SpdyFrame> get_resp(
3359 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193360 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023361 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3362 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3363 scoped_ptr<SpdyFrame> wrapped_body(
3364 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193365 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203366 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193367 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203368 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043369
3370 MockWrite spdy_writes[] = {
3371 CreateMockWrite(*connect, 1),
3372 CreateMockWrite(*wrapped_get, 3),
3373 CreateMockWrite(*window_update_get_resp, 5),
3374 CreateMockWrite(*window_update_body, 7),
3375 };
3376
[email protected]d9da5fe2010-10-13 22:37:163377 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063378 CreateMockRead(*conn_resp, 2, ASYNC),
3379 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3380 CreateMockRead(*wrapped_body, 6, ASYNC),
3381 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163382 };
3383
[email protected]dd54bd82012-07-19 23:44:573384 OrderedSocketData spdy_data(
3385 spdy_reads, arraysize(spdy_reads),
3386 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073387 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163388
[email protected]8ddf8322012-02-23 18:08:063389 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023390 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063392 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023393 ssl2.SetNextProto(GetParam());
3394 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073395 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163396
[email protected]49639fa2011-12-20 23:22:413397 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163398
[email protected]49639fa2011-12-20 23:22:413399 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163400 EXPECT_EQ(ERR_IO_PENDING, rv);
3401
3402 rv = callback1.WaitForResult();
3403 EXPECT_EQ(OK, rv);
3404
[email protected]58e32bb2013-01-21 18:23:253405 LoadTimingInfo load_timing_info;
3406 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3407 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3408
[email protected]d9da5fe2010-10-13 22:37:163409 const HttpResponseInfo* response = trans->GetResponseInfo();
3410 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503411 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163412 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3413
3414 std::string response_data;
3415 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233416 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163417}
3418
3419// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023420TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273421 HttpRequestInfo request;
3422 request.method = "GET";
3423 request.url = GURL("https://www.google.com/");
3424 request.load_flags = 0;
3425
[email protected]d9da5fe2010-10-13 22:37:163426 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073427 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113428 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293429 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073430 session_deps_.net_log = log.bound().net_log();
3431 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163432
[email protected]262eec82013-03-19 21:01:363433 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163435
[email protected]d9da5fe2010-10-13 22:37:163436 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543437 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3438 LOWEST));
[email protected]c10b20852013-05-15 21:29:203439 scoped_ptr<SpdyFrame> get(
3440 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163441
3442 MockWrite spdy_writes[] = {
3443 CreateMockWrite(*connect, 1),
3444 CreateMockWrite(*get, 3),
3445 };
3446
[email protected]23e482282013-06-14 16:08:023447 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3448 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163449 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063450 CreateMockRead(*resp, 2, ASYNC),
3451 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163452 };
3453
[email protected]dd54bd82012-07-19 23:44:573454 OrderedSocketData spdy_data(
3455 spdy_reads, arraysize(spdy_reads),
3456 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073457 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163458
[email protected]8ddf8322012-02-23 18:08:063459 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023460 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063462 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023463 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073464 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163465
[email protected]49639fa2011-12-20 23:22:413466 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163467
[email protected]49639fa2011-12-20 23:22:413468 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163469 EXPECT_EQ(ERR_IO_PENDING, rv);
3470
3471 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173472 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163473
[email protected]4eddbc732012-08-09 05:40:173474 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163475}
3476
[email protected]f6c63db52013-02-02 00:35:223477// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3478// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023479TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223480 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3481 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073482 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223483 "https://proxy:70"));
3484 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073485 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223486 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073487 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223488
3489 HttpRequestInfo request1;
3490 request1.method = "GET";
3491 request1.url = GURL("https://www.google.com/");
3492 request1.load_flags = 0;
3493
3494 HttpRequestInfo request2;
3495 request2.method = "GET";
3496 request2.url = GURL("https://news.google.com/");
3497 request2.load_flags = 0;
3498
3499 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543500 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3501 LOWEST));
[email protected]23e482282013-06-14 16:08:023502 scoped_ptr<SpdyFrame> conn_resp1(
3503 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223504
3505 // Fetch https://www.google.com/ via HTTP.
3506 const char get1[] = "GET / HTTP/1.1\r\n"
3507 "Host: www.google.com\r\n"
3508 "Connection: keep-alive\r\n\r\n";
3509 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023510 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223511 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3512 "Content-Length: 1\r\n\r\n";
3513 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023514 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3515 scoped_ptr<SpdyFrame> wrapped_body1(
3516 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223517 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203518 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223519
3520 // CONNECT to news.google.com:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293521 SpdyHeaderBlock connect2_block;
3522 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3523 connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3524 connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3525 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223526 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293527 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393528
[email protected]23e482282013-06-14 16:08:023529 scoped_ptr<SpdyFrame> conn_resp2(
3530 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223531
3532 // Fetch https://news.google.com/ via HTTP.
3533 const char get2[] = "GET / HTTP/1.1\r\n"
3534 "Host: news.google.com\r\n"
3535 "Connection: keep-alive\r\n\r\n";
3536 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023537 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223538 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3539 "Content-Length: 2\r\n\r\n";
3540 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023541 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223542 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023543 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223544
3545 MockWrite spdy_writes[] = {
3546 CreateMockWrite(*connect1, 0),
3547 CreateMockWrite(*wrapped_get1, 2),
3548 CreateMockWrite(*connect2, 5),
3549 CreateMockWrite(*wrapped_get2, 7),
3550 };
3551
3552 MockRead spdy_reads[] = {
3553 CreateMockRead(*conn_resp1, 1, ASYNC),
3554 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3555 CreateMockRead(*wrapped_body1, 4, ASYNC),
3556 CreateMockRead(*conn_resp2, 6, ASYNC),
3557 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3558 CreateMockRead(*wrapped_body2, 9, ASYNC),
3559 MockRead(ASYNC, 0, 10),
3560 };
3561
3562 DeterministicSocketData spdy_data(
3563 spdy_reads, arraysize(spdy_reads),
3564 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073565 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223566
3567 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023568 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073569 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223570 SSLSocketDataProvider ssl2(ASYNC, OK);
3571 ssl2.was_npn_negotiated = false;
3572 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073573 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223574 SSLSocketDataProvider ssl3(ASYNC, OK);
3575 ssl3.was_npn_negotiated = false;
3576 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073577 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223578
3579 TestCompletionCallback callback;
3580
[email protected]262eec82013-03-19 21:01:363581 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223583 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3584 EXPECT_EQ(ERR_IO_PENDING, rv);
3585 // The first connect and request, each of their responses, and the body.
3586 spdy_data.RunFor(5);
3587
3588 rv = callback.WaitForResult();
3589 EXPECT_EQ(OK, rv);
3590
3591 LoadTimingInfo load_timing_info;
3592 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3593 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3594
3595 const HttpResponseInfo* response = trans->GetResponseInfo();
3596 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503597 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223598 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3599
3600 std::string response_data;
3601 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503602 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223603
[email protected]262eec82013-03-19 21:01:363604 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223606 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3607 EXPECT_EQ(ERR_IO_PENDING, rv);
3608
3609 // The second connect and request, each of their responses, and the body.
3610 spdy_data.RunFor(5);
3611 rv = callback.WaitForResult();
3612 EXPECT_EQ(OK, rv);
3613
3614 LoadTimingInfo load_timing_info2;
3615 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3616 // Even though the SPDY connection is reused, a new tunnelled connection has
3617 // to be created, so the socket's load timing looks like a fresh connection.
3618 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3619
3620 // The requests should have different IDs, since they each are using their own
3621 // separate stream.
3622 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3623
[email protected]90499482013-06-01 00:39:503624 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223625}
3626
3627// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3628// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023629TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223630 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3631 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073632 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223633 "https://proxy:70"));
3634 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073635 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223636 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073637 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223638
3639 HttpRequestInfo request1;
3640 request1.method = "GET";
3641 request1.url = GURL("https://www.google.com/");
3642 request1.load_flags = 0;
3643
3644 HttpRequestInfo request2;
3645 request2.method = "GET";
3646 request2.url = GURL("https://www.google.com/2");
3647 request2.load_flags = 0;
3648
3649 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543650 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3651 LOWEST));
[email protected]23e482282013-06-14 16:08:023652 scoped_ptr<SpdyFrame> conn_resp1(
3653 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223654
3655 // Fetch https://www.google.com/ via HTTP.
3656 const char get1[] = "GET / HTTP/1.1\r\n"
3657 "Host: www.google.com\r\n"
3658 "Connection: keep-alive\r\n\r\n";
3659 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023660 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223661 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3662 "Content-Length: 1\r\n\r\n";
3663 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023664 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3665 scoped_ptr<SpdyFrame> wrapped_body1(
3666 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223667 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203668 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223669
3670 // Fetch https://www.google.com/2 via HTTP.
3671 const char get2[] = "GET /2 HTTP/1.1\r\n"
3672 "Host: www.google.com\r\n"
3673 "Connection: keep-alive\r\n\r\n";
3674 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023675 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223676 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3677 "Content-Length: 2\r\n\r\n";
3678 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023679 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223680 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023681 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223682
3683 MockWrite spdy_writes[] = {
3684 CreateMockWrite(*connect1, 0),
3685 CreateMockWrite(*wrapped_get1, 2),
3686 CreateMockWrite(*wrapped_get2, 5),
3687 };
3688
3689 MockRead spdy_reads[] = {
3690 CreateMockRead(*conn_resp1, 1, ASYNC),
3691 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3692 CreateMockRead(*wrapped_body1, 4, ASYNC),
3693 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3694 CreateMockRead(*wrapped_body2, 7, ASYNC),
3695 MockRead(ASYNC, 0, 8),
3696 };
3697
3698 DeterministicSocketData spdy_data(
3699 spdy_reads, arraysize(spdy_reads),
3700 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073701 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223702
3703 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023704 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073705 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223706 SSLSocketDataProvider ssl2(ASYNC, OK);
3707 ssl2.was_npn_negotiated = false;
3708 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073709 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223710
3711 TestCompletionCallback callback;
3712
[email protected]262eec82013-03-19 21:01:363713 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503714 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223715 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3716 EXPECT_EQ(ERR_IO_PENDING, rv);
3717 // The first connect and request, each of their responses, and the body.
3718 spdy_data.RunFor(5);
3719
3720 rv = callback.WaitForResult();
3721 EXPECT_EQ(OK, rv);
3722
3723 LoadTimingInfo load_timing_info;
3724 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3725 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3726
3727 const HttpResponseInfo* response = trans->GetResponseInfo();
3728 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503729 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223730 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3731
3732 std::string response_data;
3733 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503734 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223735 trans.reset();
3736
[email protected]262eec82013-03-19 21:01:363737 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503738 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223739 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3740 EXPECT_EQ(ERR_IO_PENDING, rv);
3741
3742 // The second request, response, and body. There should not be a second
3743 // connect.
3744 spdy_data.RunFor(3);
3745 rv = callback.WaitForResult();
3746 EXPECT_EQ(OK, rv);
3747
3748 LoadTimingInfo load_timing_info2;
3749 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3750 TestLoadTimingReused(load_timing_info2);
3751
3752 // The requests should have the same ID.
3753 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3754
[email protected]90499482013-06-01 00:39:503755 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223756}
3757
3758// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3759// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023760TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223761 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3762 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073763 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223764 "https://proxy:70"));
3765 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073766 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223767 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073768 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223769
3770 HttpRequestInfo request1;
3771 request1.method = "GET";
3772 request1.url = GURL("http://www.google.com/");
3773 request1.load_flags = 0;
3774
3775 HttpRequestInfo request2;
3776 request2.method = "GET";
3777 request2.url = GURL("http://news.google.com/");
3778 request2.load_flags = 0;
3779
3780 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023781 scoped_ptr<SpdyHeaderBlock> headers(
3782 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:293783 scoped_ptr<SpdyFrame> get1(
3784 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:023785 scoped_ptr<SpdyFrame> get_resp1(
3786 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3787 scoped_ptr<SpdyFrame> body1(
3788 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223789
3790 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023791 scoped_ptr<SpdyHeaderBlock> headers2(
3792 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]745aa9c2014-06-27 02:21:293793 scoped_ptr<SpdyFrame> get2(
3794 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:023795 scoped_ptr<SpdyFrame> get_resp2(
3796 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3797 scoped_ptr<SpdyFrame> body2(
3798 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223799
3800 MockWrite spdy_writes[] = {
3801 CreateMockWrite(*get1, 0),
3802 CreateMockWrite(*get2, 3),
3803 };
3804
3805 MockRead spdy_reads[] = {
3806 CreateMockRead(*get_resp1, 1, ASYNC),
3807 CreateMockRead(*body1, 2, ASYNC),
3808 CreateMockRead(*get_resp2, 4, ASYNC),
3809 CreateMockRead(*body2, 5, ASYNC),
3810 MockRead(ASYNC, 0, 6),
3811 };
3812
3813 DeterministicSocketData spdy_data(
3814 spdy_reads, arraysize(spdy_reads),
3815 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073816 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223817
3818 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023819 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073820 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223821
3822 TestCompletionCallback callback;
3823
[email protected]262eec82013-03-19 21:01:363824 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503825 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223826 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3827 EXPECT_EQ(ERR_IO_PENDING, rv);
3828 spdy_data.RunFor(2);
3829
3830 rv = callback.WaitForResult();
3831 EXPECT_EQ(OK, rv);
3832
3833 LoadTimingInfo load_timing_info;
3834 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3835 TestLoadTimingNotReused(load_timing_info,
3836 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3837
3838 const HttpResponseInfo* response = trans->GetResponseInfo();
3839 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503840 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223841 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3842
3843 std::string response_data;
3844 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503845 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223846 spdy_data.RunFor(1);
3847 EXPECT_EQ(1, callback.WaitForResult());
3848 // Delete the first request, so the second one can reuse the socket.
3849 trans.reset();
3850
[email protected]262eec82013-03-19 21:01:363851 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223853 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3854 EXPECT_EQ(ERR_IO_PENDING, rv);
3855
3856 spdy_data.RunFor(2);
3857 rv = callback.WaitForResult();
3858 EXPECT_EQ(OK, rv);
3859
3860 LoadTimingInfo load_timing_info2;
3861 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3862 TestLoadTimingReused(load_timing_info2);
3863
3864 // The requests should have the same ID.
3865 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3866
[email protected]90499482013-06-01 00:39:503867 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223868 spdy_data.RunFor(1);
3869 EXPECT_EQ(2, callback.WaitForResult());
3870}
3871
[email protected]2df19bb2010-08-25 20:13:463872// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023873TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463874 HttpRequestInfo request;
3875 request.method = "GET";
3876 request.url = GURL("http://www.google.com/");
3877 // when the no authentication data flag is set.
3878 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3879
[email protected]79cb5c12011-09-12 13:12:043880 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073881 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043882 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293883 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073884 session_deps_.net_log = log.bound().net_log();
3885 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273886
[email protected]2df19bb2010-08-25 20:13:463887 // Since we have proxy, should use full url
3888 MockWrite data_writes1[] = {
3889 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3890 "Host: www.google.com\r\n"
3891 "Proxy-Connection: keep-alive\r\n\r\n"),
3892
3893 // After calling trans->RestartWithAuth(), this is the request we should
3894 // be issuing -- the final header line contains the credentials.
3895 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3896 "Host: www.google.com\r\n"
3897 "Proxy-Connection: keep-alive\r\n"
3898 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3899 };
3900
3901 // The proxy responds to the GET with a 407, using a persistent
3902 // connection.
3903 MockRead data_reads1[] = {
3904 // No credentials.
3905 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3906 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3907 MockRead("Proxy-Connection: keep-alive\r\n"),
3908 MockRead("Content-Length: 0\r\n\r\n"),
3909
3910 MockRead("HTTP/1.1 200 OK\r\n"),
3911 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3912 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063913 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463914 };
3915
3916 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3917 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073918 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063919 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073920 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463921
[email protected]49639fa2011-12-20 23:22:413922 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463923
[email protected]262eec82013-03-19 21:01:363924 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503925 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503926
[email protected]49639fa2011-12-20 23:22:413927 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463928 EXPECT_EQ(ERR_IO_PENDING, rv);
3929
3930 rv = callback1.WaitForResult();
3931 EXPECT_EQ(OK, rv);
3932
[email protected]58e32bb2013-01-21 18:23:253933 LoadTimingInfo load_timing_info;
3934 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3935 TestLoadTimingNotReused(load_timing_info,
3936 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3937
[email protected]2df19bb2010-08-25 20:13:463938 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503939 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503940 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463941 EXPECT_EQ(407, response->headers->response_code());
3942 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043943 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463944
[email protected]49639fa2011-12-20 23:22:413945 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463946
[email protected]49639fa2011-12-20 23:22:413947 rv = trans->RestartWithAuth(
3948 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463949 EXPECT_EQ(ERR_IO_PENDING, rv);
3950
3951 rv = callback2.WaitForResult();
3952 EXPECT_EQ(OK, rv);
3953
[email protected]58e32bb2013-01-21 18:23:253954 load_timing_info = LoadTimingInfo();
3955 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3956 // Retrying with HTTP AUTH is considered to be reusing a socket.
3957 TestLoadTimingReused(load_timing_info);
3958
[email protected]2df19bb2010-08-25 20:13:463959 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503960 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463961
3962 EXPECT_TRUE(response->headers->IsKeepAlive());
3963 EXPECT_EQ(200, response->headers->response_code());
3964 EXPECT_EQ(100, response->headers->GetContentLength());
3965 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3966
3967 // The password prompt info should not be set.
3968 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3969}
3970
[email protected]23e482282013-06-14 16:08:023971void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083972 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423973 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083974 request.method = "GET";
3975 request.url = GURL("https://www.google.com/");
3976 request.load_flags = 0;
3977
[email protected]cb9bf6ca2011-01-28 13:15:273978 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073979 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073980 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273981
[email protected]c744cf22009-02-27 07:28:083982 // Since we have proxy, should try to establish tunnel.
3983 MockWrite data_writes[] = {
3984 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453985 "Host: www.google.com\r\n"
3986 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083987 };
3988
3989 MockRead data_reads[] = {
3990 status,
3991 MockRead("Content-Length: 10\r\n\r\n"),
3992 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063993 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083994 };
3995
[email protected]31a2bfe2010-02-09 08:03:393996 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3997 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073998 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083999
[email protected]49639fa2011-12-20 23:22:414000 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084001
[email protected]262eec82013-03-19 21:01:364002 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504003 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504004
[email protected]49639fa2011-12-20 23:22:414005 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424006 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084007
4008 rv = callback.WaitForResult();
4009 EXPECT_EQ(expected_status, rv);
4010}
4011
[email protected]23e482282013-06-14 16:08:024012void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234013 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084014 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424015 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084016}
4017
[email protected]23e482282013-06-14 16:08:024018TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084019 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4020}
4021
[email protected]23e482282013-06-14 16:08:024022TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084023 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4024}
4025
[email protected]23e482282013-06-14 16:08:024026TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084027 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4028}
4029
[email protected]23e482282013-06-14 16:08:024030TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084031 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4032}
4033
[email protected]23e482282013-06-14 16:08:024034TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084035 ConnectStatusHelper(
4036 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4037}
4038
[email protected]23e482282013-06-14 16:08:024039TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084040 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4041}
4042
[email protected]23e482282013-06-14 16:08:024043TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084044 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4045}
4046
[email protected]23e482282013-06-14 16:08:024047TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084048 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4049}
4050
[email protected]23e482282013-06-14 16:08:024051TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084052 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4053}
4054
[email protected]23e482282013-06-14 16:08:024055TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084056 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4057}
4058
[email protected]23e482282013-06-14 16:08:024059TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084060 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4061}
4062
[email protected]23e482282013-06-14 16:08:024063TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084064 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4065}
4066
[email protected]23e482282013-06-14 16:08:024067TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084068 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4069}
4070
[email protected]23e482282013-06-14 16:08:024071TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084072 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4073}
4074
[email protected]23e482282013-06-14 16:08:024075TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084076 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4077}
4078
[email protected]23e482282013-06-14 16:08:024079TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084080 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4081}
4082
[email protected]0a17aab32014-04-24 03:32:374083TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4084 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4085}
4086
[email protected]23e482282013-06-14 16:08:024087TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084088 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4089}
4090
[email protected]23e482282013-06-14 16:08:024091TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084092 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4093}
4094
[email protected]23e482282013-06-14 16:08:024095TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084096 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4097}
4098
[email protected]23e482282013-06-14 16:08:024099TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084100 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4101}
4102
[email protected]23e482282013-06-14 16:08:024103TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084104 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4105}
4106
[email protected]23e482282013-06-14 16:08:024107TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084108 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4109}
4110
[email protected]23e482282013-06-14 16:08:024111TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084112 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4113}
4114
[email protected]23e482282013-06-14 16:08:024115TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084116 ConnectStatusHelperWithExpectedStatus(
4117 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544118 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084119}
4120
[email protected]23e482282013-06-14 16:08:024121TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084122 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4123}
4124
[email protected]23e482282013-06-14 16:08:024125TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084126 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4127}
4128
[email protected]23e482282013-06-14 16:08:024129TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084130 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4131}
4132
[email protected]23e482282013-06-14 16:08:024133TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084134 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4135}
4136
[email protected]23e482282013-06-14 16:08:024137TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084138 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4139}
4140
[email protected]23e482282013-06-14 16:08:024141TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084142 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4143}
4144
[email protected]23e482282013-06-14 16:08:024145TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084146 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4147}
4148
[email protected]23e482282013-06-14 16:08:024149TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084150 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4151}
4152
[email protected]23e482282013-06-14 16:08:024153TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084154 ConnectStatusHelper(
4155 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4156}
4157
[email protected]23e482282013-06-14 16:08:024158TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084159 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4160}
4161
[email protected]23e482282013-06-14 16:08:024162TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084163 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4164}
4165
[email protected]23e482282013-06-14 16:08:024166TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084167 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4168}
4169
[email protected]23e482282013-06-14 16:08:024170TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084171 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4172}
4173
[email protected]23e482282013-06-14 16:08:024174TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084175 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4176}
4177
[email protected]23e482282013-06-14 16:08:024178TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084179 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4180}
4181
[email protected]23e482282013-06-14 16:08:024182TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084183 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4184}
4185
[email protected]038e9a32008-10-08 22:40:164186// Test the flow when both the proxy server AND origin server require
4187// authentication. Again, this uses basic auth for both since that is
4188// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024189TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274190 HttpRequestInfo request;
4191 request.method = "GET";
4192 request.url = GURL("http://www.google.com/");
4193 request.load_flags = 0;
4194
[email protected]038e9a32008-10-08 22:40:164195 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074196 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4198
4199 scoped_ptr<HttpTransaction> trans(
4200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]038e9a32008-10-08 22:40:164201
[email protected]f9ee6b52008-11-08 06:46:234202 MockWrite data_writes1[] = {
4203 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4204 "Host: www.google.com\r\n"
4205 "Proxy-Connection: keep-alive\r\n\r\n"),
4206 };
4207
[email protected]038e9a32008-10-08 22:40:164208 MockRead data_reads1[] = {
4209 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4210 // Give a couple authenticate options (only the middle one is actually
4211 // supported).
[email protected]22927ad2009-09-21 19:56:194212 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164213 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4214 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4215 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4216 // Large content-length -- won't matter, as connection will be reset.
4217 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064218 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164219 };
4220
4221 // After calling trans->RestartWithAuth() the first time, this is the
4222 // request we should be issuing -- the final header line contains the
4223 // proxy's credentials.
4224 MockWrite data_writes2[] = {
4225 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4226 "Host: www.google.com\r\n"
4227 "Proxy-Connection: keep-alive\r\n"
4228 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4229 };
4230
4231 // Now the proxy server lets the request pass through to origin server.
4232 // The origin server responds with a 401.
4233 MockRead data_reads2[] = {
4234 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4235 // Note: We are using the same realm-name as the proxy server. This is
4236 // completely valid, as realms are unique across hosts.
4237 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4238 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4239 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064240 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164241 };
4242
4243 // After calling trans->RestartWithAuth() the second time, we should send
4244 // the credentials for both the proxy and origin server.
4245 MockWrite data_writes3[] = {
4246 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4247 "Host: www.google.com\r\n"
4248 "Proxy-Connection: keep-alive\r\n"
4249 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4250 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4251 };
4252
4253 // Lastly we get the desired content.
4254 MockRead data_reads3[] = {
4255 MockRead("HTTP/1.0 200 OK\r\n"),
4256 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4257 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064258 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164259 };
4260
[email protected]31a2bfe2010-02-09 08:03:394261 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4262 data_writes1, arraysize(data_writes1));
4263 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4264 data_writes2, arraysize(data_writes2));
4265 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4266 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074267 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4268 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4269 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164270
[email protected]49639fa2011-12-20 23:22:414271 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164272
[email protected]49639fa2011-12-20 23:22:414273 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424274 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164275
4276 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424277 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164278
[email protected]1c773ea12009-04-28 19:58:424279 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504280 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044281 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164282
[email protected]49639fa2011-12-20 23:22:414283 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164284
[email protected]49639fa2011-12-20 23:22:414285 rv = trans->RestartWithAuth(
4286 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424287 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164288
4289 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424290 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164291
4292 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504293 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044294 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164295
[email protected]49639fa2011-12-20 23:22:414296 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164297
[email protected]49639fa2011-12-20 23:22:414298 rv = trans->RestartWithAuth(
4299 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424300 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164301
4302 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424303 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164304
4305 response = trans->GetResponseInfo();
4306 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4307 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164308}
[email protected]4ddaf2502008-10-23 18:26:194309
[email protected]ea9dc9a2009-09-05 00:43:324310// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4311// can't hook into its internals to cause it to generate predictable NTLM
4312// authorization headers.
4313#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294314// The NTLM authentication unit tests were generated by capturing the HTTP
4315// requests and responses using Fiddler 2 and inspecting the generated random
4316// bytes in the debugger.
4317
4318// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024319TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424320 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244321 request.method = "GET";
4322 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544323
4324 // Ensure load is not disrupted by flags which suppress behaviour specific
4325 // to other auth schemes.
4326 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244327
[email protected]cb9bf6ca2011-01-28 13:15:274328 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4329 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074330 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274331
[email protected]3f918782009-02-28 01:29:244332 MockWrite data_writes1[] = {
4333 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4334 "Host: 172.22.68.17\r\n"
4335 "Connection: keep-alive\r\n\r\n"),
4336 };
4337
4338 MockRead data_reads1[] = {
4339 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044340 // Negotiate and NTLM are often requested together. However, we only want
4341 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4342 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244343 MockRead("WWW-Authenticate: NTLM\r\n"),
4344 MockRead("Connection: close\r\n"),
4345 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364346 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244347 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064348 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244349 };
4350
4351 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224352 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244353 // request we should be issuing -- the final header line contains a Type
4354 // 1 message.
4355 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4356 "Host: 172.22.68.17\r\n"
4357 "Connection: keep-alive\r\n"
4358 "Authorization: NTLM "
4359 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4360
4361 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4362 // (the credentials for the origin server). The second request continues
4363 // on the same connection.
4364 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4365 "Host: 172.22.68.17\r\n"
4366 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294367 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4368 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4369 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4370 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4371 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244372 };
4373
4374 MockRead data_reads2[] = {
4375 // The origin server responds with a Type 2 message.
4376 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4377 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294378 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244379 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4380 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4381 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4382 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4383 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4384 "BtAAAAAAA=\r\n"),
4385 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364386 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244387 MockRead("You are not authorized to view this page\r\n"),
4388
4389 // Lastly we get the desired content.
4390 MockRead("HTTP/1.1 200 OK\r\n"),
4391 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4392 MockRead("Content-Length: 13\r\n\r\n"),
4393 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064394 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244395 };
4396
[email protected]31a2bfe2010-02-09 08:03:394397 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4398 data_writes1, arraysize(data_writes1));
4399 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4400 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074401 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4402 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244403
[email protected]49639fa2011-12-20 23:22:414404 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244405
[email protected]262eec82013-03-19 21:01:364406 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504407 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504408
[email protected]49639fa2011-12-20 23:22:414409 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424410 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244411
4412 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424413 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244414
[email protected]0757e7702009-03-27 04:00:224415 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4416
[email protected]1c773ea12009-04-28 19:58:424417 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044418 ASSERT_FALSE(response == NULL);
4419 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244420
[email protected]49639fa2011-12-20 23:22:414421 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254422
[email protected]f3cf9802011-10-28 18:44:584423 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414424 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254425 EXPECT_EQ(ERR_IO_PENDING, rv);
4426
4427 rv = callback2.WaitForResult();
4428 EXPECT_EQ(OK, rv);
4429
4430 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4431
4432 response = trans->GetResponseInfo();
4433 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254434 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4435
[email protected]49639fa2011-12-20 23:22:414436 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244437
[email protected]49639fa2011-12-20 23:22:414438 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424439 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244440
[email protected]0757e7702009-03-27 04:00:224441 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424442 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244443
4444 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504445 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244446 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4447 EXPECT_EQ(13, response->headers->GetContentLength());
4448}
4449
[email protected]385a4672009-03-11 22:21:294450// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024451TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424452 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294453 request.method = "GET";
4454 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4455 request.load_flags = 0;
4456
[email protected]cb9bf6ca2011-01-28 13:15:274457 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4458 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074459 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274460
[email protected]385a4672009-03-11 22:21:294461 MockWrite data_writes1[] = {
4462 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4463 "Host: 172.22.68.17\r\n"
4464 "Connection: keep-alive\r\n\r\n"),
4465 };
4466
4467 MockRead data_reads1[] = {
4468 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044469 // Negotiate and NTLM are often requested together. However, we only want
4470 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4471 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294472 MockRead("WWW-Authenticate: NTLM\r\n"),
4473 MockRead("Connection: close\r\n"),
4474 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364475 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294476 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064477 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294478 };
4479
4480 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224481 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294482 // request we should be issuing -- the final header line contains a Type
4483 // 1 message.
4484 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4485 "Host: 172.22.68.17\r\n"
4486 "Connection: keep-alive\r\n"
4487 "Authorization: NTLM "
4488 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4489
4490 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4491 // (the credentials for the origin server). The second request continues
4492 // on the same connection.
4493 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4494 "Host: 172.22.68.17\r\n"
4495 "Connection: keep-alive\r\n"
4496 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4497 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4498 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4499 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4500 "4Ww7b7E=\r\n\r\n"),
4501 };
4502
4503 MockRead data_reads2[] = {
4504 // The origin server responds with a Type 2 message.
4505 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4506 MockRead("WWW-Authenticate: NTLM "
4507 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4508 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4509 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4510 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4511 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4512 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4513 "BtAAAAAAA=\r\n"),
4514 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364515 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294516 MockRead("You are not authorized to view this page\r\n"),
4517
4518 // Wrong password.
4519 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294520 MockRead("WWW-Authenticate: NTLM\r\n"),
4521 MockRead("Connection: close\r\n"),
4522 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364523 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294524 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064525 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294526 };
4527
4528 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224529 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294530 // request we should be issuing -- the final header line contains a Type
4531 // 1 message.
4532 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4533 "Host: 172.22.68.17\r\n"
4534 "Connection: keep-alive\r\n"
4535 "Authorization: NTLM "
4536 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4537
4538 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4539 // (the credentials for the origin server). The second request continues
4540 // on the same connection.
4541 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4542 "Host: 172.22.68.17\r\n"
4543 "Connection: keep-alive\r\n"
4544 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4545 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4546 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4547 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4548 "+4MUm7c=\r\n\r\n"),
4549 };
4550
4551 MockRead data_reads3[] = {
4552 // The origin server responds with a Type 2 message.
4553 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4554 MockRead("WWW-Authenticate: NTLM "
4555 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4556 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4557 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4558 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4559 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4560 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4561 "BtAAAAAAA=\r\n"),
4562 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364563 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294564 MockRead("You are not authorized to view this page\r\n"),
4565
4566 // Lastly we get the desired content.
4567 MockRead("HTTP/1.1 200 OK\r\n"),
4568 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4569 MockRead("Content-Length: 13\r\n\r\n"),
4570 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064571 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294572 };
4573
[email protected]31a2bfe2010-02-09 08:03:394574 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4575 data_writes1, arraysize(data_writes1));
4576 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4577 data_writes2, arraysize(data_writes2));
4578 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4579 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074580 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4581 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4582 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294583
[email protected]49639fa2011-12-20 23:22:414584 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294585
[email protected]262eec82013-03-19 21:01:364586 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504587 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504588
[email protected]49639fa2011-12-20 23:22:414589 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424590 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294591
4592 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424593 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294594
[email protected]0757e7702009-03-27 04:00:224595 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294596
[email protected]1c773ea12009-04-28 19:58:424597 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504598 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044599 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294600
[email protected]49639fa2011-12-20 23:22:414601 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294602
[email protected]0757e7702009-03-27 04:00:224603 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584604 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414605 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424606 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294607
[email protected]10af5fe72011-01-31 16:17:254608 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424609 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294610
[email protected]0757e7702009-03-27 04:00:224611 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414612 TestCompletionCallback callback3;
4613 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424614 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254615 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424616 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224617 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4618
4619 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044620 ASSERT_FALSE(response == NULL);
4621 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224622
[email protected]49639fa2011-12-20 23:22:414623 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224624
4625 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584626 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414627 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254628 EXPECT_EQ(ERR_IO_PENDING, rv);
4629
4630 rv = callback4.WaitForResult();
4631 EXPECT_EQ(OK, rv);
4632
4633 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4634
[email protected]49639fa2011-12-20 23:22:414635 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254636
4637 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414638 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424639 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224640
4641 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424642 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224643
[email protected]385a4672009-03-11 22:21:294644 response = trans->GetResponseInfo();
4645 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4646 EXPECT_EQ(13, response->headers->GetContentLength());
4647}
[email protected]ea9dc9a2009-09-05 00:43:324648#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294649
[email protected]4ddaf2502008-10-23 18:26:194650// Test reading a server response which has only headers, and no body.
4651// After some maximum number of bytes is consumed, the transaction should
4652// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024653TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424654 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194655 request.method = "GET";
4656 request.url = GURL("http://www.google.com/");
4657 request.load_flags = 0;
4658
[email protected]3fe8d2f82013-10-17 08:56:074659 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274660 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074661 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274662
[email protected]b75b7b2f2009-10-06 00:54:534663 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434664 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534665 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194666
4667 MockRead data_reads[] = {
4668 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064669 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194670 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064671 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194672 };
[email protected]31a2bfe2010-02-09 08:03:394673 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074674 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194675
[email protected]49639fa2011-12-20 23:22:414676 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194677
[email protected]49639fa2011-12-20 23:22:414678 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424679 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194680
4681 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424682 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194683
[email protected]1c773ea12009-04-28 19:58:424684 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194685 EXPECT_TRUE(response == NULL);
4686}
[email protected]f4e426b2008-11-05 00:24:494687
4688// Make sure that we don't try to reuse a TCPClientSocket when failing to
4689// establish tunnel.
4690// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024691TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234692 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274693 HttpRequestInfo request;
4694 request.method = "GET";
4695 request.url = GURL("https://www.google.com/");
4696 request.load_flags = 0;
4697
[email protected]f4e426b2008-11-05 00:24:494698 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074699 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014700
[email protected]bb88e1d32013-05-03 23:11:074701 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494702
[email protected]262eec82013-03-19 21:01:364703 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504704 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494705
[email protected]f4e426b2008-11-05 00:24:494706 // Since we have proxy, should try to establish tunnel.
4707 MockWrite data_writes1[] = {
4708 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454709 "Host: www.google.com\r\n"
4710 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494711 };
4712
[email protected]77848d12008-11-14 00:00:224713 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494714 // connection. Usually a proxy would return 501 (not implemented),
4715 // or 200 (tunnel established).
4716 MockRead data_reads1[] = {
4717 MockRead("HTTP/1.1 404 Not Found\r\n"),
4718 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064719 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494720 };
4721
[email protected]31a2bfe2010-02-09 08:03:394722 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4723 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074724 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494725
[email protected]49639fa2011-12-20 23:22:414726 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494727
[email protected]49639fa2011-12-20 23:22:414728 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424729 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494730
4731 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424732 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494733
[email protected]1c773ea12009-04-28 19:58:424734 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084735 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494736
[email protected]b4404c02009-04-10 16:38:524737 // Empty the current queue. This is necessary because idle sockets are
4738 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344739 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524740
[email protected]f4e426b2008-11-05 00:24:494741 // We now check to make sure the TCPClientSocket was not added back to
4742 // the pool.
[email protected]90499482013-06-01 00:39:504743 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494744 trans.reset();
[email protected]2da659e2013-05-23 20:51:344745 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494746 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504747 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494748}
[email protected]372d34a2008-11-05 21:30:514749
[email protected]1b157c02009-04-21 01:55:404750// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024751TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424752 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404753 request.method = "GET";
4754 request.url = GURL("http://www.google.com/");
4755 request.load_flags = 0;
4756
[email protected]bb88e1d32013-05-03 23:11:074757 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274758
[email protected]262eec82013-03-19 21:01:364759 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274761
[email protected]1b157c02009-04-21 01:55:404762 MockRead data_reads[] = {
4763 // A part of the response body is received with the response headers.
4764 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4765 // The rest of the response body is received in two parts.
4766 MockRead("lo"),
4767 MockRead(" world"),
4768 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064769 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404770 };
4771
[email protected]31a2bfe2010-02-09 08:03:394772 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074773 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404774
[email protected]49639fa2011-12-20 23:22:414775 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404776
[email protected]49639fa2011-12-20 23:22:414777 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424778 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404779
4780 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424781 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404782
[email protected]1c773ea12009-04-28 19:58:424783 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504784 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404785
[email protected]90499482013-06-01 00:39:504786 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404787 std::string status_line = response->headers->GetStatusLine();
4788 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4789
[email protected]90499482013-06-01 00:39:504790 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404791
4792 std::string response_data;
4793 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424794 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404795 EXPECT_EQ("hello world", response_data);
4796
4797 // Empty the current queue. This is necessary because idle sockets are
4798 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344799 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404800
4801 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504802 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404803}
4804
[email protected]76a505b2010-08-25 06:23:004805// Make sure that we recycle a SSL socket after reading all of the response
4806// body.
[email protected]23e482282013-06-14 16:08:024807TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004808 HttpRequestInfo request;
4809 request.method = "GET";
4810 request.url = GURL("https://www.google.com/");
4811 request.load_flags = 0;
4812
4813 MockWrite data_writes[] = {
4814 MockWrite("GET / HTTP/1.1\r\n"
4815 "Host: www.google.com\r\n"
4816 "Connection: keep-alive\r\n\r\n"),
4817 };
4818
4819 MockRead data_reads[] = {
4820 MockRead("HTTP/1.1 200 OK\r\n"),
4821 MockRead("Content-Length: 11\r\n\r\n"),
4822 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064823 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004824 };
4825
[email protected]8ddf8322012-02-23 18:08:064826 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074827 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004828
4829 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4830 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074831 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004832
[email protected]49639fa2011-12-20 23:22:414833 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004834
[email protected]bb88e1d32013-05-03 23:11:074835 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364836 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504837 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004838
[email protected]49639fa2011-12-20 23:22:414839 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004840
4841 EXPECT_EQ(ERR_IO_PENDING, rv);
4842 EXPECT_EQ(OK, callback.WaitForResult());
4843
4844 const HttpResponseInfo* response = trans->GetResponseInfo();
4845 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504846 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004847 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4848
[email protected]90499482013-06-01 00:39:504849 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004850
4851 std::string response_data;
4852 rv = ReadTransaction(trans.get(), &response_data);
4853 EXPECT_EQ(OK, rv);
4854 EXPECT_EQ("hello world", response_data);
4855
4856 // Empty the current queue. This is necessary because idle sockets are
4857 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344858 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004859
4860 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504861 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004862}
4863
4864// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4865// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024866TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004867 HttpRequestInfo request;
4868 request.method = "GET";
4869 request.url = GURL("https://www.google.com/");
4870 request.load_flags = 0;
4871
4872 MockWrite data_writes[] = {
4873 MockWrite("GET / HTTP/1.1\r\n"
4874 "Host: www.google.com\r\n"
4875 "Connection: keep-alive\r\n\r\n"),
4876 MockWrite("GET / HTTP/1.1\r\n"
4877 "Host: www.google.com\r\n"
4878 "Connection: keep-alive\r\n\r\n"),
4879 };
4880
4881 MockRead data_reads[] = {
4882 MockRead("HTTP/1.1 200 OK\r\n"),
4883 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064884 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004885 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064886 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004887 };
4888
[email protected]8ddf8322012-02-23 18:08:064889 SSLSocketDataProvider ssl(ASYNC, OK);
4890 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4892 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004893
4894 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4895 data_writes, arraysize(data_writes));
4896 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4897 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074898 session_deps_.socket_factory->AddSocketDataProvider(&data);
4899 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004900
[email protected]49639fa2011-12-20 23:22:414901 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004902
[email protected]bb88e1d32013-05-03 23:11:074903 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364904 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504905 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004906
[email protected]49639fa2011-12-20 23:22:414907 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004908
4909 EXPECT_EQ(ERR_IO_PENDING, rv);
4910 EXPECT_EQ(OK, callback.WaitForResult());
4911
4912 const HttpResponseInfo* response = trans->GetResponseInfo();
4913 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504914 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004915 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4916
[email protected]90499482013-06-01 00:39:504917 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004918
4919 std::string response_data;
4920 rv = ReadTransaction(trans.get(), &response_data);
4921 EXPECT_EQ(OK, rv);
4922 EXPECT_EQ("hello world", response_data);
4923
4924 // Empty the current queue. This is necessary because idle sockets are
4925 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344926 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004927
4928 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504929 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004930
4931 // Now start the second transaction, which should reuse the previous socket.
4932
[email protected]90499482013-06-01 00:39:504933 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004934
[email protected]49639fa2011-12-20 23:22:414935 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004936
4937 EXPECT_EQ(ERR_IO_PENDING, rv);
4938 EXPECT_EQ(OK, callback.WaitForResult());
4939
4940 response = trans->GetResponseInfo();
4941 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504942 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004943 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4944
[email protected]90499482013-06-01 00:39:504945 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004946
4947 rv = ReadTransaction(trans.get(), &response_data);
4948 EXPECT_EQ(OK, rv);
4949 EXPECT_EQ("hello world", response_data);
4950
4951 // Empty the current queue. This is necessary because idle sockets are
4952 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344953 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004954
4955 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504956 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004957}
4958
[email protected]b4404c02009-04-10 16:38:524959// Make sure that we recycle a socket after a zero-length response.
4960// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024961TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424962 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524963 request.method = "GET";
4964 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4965 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4966 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4967 "rt=prt.2642,ol.2649,xjs.2951");
4968 request.load_flags = 0;
4969
[email protected]bb88e1d32013-05-03 23:11:074970 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274971
[email protected]262eec82013-03-19 21:01:364972 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504973 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274974
[email protected]b4404c02009-04-10 16:38:524975 MockRead data_reads[] = {
4976 MockRead("HTTP/1.1 204 No Content\r\n"
4977 "Content-Length: 0\r\n"
4978 "Content-Type: text/html\r\n\r\n"),
4979 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064980 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524981 };
4982
[email protected]31a2bfe2010-02-09 08:03:394983 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074984 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524985
[email protected]49639fa2011-12-20 23:22:414986 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524987
[email protected]49639fa2011-12-20 23:22:414988 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424989 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524990
4991 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424992 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524993
[email protected]1c773ea12009-04-28 19:58:424994 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504995 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524996
[email protected]90499482013-06-01 00:39:504997 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524998 std::string status_line = response->headers->GetStatusLine();
4999 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5000
[email protected]90499482013-06-01 00:39:505001 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525002
5003 std::string response_data;
5004 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425005 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525006 EXPECT_EQ("", response_data);
5007
5008 // Empty the current queue. This is necessary because idle sockets are
5009 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345010 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525011
5012 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505013 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525014}
5015
[email protected]23e482282013-06-14 16:08:025016TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065017 ScopedVector<UploadElementReader> element_readers;
5018 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:205019 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275020
[email protected]1c773ea12009-04-28 19:58:425021 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515022 // Transaction 1: a GET request that succeeds. The socket is recycled
5023 // after use.
5024 request[0].method = "GET";
5025 request[0].url = GURL("http://www.google.com/");
5026 request[0].load_flags = 0;
5027 // Transaction 2: a POST request. Reuses the socket kept alive from
5028 // transaction 1. The first attempts fails when writing the POST data.
5029 // This causes the transaction to retry with a new socket. The second
5030 // attempt succeeds.
5031 request[1].method = "POST";
5032 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275033 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515034 request[1].load_flags = 0;
5035
[email protected]bb88e1d32013-05-03 23:11:075036 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515037
5038 // The first socket is used for transaction 1 and the first attempt of
5039 // transaction 2.
5040
5041 // The response of transaction 1.
5042 MockRead data_reads1[] = {
5043 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5044 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065045 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515046 };
5047 // The mock write results of transaction 1 and the first attempt of
5048 // transaction 2.
5049 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065050 MockWrite(SYNCHRONOUS, 64), // GET
5051 MockWrite(SYNCHRONOUS, 93), // POST
5052 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515053 };
[email protected]31a2bfe2010-02-09 08:03:395054 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5055 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515056
5057 // The second socket is used for the second attempt of transaction 2.
5058
5059 // The response of transaction 2.
5060 MockRead data_reads2[] = {
5061 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5062 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065063 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515064 };
5065 // The mock write results of the second attempt of transaction 2.
5066 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065067 MockWrite(SYNCHRONOUS, 93), // POST
5068 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515069 };
[email protected]31a2bfe2010-02-09 08:03:395070 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5071 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515072
[email protected]bb88e1d32013-05-03 23:11:075073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5074 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515075
5076 const char* kExpectedResponseData[] = {
5077 "hello world", "welcome"
5078 };
5079
5080 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425081 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505082 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515083
[email protected]49639fa2011-12-20 23:22:415084 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515085
[email protected]49639fa2011-12-20 23:22:415086 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425087 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515088
5089 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425090 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515091
[email protected]1c773ea12009-04-28 19:58:425092 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505093 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515094
[email protected]90499482013-06-01 00:39:505095 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515096 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5097
5098 std::string response_data;
5099 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425100 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515101 EXPECT_EQ(kExpectedResponseData[i], response_data);
5102 }
5103}
[email protected]f9ee6b52008-11-08 06:46:235104
5105// Test the request-challenge-retry sequence for basic auth when there is
5106// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165107// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025108TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425109 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235110 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:295111 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415112 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295113
[email protected]3fe8d2f82013-10-17 08:56:075114 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275115 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275117
[email protected]a97cca42009-08-14 01:00:295118 // The password contains an escaped character -- for this test to pass it
5119 // will need to be unescaped by HttpNetworkTransaction.
5120 EXPECT_EQ("b%40r", request.url.password());
5121
[email protected]f9ee6b52008-11-08 06:46:235122 MockWrite data_writes1[] = {
5123 MockWrite("GET / HTTP/1.1\r\n"
5124 "Host: www.google.com\r\n"
5125 "Connection: keep-alive\r\n\r\n"),
5126 };
5127
5128 MockRead data_reads1[] = {
5129 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5130 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5131 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065132 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235133 };
5134
[email protected]2262e3a2012-05-22 16:08:165135 // After the challenge above, the transaction will be restarted using the
5136 // identity from the url (foo, b@r) to answer the challenge.
5137 MockWrite data_writes2[] = {
5138 MockWrite("GET / HTTP/1.1\r\n"
5139 "Host: www.google.com\r\n"
5140 "Connection: keep-alive\r\n"
5141 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5142 };
5143
5144 MockRead data_reads2[] = {
5145 MockRead("HTTP/1.0 200 OK\r\n"),
5146 MockRead("Content-Length: 100\r\n\r\n"),
5147 MockRead(SYNCHRONOUS, OK),
5148 };
5149
[email protected]31a2bfe2010-02-09 08:03:395150 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5151 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165152 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5153 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075154 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5155 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235156
[email protected]49639fa2011-12-20 23:22:415157 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415158 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425159 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235160 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425161 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165162 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5163
5164 TestCompletionCallback callback2;
5165 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5166 EXPECT_EQ(ERR_IO_PENDING, rv);
5167 rv = callback2.WaitForResult();
5168 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225169 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5170
[email protected]2262e3a2012-05-22 16:08:165171 const HttpResponseInfo* response = trans->GetResponseInfo();
5172 ASSERT_TRUE(response != NULL);
5173
5174 // There is no challenge info, since the identity in URL worked.
5175 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5176
5177 EXPECT_EQ(100, response->headers->GetContentLength());
5178
5179 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345180 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165181}
5182
5183// Test the request-challenge-retry sequence for basic auth when there is an
5184// incorrect identity in the URL. The identity from the URL should be used only
5185// once.
[email protected]23e482282013-06-14 16:08:025186TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165187 HttpRequestInfo request;
5188 request.method = "GET";
5189 // Note: the URL has a username:password in it. The password "baz" is
5190 // wrong (should be "bar").
5191 request.url = GURL("http://foo:[email protected]/");
5192
5193 request.load_flags = LOAD_NORMAL;
5194
[email protected]3fe8d2f82013-10-17 08:56:075195 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165196 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075197 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2262e3a2012-05-22 16:08:165198
5199 MockWrite data_writes1[] = {
5200 MockWrite("GET / HTTP/1.1\r\n"
5201 "Host: www.google.com\r\n"
5202 "Connection: keep-alive\r\n\r\n"),
5203 };
5204
5205 MockRead data_reads1[] = {
5206 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5207 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5208 MockRead("Content-Length: 10\r\n\r\n"),
5209 MockRead(SYNCHRONOUS, ERR_FAILED),
5210 };
5211
5212 // After the challenge above, the transaction will be restarted using the
5213 // identity from the url (foo, baz) to answer the challenge.
5214 MockWrite data_writes2[] = {
5215 MockWrite("GET / HTTP/1.1\r\n"
5216 "Host: www.google.com\r\n"
5217 "Connection: keep-alive\r\n"
5218 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5219 };
5220
5221 MockRead data_reads2[] = {
5222 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5223 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5224 MockRead("Content-Length: 10\r\n\r\n"),
5225 MockRead(SYNCHRONOUS, ERR_FAILED),
5226 };
5227
5228 // After the challenge above, the transaction will be restarted using the
5229 // identity supplied by the user (foo, bar) to answer the challenge.
5230 MockWrite data_writes3[] = {
5231 MockWrite("GET / HTTP/1.1\r\n"
5232 "Host: www.google.com\r\n"
5233 "Connection: keep-alive\r\n"
5234 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5235 };
5236
5237 MockRead data_reads3[] = {
5238 MockRead("HTTP/1.0 200 OK\r\n"),
5239 MockRead("Content-Length: 100\r\n\r\n"),
5240 MockRead(SYNCHRONOUS, OK),
5241 };
5242
5243 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5244 data_writes1, arraysize(data_writes1));
5245 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5246 data_writes2, arraysize(data_writes2));
5247 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5248 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075249 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5250 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5251 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165252
5253 TestCompletionCallback callback1;
5254
5255 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5256 EXPECT_EQ(ERR_IO_PENDING, rv);
5257
5258 rv = callback1.WaitForResult();
5259 EXPECT_EQ(OK, rv);
5260
5261 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5262 TestCompletionCallback callback2;
5263 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5264 EXPECT_EQ(ERR_IO_PENDING, rv);
5265 rv = callback2.WaitForResult();
5266 EXPECT_EQ(OK, rv);
5267 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5268
5269 const HttpResponseInfo* response = trans->GetResponseInfo();
5270 ASSERT_TRUE(response != NULL);
5271 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5272
5273 TestCompletionCallback callback3;
5274 rv = trans->RestartWithAuth(
5275 AuthCredentials(kFoo, kBar), callback3.callback());
5276 EXPECT_EQ(ERR_IO_PENDING, rv);
5277 rv = callback3.WaitForResult();
5278 EXPECT_EQ(OK, rv);
5279 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5280
5281 response = trans->GetResponseInfo();
5282 ASSERT_TRUE(response != NULL);
5283
5284 // There is no challenge info, since the identity worked.
5285 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5286
5287 EXPECT_EQ(100, response->headers->GetContentLength());
5288
[email protected]ea9dc9a2009-09-05 00:43:325289 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345290 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325291}
5292
[email protected]2217aa22013-10-11 03:03:545293
5294// Test the request-challenge-retry sequence for basic auth when there is a
5295// correct identity in the URL, but its use is being suppressed. The identity
5296// from the URL should never be used.
5297TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5298 HttpRequestInfo request;
5299 request.method = "GET";
5300 request.url = GURL("http://foo:[email protected]/");
5301 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5302
[email protected]3fe8d2f82013-10-17 08:56:075303 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545304 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2217aa22013-10-11 03:03:545306
5307 MockWrite data_writes1[] = {
5308 MockWrite("GET / HTTP/1.1\r\n"
5309 "Host: www.google.com\r\n"
5310 "Connection: keep-alive\r\n\r\n"),
5311 };
5312
5313 MockRead data_reads1[] = {
5314 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5315 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5316 MockRead("Content-Length: 10\r\n\r\n"),
5317 MockRead(SYNCHRONOUS, ERR_FAILED),
5318 };
5319
5320 // After the challenge above, the transaction will be restarted using the
5321 // identity supplied by the user, not the one in the URL, to answer the
5322 // challenge.
5323 MockWrite data_writes3[] = {
5324 MockWrite("GET / HTTP/1.1\r\n"
5325 "Host: www.google.com\r\n"
5326 "Connection: keep-alive\r\n"
5327 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5328 };
5329
5330 MockRead data_reads3[] = {
5331 MockRead("HTTP/1.0 200 OK\r\n"),
5332 MockRead("Content-Length: 100\r\n\r\n"),
5333 MockRead(SYNCHRONOUS, OK),
5334 };
5335
5336 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5337 data_writes1, arraysize(data_writes1));
5338 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5339 data_writes3, arraysize(data_writes3));
5340 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5341 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5342
5343 TestCompletionCallback callback1;
5344 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5345 EXPECT_EQ(ERR_IO_PENDING, rv);
5346 rv = callback1.WaitForResult();
5347 EXPECT_EQ(OK, rv);
5348 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5349
5350 const HttpResponseInfo* response = trans->GetResponseInfo();
5351 ASSERT_TRUE(response != NULL);
5352 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5353
5354 TestCompletionCallback callback3;
5355 rv = trans->RestartWithAuth(
5356 AuthCredentials(kFoo, kBar), callback3.callback());
5357 EXPECT_EQ(ERR_IO_PENDING, rv);
5358 rv = callback3.WaitForResult();
5359 EXPECT_EQ(OK, rv);
5360 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5361
5362 response = trans->GetResponseInfo();
5363 ASSERT_TRUE(response != NULL);
5364
5365 // There is no challenge info, since the identity worked.
5366 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5367 EXPECT_EQ(100, response->headers->GetContentLength());
5368
5369 // Empty the current queue.
5370 base::MessageLoop::current()->RunUntilIdle();
5371}
5372
[email protected]f9ee6b52008-11-08 06:46:235373// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025374TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075375 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235376
5377 // Transaction 1: authenticate (foo, bar) on MyRealm1
5378 {
[email protected]1c773ea12009-04-28 19:58:425379 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235380 request.method = "GET";
5381 request.url = GURL("http://www.google.com/x/y/z");
5382 request.load_flags = 0;
5383
[email protected]262eec82013-03-19 21:01:365384 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275386
[email protected]f9ee6b52008-11-08 06:46:235387 MockWrite data_writes1[] = {
5388 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5389 "Host: www.google.com\r\n"
5390 "Connection: keep-alive\r\n\r\n"),
5391 };
5392
5393 MockRead data_reads1[] = {
5394 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5395 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5396 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065397 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235398 };
5399
5400 // Resend with authorization (username=foo, password=bar)
5401 MockWrite data_writes2[] = {
5402 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5403 "Host: www.google.com\r\n"
5404 "Connection: keep-alive\r\n"
5405 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5406 };
5407
5408 // Sever accepts the authorization.
5409 MockRead data_reads2[] = {
5410 MockRead("HTTP/1.0 200 OK\r\n"),
5411 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065412 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235413 };
5414
[email protected]31a2bfe2010-02-09 08:03:395415 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5416 data_writes1, arraysize(data_writes1));
5417 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5418 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075419 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5420 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235421
[email protected]49639fa2011-12-20 23:22:415422 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235423
[email protected]49639fa2011-12-20 23:22:415424 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425425 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235426
5427 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425428 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235429
[email protected]1c773ea12009-04-28 19:58:425430 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505431 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045432 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235433
[email protected]49639fa2011-12-20 23:22:415434 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235435
[email protected]49639fa2011-12-20 23:22:415436 rv = trans->RestartWithAuth(
5437 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425438 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235439
5440 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425441 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235442
5443 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505444 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235445 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5446 EXPECT_EQ(100, response->headers->GetContentLength());
5447 }
5448
5449 // ------------------------------------------------------------------------
5450
5451 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5452 {
[email protected]1c773ea12009-04-28 19:58:425453 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235454 request.method = "GET";
5455 // Note that Transaction 1 was at /x/y/z, so this is in the same
5456 // protection space as MyRealm1.
5457 request.url = GURL("http://www.google.com/x/y/a/b");
5458 request.load_flags = 0;
5459
[email protected]262eec82013-03-19 21:01:365460 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505461 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275462
[email protected]f9ee6b52008-11-08 06:46:235463 MockWrite data_writes1[] = {
5464 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5465 "Host: www.google.com\r\n"
5466 "Connection: keep-alive\r\n"
5467 // Send preemptive authorization for MyRealm1
5468 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5469 };
5470
5471 // The server didn't like the preemptive authorization, and
5472 // challenges us for a different realm (MyRealm2).
5473 MockRead data_reads1[] = {
5474 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5475 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5476 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065477 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235478 };
5479
5480 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5481 MockWrite data_writes2[] = {
5482 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5483 "Host: www.google.com\r\n"
5484 "Connection: keep-alive\r\n"
5485 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5486 };
5487
5488 // Sever accepts the authorization.
5489 MockRead data_reads2[] = {
5490 MockRead("HTTP/1.0 200 OK\r\n"),
5491 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065492 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235493 };
5494
[email protected]31a2bfe2010-02-09 08:03:395495 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5496 data_writes1, arraysize(data_writes1));
5497 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5498 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075499 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5500 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235501
[email protected]49639fa2011-12-20 23:22:415502 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235503
[email protected]49639fa2011-12-20 23:22:415504 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425505 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235506
5507 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425508 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235509
[email protected]1c773ea12009-04-28 19:58:425510 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505511 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045512 ASSERT_TRUE(response->auth_challenge.get());
5513 EXPECT_FALSE(response->auth_challenge->is_proxy);
5514 EXPECT_EQ("www.google.com:80",
5515 response->auth_challenge->challenger.ToString());
5516 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5517 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235518
[email protected]49639fa2011-12-20 23:22:415519 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235520
[email protected]49639fa2011-12-20 23:22:415521 rv = trans->RestartWithAuth(
5522 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425523 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235524
5525 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425526 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235527
5528 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505529 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235530 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5531 EXPECT_EQ(100, response->headers->GetContentLength());
5532 }
5533
5534 // ------------------------------------------------------------------------
5535
5536 // Transaction 3: Resend a request in MyRealm's protection space --
5537 // succeed with preemptive authorization.
5538 {
[email protected]1c773ea12009-04-28 19:58:425539 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235540 request.method = "GET";
5541 request.url = GURL("http://www.google.com/x/y/z2");
5542 request.load_flags = 0;
5543
[email protected]262eec82013-03-19 21:01:365544 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505545 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275546
[email protected]f9ee6b52008-11-08 06:46:235547 MockWrite data_writes1[] = {
5548 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5549 "Host: www.google.com\r\n"
5550 "Connection: keep-alive\r\n"
5551 // The authorization for MyRealm1 gets sent preemptively
5552 // (since the url is in the same protection space)
5553 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5554 };
5555
5556 // Sever accepts the preemptive authorization
5557 MockRead data_reads1[] = {
5558 MockRead("HTTP/1.0 200 OK\r\n"),
5559 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065560 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235561 };
5562
[email protected]31a2bfe2010-02-09 08:03:395563 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5564 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075565 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235566
[email protected]49639fa2011-12-20 23:22:415567 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235568
[email protected]49639fa2011-12-20 23:22:415569 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425570 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235571
5572 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425573 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235574
[email protected]1c773ea12009-04-28 19:58:425575 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505576 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235577
5578 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5579 EXPECT_EQ(100, response->headers->GetContentLength());
5580 }
5581
5582 // ------------------------------------------------------------------------
5583
5584 // Transaction 4: request another URL in MyRealm (however the
5585 // url is not known to belong to the protection space, so no pre-auth).
5586 {
[email protected]1c773ea12009-04-28 19:58:425587 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235588 request.method = "GET";
5589 request.url = GURL("http://www.google.com/x/1");
5590 request.load_flags = 0;
5591
[email protected]262eec82013-03-19 21:01:365592 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275594
[email protected]f9ee6b52008-11-08 06:46:235595 MockWrite data_writes1[] = {
5596 MockWrite("GET /x/1 HTTP/1.1\r\n"
5597 "Host: www.google.com\r\n"
5598 "Connection: keep-alive\r\n\r\n"),
5599 };
5600
5601 MockRead data_reads1[] = {
5602 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5603 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5604 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065605 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235606 };
5607
5608 // Resend with authorization from MyRealm's cache.
5609 MockWrite data_writes2[] = {
5610 MockWrite("GET /x/1 HTTP/1.1\r\n"
5611 "Host: www.google.com\r\n"
5612 "Connection: keep-alive\r\n"
5613 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5614 };
5615
5616 // Sever accepts the authorization.
5617 MockRead data_reads2[] = {
5618 MockRead("HTTP/1.0 200 OK\r\n"),
5619 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065620 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235621 };
5622
[email protected]31a2bfe2010-02-09 08:03:395623 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5624 data_writes1, arraysize(data_writes1));
5625 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5626 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075627 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5628 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235629
[email protected]49639fa2011-12-20 23:22:415630 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235631
[email protected]49639fa2011-12-20 23:22:415632 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425633 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235634
5635 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425636 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235637
[email protected]0757e7702009-03-27 04:00:225638 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415639 TestCompletionCallback callback2;
5640 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425641 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225642 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425643 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225644 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5645
[email protected]1c773ea12009-04-28 19:58:425646 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505647 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235648 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5649 EXPECT_EQ(100, response->headers->GetContentLength());
5650 }
5651
5652 // ------------------------------------------------------------------------
5653
5654 // Transaction 5: request a URL in MyRealm, but the server rejects the
5655 // cached identity. Should invalidate and re-prompt.
5656 {
[email protected]1c773ea12009-04-28 19:58:425657 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235658 request.method = "GET";
5659 request.url = GURL("http://www.google.com/p/q/t");
5660 request.load_flags = 0;
5661
[email protected]262eec82013-03-19 21:01:365662 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505663 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275664
[email protected]f9ee6b52008-11-08 06:46:235665 MockWrite data_writes1[] = {
5666 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5667 "Host: www.google.com\r\n"
5668 "Connection: keep-alive\r\n\r\n"),
5669 };
5670
5671 MockRead data_reads1[] = {
5672 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5673 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5674 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065675 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235676 };
5677
5678 // Resend with authorization from cache for MyRealm.
5679 MockWrite data_writes2[] = {
5680 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5681 "Host: www.google.com\r\n"
5682 "Connection: keep-alive\r\n"
5683 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5684 };
5685
5686 // Sever rejects the authorization.
5687 MockRead data_reads2[] = {
5688 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5689 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5690 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065691 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235692 };
5693
5694 // At this point we should prompt for new credentials for MyRealm.
5695 // Restart with username=foo3, password=foo4.
5696 MockWrite data_writes3[] = {
5697 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5698 "Host: www.google.com\r\n"
5699 "Connection: keep-alive\r\n"
5700 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5701 };
5702
5703 // Sever accepts the authorization.
5704 MockRead data_reads3[] = {
5705 MockRead("HTTP/1.0 200 OK\r\n"),
5706 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065707 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235708 };
5709
[email protected]31a2bfe2010-02-09 08:03:395710 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5711 data_writes1, arraysize(data_writes1));
5712 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5713 data_writes2, arraysize(data_writes2));
5714 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5715 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075716 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5717 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5718 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235719
[email protected]49639fa2011-12-20 23:22:415720 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235721
[email protected]49639fa2011-12-20 23:22:415722 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425723 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235724
5725 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425726 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235727
[email protected]0757e7702009-03-27 04:00:225728 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415729 TestCompletionCallback callback2;
5730 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425731 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225732 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425733 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225734 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5735
[email protected]1c773ea12009-04-28 19:58:425736 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505737 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045738 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235739
[email protected]49639fa2011-12-20 23:22:415740 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235741
[email protected]49639fa2011-12-20 23:22:415742 rv = trans->RestartWithAuth(
5743 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425744 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235745
[email protected]0757e7702009-03-27 04:00:225746 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425747 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235748
5749 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505750 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235751 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5752 EXPECT_EQ(100, response->headers->GetContentLength());
5753 }
5754}
[email protected]89ceba9a2009-03-21 03:46:065755
[email protected]3c32c5f2010-05-18 15:18:125756// Tests that nonce count increments when multiple auth attempts
5757// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025758TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445759 HttpAuthHandlerDigest::Factory* digest_factory =
5760 new HttpAuthHandlerDigest::Factory();
5761 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5762 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5763 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075764 session_deps_.http_auth_handler_factory.reset(digest_factory);
5765 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125766
5767 // Transaction 1: authenticate (foo, bar) on MyRealm1
5768 {
[email protected]3c32c5f2010-05-18 15:18:125769 HttpRequestInfo request;
5770 request.method = "GET";
5771 request.url = GURL("http://www.google.com/x/y/z");
5772 request.load_flags = 0;
5773
[email protected]262eec82013-03-19 21:01:365774 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505775 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275776
[email protected]3c32c5f2010-05-18 15:18:125777 MockWrite data_writes1[] = {
5778 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5779 "Host: www.google.com\r\n"
5780 "Connection: keep-alive\r\n\r\n"),
5781 };
5782
5783 MockRead data_reads1[] = {
5784 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5785 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5786 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065787 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125788 };
5789
5790 // Resend with authorization (username=foo, password=bar)
5791 MockWrite data_writes2[] = {
5792 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5793 "Host: www.google.com\r\n"
5794 "Connection: keep-alive\r\n"
5795 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5796 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5797 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5798 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5799 };
5800
5801 // Sever accepts the authorization.
5802 MockRead data_reads2[] = {
5803 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065804 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125805 };
5806
5807 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5808 data_writes1, arraysize(data_writes1));
5809 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5810 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075811 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5812 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125813
[email protected]49639fa2011-12-20 23:22:415814 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125815
[email protected]49639fa2011-12-20 23:22:415816 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125817 EXPECT_EQ(ERR_IO_PENDING, rv);
5818
5819 rv = callback1.WaitForResult();
5820 EXPECT_EQ(OK, rv);
5821
5822 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505823 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045824 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125825
[email protected]49639fa2011-12-20 23:22:415826 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125827
[email protected]49639fa2011-12-20 23:22:415828 rv = trans->RestartWithAuth(
5829 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125830 EXPECT_EQ(ERR_IO_PENDING, rv);
5831
5832 rv = callback2.WaitForResult();
5833 EXPECT_EQ(OK, rv);
5834
5835 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505836 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125837 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5838 }
5839
5840 // ------------------------------------------------------------------------
5841
5842 // Transaction 2: Request another resource in digestive's protection space.
5843 // This will preemptively add an Authorization header which should have an
5844 // "nc" value of 2 (as compared to 1 in the first use.
5845 {
[email protected]3c32c5f2010-05-18 15:18:125846 HttpRequestInfo request;
5847 request.method = "GET";
5848 // Note that Transaction 1 was at /x/y/z, so this is in the same
5849 // protection space as digest.
5850 request.url = GURL("http://www.google.com/x/y/a/b");
5851 request.load_flags = 0;
5852
[email protected]262eec82013-03-19 21:01:365853 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505854 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275855
[email protected]3c32c5f2010-05-18 15:18:125856 MockWrite data_writes1[] = {
5857 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5858 "Host: www.google.com\r\n"
5859 "Connection: keep-alive\r\n"
5860 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5861 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5862 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5863 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5864 };
5865
5866 // Sever accepts the authorization.
5867 MockRead data_reads1[] = {
5868 MockRead("HTTP/1.0 200 OK\r\n"),
5869 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065870 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125871 };
5872
5873 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5874 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075875 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125876
[email protected]49639fa2011-12-20 23:22:415877 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125878
[email protected]49639fa2011-12-20 23:22:415879 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125880 EXPECT_EQ(ERR_IO_PENDING, rv);
5881
5882 rv = callback1.WaitForResult();
5883 EXPECT_EQ(OK, rv);
5884
5885 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505886 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125887 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5888 }
5889}
5890
[email protected]89ceba9a2009-03-21 03:46:065891// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025892TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065893 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075894 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405895 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]89ceba9a2009-03-21 03:46:065897
5898 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065899 trans->read_buf_ = new IOBuffer(15);
5900 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205901 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065902
5903 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145904 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575905 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085906 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575907 response->response_time = base::Time::Now();
5908 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065909
5910 { // Setup state for response_.vary_data
5911 HttpRequestInfo request;
5912 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5913 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275914 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435915 request.extra_headers.SetHeader("Foo", "1");
5916 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505917 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065918 }
5919
5920 // Cause the above state to be reset.
5921 trans->ResetStateForRestart();
5922
5923 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075924 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065925 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205926 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575927 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5928 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045929 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085930 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575931 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065932}
5933
[email protected]bacff652009-03-31 17:50:335934// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025935TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335936 HttpRequestInfo request;
5937 request.method = "GET";
5938 request.url = GURL("https://www.google.com/");
5939 request.load_flags = 0;
5940
[email protected]3fe8d2f82013-10-17 08:56:075941 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275942 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075943 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275944
[email protected]bacff652009-03-31 17:50:335945 MockWrite data_writes[] = {
5946 MockWrite("GET / HTTP/1.1\r\n"
5947 "Host: www.google.com\r\n"
5948 "Connection: keep-alive\r\n\r\n"),
5949 };
5950
5951 MockRead data_reads[] = {
5952 MockRead("HTTP/1.0 200 OK\r\n"),
5953 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5954 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065955 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335956 };
5957
[email protected]5ecc992a42009-11-11 01:41:595958 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395959 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5960 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065961 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5962 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335963
[email protected]bb88e1d32013-05-03 23:11:075964 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5965 session_deps_.socket_factory->AddSocketDataProvider(&data);
5966 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5967 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335968
[email protected]49639fa2011-12-20 23:22:415969 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335970
[email protected]49639fa2011-12-20 23:22:415971 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335972 EXPECT_EQ(ERR_IO_PENDING, rv);
5973
5974 rv = callback.WaitForResult();
5975 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5976
[email protected]49639fa2011-12-20 23:22:415977 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335978 EXPECT_EQ(ERR_IO_PENDING, rv);
5979
5980 rv = callback.WaitForResult();
5981 EXPECT_EQ(OK, rv);
5982
5983 const HttpResponseInfo* response = trans->GetResponseInfo();
5984
[email protected]fe2255a2011-09-20 19:37:505985 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335986 EXPECT_EQ(100, response->headers->GetContentLength());
5987}
5988
5989// Test HTTPS connections to a site with a bad certificate, going through a
5990// proxy
[email protected]23e482282013-06-14 16:08:025991TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075992 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335993
5994 HttpRequestInfo request;
5995 request.method = "GET";
5996 request.url = GURL("https://www.google.com/");
5997 request.load_flags = 0;
5998
5999 MockWrite proxy_writes[] = {
6000 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456001 "Host: www.google.com\r\n"
6002 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336003 };
6004
6005 MockRead proxy_reads[] = {
6006 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066007 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336008 };
6009
6010 MockWrite data_writes[] = {
6011 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456012 "Host: www.google.com\r\n"
6013 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336014 MockWrite("GET / HTTP/1.1\r\n"
6015 "Host: www.google.com\r\n"
6016 "Connection: keep-alive\r\n\r\n"),
6017 };
6018
6019 MockRead data_reads[] = {
6020 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6021 MockRead("HTTP/1.0 200 OK\r\n"),
6022 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6023 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066024 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336025 };
6026
[email protected]31a2bfe2010-02-09 08:03:396027 StaticSocketDataProvider ssl_bad_certificate(
6028 proxy_reads, arraysize(proxy_reads),
6029 proxy_writes, arraysize(proxy_writes));
6030 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6031 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066032 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6033 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336034
[email protected]bb88e1d32013-05-03 23:11:076035 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6036 session_deps_.socket_factory->AddSocketDataProvider(&data);
6037 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336039
[email protected]49639fa2011-12-20 23:22:416040 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336041
6042 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076043 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336044
[email protected]3fe8d2f82013-10-17 08:56:076045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406046 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076047 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]bacff652009-03-31 17:50:336048
[email protected]49639fa2011-12-20 23:22:416049 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336050 EXPECT_EQ(ERR_IO_PENDING, rv);
6051
6052 rv = callback.WaitForResult();
6053 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6054
[email protected]49639fa2011-12-20 23:22:416055 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336056 EXPECT_EQ(ERR_IO_PENDING, rv);
6057
6058 rv = callback.WaitForResult();
6059 EXPECT_EQ(OK, rv);
6060
6061 const HttpResponseInfo* response = trans->GetResponseInfo();
6062
[email protected]fe2255a2011-09-20 19:37:506063 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336064 EXPECT_EQ(100, response->headers->GetContentLength());
6065 }
6066}
6067
[email protected]2df19bb2010-08-25 20:13:466068
6069// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026070TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076071 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206072 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6073 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076074 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466075
6076 HttpRequestInfo request;
6077 request.method = "GET";
6078 request.url = GURL("https://www.google.com/");
6079 request.load_flags = 0;
6080
6081 MockWrite data_writes[] = {
6082 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6083 "Host: www.google.com\r\n"
6084 "Proxy-Connection: keep-alive\r\n\r\n"),
6085 MockWrite("GET / HTTP/1.1\r\n"
6086 "Host: www.google.com\r\n"
6087 "Connection: keep-alive\r\n\r\n"),
6088 };
6089
6090 MockRead data_reads[] = {
6091 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6092 MockRead("HTTP/1.1 200 OK\r\n"),
6093 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6094 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066095 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466096 };
6097
6098 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6099 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066100 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6101 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466102
[email protected]bb88e1d32013-05-03 23:11:076103 session_deps_.socket_factory->AddSocketDataProvider(&data);
6104 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6105 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466106
[email protected]49639fa2011-12-20 23:22:416107 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466108
[email protected]3fe8d2f82013-10-17 08:56:076109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466110 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076111 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466112
[email protected]49639fa2011-12-20 23:22:416113 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466114 EXPECT_EQ(ERR_IO_PENDING, rv);
6115
6116 rv = callback.WaitForResult();
6117 EXPECT_EQ(OK, rv);
6118 const HttpResponseInfo* response = trans->GetResponseInfo();
6119
[email protected]fe2255a2011-09-20 19:37:506120 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466121
6122 EXPECT_TRUE(response->headers->IsKeepAlive());
6123 EXPECT_EQ(200, response->headers->response_code());
6124 EXPECT_EQ(100, response->headers->GetContentLength());
6125 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206126
6127 LoadTimingInfo load_timing_info;
6128 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6129 TestLoadTimingNotReusedWithPac(load_timing_info,
6130 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466131}
6132
[email protected]511f6f52010-12-17 03:58:296133// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026134TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076135 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206136 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6137 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076138 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296139
6140 HttpRequestInfo request;
6141 request.method = "GET";
6142 request.url = GURL("https://www.google.com/");
6143 request.load_flags = 0;
6144
6145 MockWrite data_writes[] = {
6146 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6147 "Host: www.google.com\r\n"
6148 "Proxy-Connection: keep-alive\r\n\r\n"),
6149 };
6150
6151 MockRead data_reads[] = {
6152 MockRead("HTTP/1.1 302 Redirect\r\n"),
6153 MockRead("Location: http://login.example.com/\r\n"),
6154 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066155 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296156 };
6157
6158 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6159 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066160 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296161
[email protected]bb88e1d32013-05-03 23:11:076162 session_deps_.socket_factory->AddSocketDataProvider(&data);
6163 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296164
[email protected]49639fa2011-12-20 23:22:416165 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296166
[email protected]3fe8d2f82013-10-17 08:56:076167 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296168 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296170
[email protected]49639fa2011-12-20 23:22:416171 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296172 EXPECT_EQ(ERR_IO_PENDING, rv);
6173
6174 rv = callback.WaitForResult();
6175 EXPECT_EQ(OK, rv);
6176 const HttpResponseInfo* response = trans->GetResponseInfo();
6177
[email protected]fe2255a2011-09-20 19:37:506178 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296179
6180 EXPECT_EQ(302, response->headers->response_code());
6181 std::string url;
6182 EXPECT_TRUE(response->headers->IsRedirect(&url));
6183 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206184
6185 // In the case of redirects from proxies, HttpNetworkTransaction returns
6186 // timing for the proxy connection instead of the connection to the host,
6187 // and no send / receive times.
6188 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6189 LoadTimingInfo load_timing_info;
6190 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6191
6192 EXPECT_FALSE(load_timing_info.socket_reused);
6193 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6194
6195 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6196 EXPECT_LE(load_timing_info.proxy_resolve_start,
6197 load_timing_info.proxy_resolve_end);
6198 EXPECT_LE(load_timing_info.proxy_resolve_end,
6199 load_timing_info.connect_timing.connect_start);
6200 ExpectConnectTimingHasTimes(
6201 load_timing_info.connect_timing,
6202 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6203
6204 EXPECT_TRUE(load_timing_info.send_start.is_null());
6205 EXPECT_TRUE(load_timing_info.send_end.is_null());
6206 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296207}
6208
6209// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026210TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076211 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296212 ProxyService::CreateFixed("https://proxy:70"));
6213
6214 HttpRequestInfo request;
6215 request.method = "GET";
6216 request.url = GURL("https://www.google.com/");
6217 request.load_flags = 0;
6218
[email protected]9075f51c2013-08-15 17:53:546219 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6220 LOWEST));
[email protected]c10b20852013-05-15 21:29:206221 scoped_ptr<SpdyFrame> goaway(
6222 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296223 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066224 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:126225 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296226 };
6227
6228 static const char* const kExtraHeaders[] = {
6229 "location",
6230 "http://login.example.com/",
6231 };
[email protected]ff98d7f02012-03-22 21:44:196232 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026233 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296234 arraysize(kExtraHeaders)/2, 1));
6235 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066236 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6237 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:296238 };
6239
[email protected]dd54bd82012-07-19 23:44:576240 DelayedSocketData data(
6241 1, // wait for one write to finish before reading.
6242 data_reads, arraysize(data_reads),
6243 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066244 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026245 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296246
[email protected]bb88e1d32013-05-03 23:11:076247 session_deps_.socket_factory->AddSocketDataProvider(&data);
6248 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296249
[email protected]49639fa2011-12-20 23:22:416250 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296251
[email protected]3fe8d2f82013-10-17 08:56:076252 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296253 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076254 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296255
[email protected]49639fa2011-12-20 23:22:416256 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296257 EXPECT_EQ(ERR_IO_PENDING, rv);
6258
6259 rv = callback.WaitForResult();
6260 EXPECT_EQ(OK, rv);
6261 const HttpResponseInfo* response = trans->GetResponseInfo();
6262
[email protected]fe2255a2011-09-20 19:37:506263 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296264
6265 EXPECT_EQ(302, response->headers->response_code());
6266 std::string url;
6267 EXPECT_TRUE(response->headers->IsRedirect(&url));
6268 EXPECT_EQ("http://login.example.com/", url);
6269}
6270
[email protected]4eddbc732012-08-09 05:40:176271// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026272TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176273 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076274 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296275 ProxyService::CreateFixed("https://proxy:70"));
6276
6277 HttpRequestInfo request;
6278 request.method = "GET";
6279 request.url = GURL("https://www.google.com/");
6280 request.load_flags = 0;
6281
6282 MockWrite data_writes[] = {
6283 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6284 "Host: www.google.com\r\n"
6285 "Proxy-Connection: keep-alive\r\n\r\n"),
6286 };
6287
6288 MockRead data_reads[] = {
6289 MockRead("HTTP/1.1 404 Not Found\r\n"),
6290 MockRead("Content-Length: 23\r\n\r\n"),
6291 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066292 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296293 };
6294
6295 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6296 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066297 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296298
[email protected]bb88e1d32013-05-03 23:11:076299 session_deps_.socket_factory->AddSocketDataProvider(&data);
6300 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296301
[email protected]49639fa2011-12-20 23:22:416302 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296303
[email protected]3fe8d2f82013-10-17 08:56:076304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296305 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296307
[email protected]49639fa2011-12-20 23:22:416308 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296309 EXPECT_EQ(ERR_IO_PENDING, rv);
6310
6311 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176312 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296313
[email protected]4eddbc732012-08-09 05:40:176314 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296315}
6316
[email protected]4eddbc732012-08-09 05:40:176317// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026318TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176319 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076320 session_deps_.proxy_service.reset(
6321 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296322
6323 HttpRequestInfo request;
6324 request.method = "GET";
6325 request.url = GURL("https://www.google.com/");
6326 request.load_flags = 0;
6327
[email protected]9075f51c2013-08-15 17:53:546328 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6329 LOWEST));
[email protected]c10b20852013-05-15 21:29:206330 scoped_ptr<SpdyFrame> rst(
6331 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296332 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066333 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176334 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296335 };
6336
6337 static const char* const kExtraHeaders[] = {
6338 "location",
6339 "http://login.example.com/",
6340 };
[email protected]ff98d7f02012-03-22 21:44:196341 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026342 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296343 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196344 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026345 spdy_util_.ConstructSpdyBodyFrame(
6346 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296347 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066348 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6349 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176350 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296351 };
6352
[email protected]dd54bd82012-07-19 23:44:576353 DelayedSocketData data(
6354 1, // wait for one write to finish before reading.
6355 data_reads, arraysize(data_reads),
6356 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066357 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026358 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296359
[email protected]bb88e1d32013-05-03 23:11:076360 session_deps_.socket_factory->AddSocketDataProvider(&data);
6361 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296362
[email protected]49639fa2011-12-20 23:22:416363 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296364
[email protected]3fe8d2f82013-10-17 08:56:076365 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296366 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076367 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296368
[email protected]49639fa2011-12-20 23:22:416369 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296370 EXPECT_EQ(ERR_IO_PENDING, rv);
6371
6372 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176373 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296374
[email protected]4eddbc732012-08-09 05:40:176375 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296376}
6377
[email protected]0c5fb722012-02-28 11:50:356378// Test the request-challenge-retry sequence for basic auth, through
6379// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026380TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356381 HttpRequestInfo request;
6382 request.method = "GET";
6383 request.url = GURL("https://www.google.com/");
6384 // when the no authentication data flag is set.
6385 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6386
6387 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076388 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206389 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296390 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076391 session_deps_.net_log = log.bound().net_log();
6392 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356393
6394 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:546395 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6396 LOWEST));
[email protected]c10b20852013-05-15 21:29:206397 scoped_ptr<SpdyFrame> rst(
6398 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356399
6400 // After calling trans->RestartWithAuth(), this is the request we should
6401 // be issuing -- the final header line contains the credentials.
6402 const char* const kAuthCredentials[] = {
6403 "proxy-authorization", "Basic Zm9vOmJhcg==",
6404 };
[email protected]fba2dbde2013-05-24 16:09:016405 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:546406 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:356407 // fetch https://www.google.com/ via HTTP
6408 const char get[] = "GET / HTTP/1.1\r\n"
6409 "Host: www.google.com\r\n"
6410 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196411 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026412 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356413
6414 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206415 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216416 CreateMockWrite(*rst, 4, ASYNC),
6417 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206418 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356419 };
6420
6421 // The proxy responds to the connect with a 407, using a persistent
6422 // connection.
[email protected]745aa9c2014-06-27 02:21:296423 const char* const kAuthStatus = "407";
[email protected]0c5fb722012-02-28 11:50:356424 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356425 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6426 };
[email protected]745aa9c2014-06-27 02:21:296427 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6428 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356429
[email protected]23e482282013-06-14 16:08:026430 scoped_ptr<SpdyFrame> conn_resp(
6431 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356432 const char resp[] = "HTTP/1.1 200 OK\r\n"
6433 "Content-Length: 5\r\n\r\n";
6434
[email protected]ff98d7f02012-03-22 21:44:196435 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026436 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196437 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026438 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356439 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206440 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6441 CreateMockRead(*conn_resp, 6, ASYNC),
6442 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6443 CreateMockRead(*wrapped_body, 10, ASYNC),
6444 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356445 };
6446
[email protected]dd54bd82012-07-19 23:44:576447 OrderedSocketData spdy_data(
6448 spdy_reads, arraysize(spdy_reads),
6449 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076450 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356451 // Negotiate SPDY to the proxy
6452 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026453 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076454 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356455 // Vanilla SSL to the server
6456 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076457 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356458
6459 TestCompletionCallback callback1;
6460
[email protected]262eec82013-03-19 21:01:366461 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506462 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356463
6464 int rv = trans->Start(&request, callback1.callback(), log.bound());
6465 EXPECT_EQ(ERR_IO_PENDING, rv);
6466
6467 rv = callback1.WaitForResult();
6468 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576469 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356470 log.GetEntries(&entries);
6471 size_t pos = ExpectLogContainsSomewhere(
6472 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6473 NetLog::PHASE_NONE);
6474 ExpectLogContainsSomewhere(
6475 entries, pos,
6476 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6477 NetLog::PHASE_NONE);
6478
6479 const HttpResponseInfo* response = trans->GetResponseInfo();
6480 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506481 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356482 EXPECT_EQ(407, response->headers->response_code());
6483 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6484 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6485 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6486
6487 TestCompletionCallback callback2;
6488
6489 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6490 callback2.callback());
6491 EXPECT_EQ(ERR_IO_PENDING, rv);
6492
6493 rv = callback2.WaitForResult();
6494 EXPECT_EQ(OK, rv);
6495
6496 response = trans->GetResponseInfo();
6497 ASSERT_TRUE(response != NULL);
6498
6499 EXPECT_TRUE(response->headers->IsKeepAlive());
6500 EXPECT_EQ(200, response->headers->response_code());
6501 EXPECT_EQ(5, response->headers->GetContentLength());
6502 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6503
6504 // The password prompt info should not be set.
6505 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6506
[email protected]029c83b62013-01-24 05:28:206507 LoadTimingInfo load_timing_info;
6508 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6509 TestLoadTimingNotReusedWithPac(load_timing_info,
6510 CONNECT_TIMING_HAS_SSL_TIMES);
6511
[email protected]0c5fb722012-02-28 11:50:356512 trans.reset();
6513 session->CloseAllConnections();
6514}
6515
[email protected]7c6f7ba2012-04-03 04:09:296516// Test that an explicitly trusted SPDY proxy can push a resource from an
6517// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026518TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296519 HttpRequestInfo request;
6520 HttpRequestInfo push_request;
6521
[email protected]7c6f7ba2012-04-03 04:09:296522 request.method = "GET";
6523 request.url = GURL("http://www.google.com/");
6524 push_request.method = "GET";
6525 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6526
[email protected]7c6f7ba2012-04-03 04:09:296527 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076528 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206529 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296530 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076531 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506532
6533 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076534 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506535
[email protected]bb88e1d32013-05-03 23:11:076536 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296537
[email protected]cdf8f7e72013-05-23 10:56:466538 scoped_ptr<SpdyFrame> stream1_syn(
6539 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296540
6541 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466542 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296543 };
6544
6545 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026546 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296547
6548 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026549 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296550
6551 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026552 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296553 0,
6554 2,
6555 1,
6556 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436557 const char kPushedData[] = "pushed";
6558 scoped_ptr<SpdyFrame> stream2_body(
6559 spdy_util_.ConstructSpdyBodyFrame(
6560 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296561
6562 MockRead spdy_reads[] = {
6563 CreateMockRead(*stream1_reply, 2, ASYNC),
6564 CreateMockRead(*stream2_syn, 3, ASYNC),
6565 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436566 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296567 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6568 };
6569
[email protected]dd54bd82012-07-19 23:44:576570 OrderedSocketData spdy_data(
6571 spdy_reads, arraysize(spdy_reads),
6572 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076573 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296574 // Negotiate SPDY to the proxy
6575 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026576 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076577 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296578
[email protected]262eec82013-03-19 21:01:366579 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506580 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296581 TestCompletionCallback callback;
6582 int rv = trans->Start(&request, callback.callback(), log.bound());
6583 EXPECT_EQ(ERR_IO_PENDING, rv);
6584
6585 rv = callback.WaitForResult();
6586 EXPECT_EQ(OK, rv);
6587 const HttpResponseInfo* response = trans->GetResponseInfo();
6588
[email protected]262eec82013-03-19 21:01:366589 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506590 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6591 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296592 EXPECT_EQ(ERR_IO_PENDING, rv);
6593
6594 rv = callback.WaitForResult();
6595 EXPECT_EQ(OK, rv);
6596 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6597
6598 ASSERT_TRUE(response != NULL);
6599 EXPECT_TRUE(response->headers->IsKeepAlive());
6600
6601 EXPECT_EQ(200, response->headers->response_code());
6602 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6603
6604 std::string response_data;
6605 rv = ReadTransaction(trans.get(), &response_data);
6606 EXPECT_EQ(OK, rv);
6607 EXPECT_EQ("hello!", response_data);
6608
[email protected]029c83b62013-01-24 05:28:206609 LoadTimingInfo load_timing_info;
6610 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6611 TestLoadTimingNotReusedWithPac(load_timing_info,
6612 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6613
[email protected]7c6f7ba2012-04-03 04:09:296614 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506615 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296616 EXPECT_EQ(200, push_response->headers->response_code());
6617
6618 rv = ReadTransaction(push_trans.get(), &response_data);
6619 EXPECT_EQ(OK, rv);
6620 EXPECT_EQ("pushed", response_data);
6621
[email protected]029c83b62013-01-24 05:28:206622 LoadTimingInfo push_load_timing_info;
6623 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6624 TestLoadTimingReusedWithPac(push_load_timing_info);
6625 // The transactions should share a socket ID, despite being for different
6626 // origins.
6627 EXPECT_EQ(load_timing_info.socket_log_id,
6628 push_load_timing_info.socket_log_id);
6629
[email protected]7c6f7ba2012-04-03 04:09:296630 trans.reset();
6631 push_trans.reset();
6632 session->CloseAllConnections();
6633}
6634
[email protected]8c843192012-04-05 07:15:006635// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026636TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006637 HttpRequestInfo request;
6638
6639 request.method = "GET";
6640 request.url = GURL("http://www.google.com/");
6641
[email protected]8c843192012-04-05 07:15:006642 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076643 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006644 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296645 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076646 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506647
6648 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076649 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506650
[email protected]bb88e1d32013-05-03 23:11:076651 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006652
[email protected]cdf8f7e72013-05-23 10:56:466653 scoped_ptr<SpdyFrame> stream1_syn(
6654 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006655
6656 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206657 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006658
6659 MockWrite spdy_writes[] = {
6660 CreateMockWrite(*stream1_syn, 1, ASYNC),
6661 CreateMockWrite(*push_rst, 4),
6662 };
6663
6664 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026665 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006666
6667 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026668 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006669
6670 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026671 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006672 0,
6673 2,
6674 1,
6675 "https://www.another-origin.com/foo.dat"));
6676
6677 MockRead spdy_reads[] = {
6678 CreateMockRead(*stream1_reply, 2, ASYNC),
6679 CreateMockRead(*stream2_syn, 3, ASYNC),
6680 CreateMockRead(*stream1_body, 5, ASYNC),
6681 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6682 };
6683
[email protected]dd54bd82012-07-19 23:44:576684 OrderedSocketData spdy_data(
6685 spdy_reads, arraysize(spdy_reads),
6686 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076687 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006688 // Negotiate SPDY to the proxy
6689 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026690 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076691 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006692
[email protected]262eec82013-03-19 21:01:366693 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506694 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006695 TestCompletionCallback callback;
6696 int rv = trans->Start(&request, callback.callback(), log.bound());
6697 EXPECT_EQ(ERR_IO_PENDING, rv);
6698
6699 rv = callback.WaitForResult();
6700 EXPECT_EQ(OK, rv);
6701 const HttpResponseInfo* response = trans->GetResponseInfo();
6702
6703 ASSERT_TRUE(response != NULL);
6704 EXPECT_TRUE(response->headers->IsKeepAlive());
6705
6706 EXPECT_EQ(200, response->headers->response_code());
6707 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6708
6709 std::string response_data;
6710 rv = ReadTransaction(trans.get(), &response_data);
6711 EXPECT_EQ(OK, rv);
6712 EXPECT_EQ("hello!", response_data);
6713
6714 trans.reset();
6715 session->CloseAllConnections();
6716}
6717
[email protected]2df19bb2010-08-25 20:13:466718// Test HTTPS connections to a site with a bad certificate, going through an
6719// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026720TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076721 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116722 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466723
6724 HttpRequestInfo request;
6725 request.method = "GET";
6726 request.url = GURL("https://www.google.com/");
6727 request.load_flags = 0;
6728
6729 // Attempt to fetch the URL from a server with a bad cert
6730 MockWrite bad_cert_writes[] = {
6731 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6732 "Host: www.google.com\r\n"
6733 "Proxy-Connection: keep-alive\r\n\r\n"),
6734 };
6735
6736 MockRead bad_cert_reads[] = {
6737 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066738 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466739 };
6740
6741 // Attempt to fetch the URL with a good cert
6742 MockWrite good_data_writes[] = {
6743 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6744 "Host: www.google.com\r\n"
6745 "Proxy-Connection: keep-alive\r\n\r\n"),
6746 MockWrite("GET / HTTP/1.1\r\n"
6747 "Host: www.google.com\r\n"
6748 "Connection: keep-alive\r\n\r\n"),
6749 };
6750
6751 MockRead good_cert_reads[] = {
6752 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6753 MockRead("HTTP/1.0 200 OK\r\n"),
6754 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6755 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066756 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466757 };
6758
6759 StaticSocketDataProvider ssl_bad_certificate(
6760 bad_cert_reads, arraysize(bad_cert_reads),
6761 bad_cert_writes, arraysize(bad_cert_writes));
6762 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6763 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066764 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6765 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466766
6767 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076768 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6769 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6770 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466771
6772 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6774 session_deps_.socket_factory->AddSocketDataProvider(&data);
6775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466776
[email protected]49639fa2011-12-20 23:22:416777 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466778
[email protected]3fe8d2f82013-10-17 08:56:076779 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466780 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076781 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466782
[email protected]49639fa2011-12-20 23:22:416783 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466784 EXPECT_EQ(ERR_IO_PENDING, rv);
6785
6786 rv = callback.WaitForResult();
6787 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6788
[email protected]49639fa2011-12-20 23:22:416789 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466790 EXPECT_EQ(ERR_IO_PENDING, rv);
6791
6792 rv = callback.WaitForResult();
6793 EXPECT_EQ(OK, rv);
6794
6795 const HttpResponseInfo* response = trans->GetResponseInfo();
6796
[email protected]fe2255a2011-09-20 19:37:506797 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466798 EXPECT_EQ(100, response->headers->GetContentLength());
6799}
6800
[email protected]23e482282013-06-14 16:08:026801TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426802 HttpRequestInfo request;
6803 request.method = "GET";
6804 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436805 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6806 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426807
[email protected]3fe8d2f82013-10-17 08:56:076808 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276809 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076810 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276811
[email protected]1c773ea12009-04-28 19:58:426812 MockWrite data_writes[] = {
6813 MockWrite("GET / HTTP/1.1\r\n"
6814 "Host: www.google.com\r\n"
6815 "Connection: keep-alive\r\n"
6816 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6817 };
6818
6819 // Lastly, the server responds with the actual content.
6820 MockRead data_reads[] = {
6821 MockRead("HTTP/1.0 200 OK\r\n"),
6822 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6823 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066824 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426825 };
6826
[email protected]31a2bfe2010-02-09 08:03:396827 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6828 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076829 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426830
[email protected]49639fa2011-12-20 23:22:416831 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426832
[email protected]49639fa2011-12-20 23:22:416833 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426834 EXPECT_EQ(ERR_IO_PENDING, rv);
6835
6836 rv = callback.WaitForResult();
6837 EXPECT_EQ(OK, rv);
6838}
6839
[email protected]23e482282013-06-14 16:08:026840TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296841 HttpRequestInfo request;
6842 request.method = "GET";
6843 request.url = GURL("https://www.google.com/");
6844 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6845 "Chromium Ultra Awesome X Edition");
6846
[email protected]bb88e1d32013-05-03 23:11:076847 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076848 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276849 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276851
[email protected]da81f132010-08-18 23:39:296852 MockWrite data_writes[] = {
6853 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6854 "Host: www.google.com\r\n"
6855 "Proxy-Connection: keep-alive\r\n"
6856 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6857 };
6858 MockRead data_reads[] = {
6859 // Return an error, so the transaction stops here (this test isn't
6860 // interested in the rest).
6861 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6862 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6863 MockRead("Proxy-Connection: close\r\n\r\n"),
6864 };
6865
6866 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6867 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076868 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296869
[email protected]49639fa2011-12-20 23:22:416870 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296871
[email protected]49639fa2011-12-20 23:22:416872 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296873 EXPECT_EQ(ERR_IO_PENDING, rv);
6874
6875 rv = callback.WaitForResult();
6876 EXPECT_EQ(OK, rv);
6877}
6878
[email protected]23e482282013-06-14 16:08:026879TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426880 HttpRequestInfo request;
6881 request.method = "GET";
6882 request.url = GURL("http://www.google.com/");
6883 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166884 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6885 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426886
[email protected]3fe8d2f82013-10-17 08:56:076887 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276888 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076889 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276890
[email protected]1c773ea12009-04-28 19:58:426891 MockWrite data_writes[] = {
6892 MockWrite("GET / HTTP/1.1\r\n"
6893 "Host: www.google.com\r\n"
6894 "Connection: keep-alive\r\n"
6895 "Referer: http://the.previous.site.com/\r\n\r\n"),
6896 };
6897
6898 // Lastly, the server responds with the actual content.
6899 MockRead data_reads[] = {
6900 MockRead("HTTP/1.0 200 OK\r\n"),
6901 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6902 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066903 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426904 };
6905
[email protected]31a2bfe2010-02-09 08:03:396906 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6907 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076908 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426909
[email protected]49639fa2011-12-20 23:22:416910 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426911
[email protected]49639fa2011-12-20 23:22:416912 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426913 EXPECT_EQ(ERR_IO_PENDING, rv);
6914
6915 rv = callback.WaitForResult();
6916 EXPECT_EQ(OK, rv);
6917}
6918
[email protected]23e482282013-06-14 16:08:026919TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426920 HttpRequestInfo request;
6921 request.method = "POST";
6922 request.url = GURL("http://www.google.com/");
6923
[email protected]3fe8d2f82013-10-17 08:56:076924 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276925 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076926 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276927
[email protected]1c773ea12009-04-28 19:58:426928 MockWrite data_writes[] = {
6929 MockWrite("POST / HTTP/1.1\r\n"
6930 "Host: www.google.com\r\n"
6931 "Connection: keep-alive\r\n"
6932 "Content-Length: 0\r\n\r\n"),
6933 };
6934
6935 // Lastly, the server responds with the actual content.
6936 MockRead data_reads[] = {
6937 MockRead("HTTP/1.0 200 OK\r\n"),
6938 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6939 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066940 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426941 };
6942
[email protected]31a2bfe2010-02-09 08:03:396943 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6944 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076945 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426946
[email protected]49639fa2011-12-20 23:22:416947 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426948
[email protected]49639fa2011-12-20 23:22:416949 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426950 EXPECT_EQ(ERR_IO_PENDING, rv);
6951
6952 rv = callback.WaitForResult();
6953 EXPECT_EQ(OK, rv);
6954}
6955
[email protected]23e482282013-06-14 16:08:026956TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426957 HttpRequestInfo request;
6958 request.method = "PUT";
6959 request.url = GURL("http://www.google.com/");
6960
[email protected]3fe8d2f82013-10-17 08:56:076961 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276962 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076963 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276964
[email protected]1c773ea12009-04-28 19:58:426965 MockWrite data_writes[] = {
6966 MockWrite("PUT / HTTP/1.1\r\n"
6967 "Host: www.google.com\r\n"
6968 "Connection: keep-alive\r\n"
6969 "Content-Length: 0\r\n\r\n"),
6970 };
6971
6972 // Lastly, the server responds with the actual content.
6973 MockRead data_reads[] = {
6974 MockRead("HTTP/1.0 200 OK\r\n"),
6975 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6976 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066977 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426978 };
6979
[email protected]31a2bfe2010-02-09 08:03:396980 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6981 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076982 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426983
[email protected]49639fa2011-12-20 23:22:416984 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426985
[email protected]49639fa2011-12-20 23:22:416986 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426987 EXPECT_EQ(ERR_IO_PENDING, rv);
6988
6989 rv = callback.WaitForResult();
6990 EXPECT_EQ(OK, rv);
6991}
6992
[email protected]23e482282013-06-14 16:08:026993TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426994 HttpRequestInfo request;
6995 request.method = "HEAD";
6996 request.url = GURL("http://www.google.com/");
6997
[email protected]3fe8d2f82013-10-17 08:56:076998 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276999 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077000 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277001
[email protected]1c773ea12009-04-28 19:58:427002 MockWrite data_writes[] = {
7003 MockWrite("HEAD / HTTP/1.1\r\n"
7004 "Host: www.google.com\r\n"
7005 "Connection: keep-alive\r\n"
7006 "Content-Length: 0\r\n\r\n"),
7007 };
7008
7009 // Lastly, the server responds with the actual content.
7010 MockRead data_reads[] = {
7011 MockRead("HTTP/1.0 200 OK\r\n"),
7012 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7013 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067014 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427015 };
7016
[email protected]31a2bfe2010-02-09 08:03:397017 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7018 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077019 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427020
[email protected]49639fa2011-12-20 23:22:417021 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427022
[email protected]49639fa2011-12-20 23:22:417023 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427024 EXPECT_EQ(ERR_IO_PENDING, rv);
7025
7026 rv = callback.WaitForResult();
7027 EXPECT_EQ(OK, rv);
7028}
7029
[email protected]23e482282013-06-14 16:08:027030TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427031 HttpRequestInfo request;
7032 request.method = "GET";
7033 request.url = GURL("http://www.google.com/");
7034 request.load_flags = LOAD_BYPASS_CACHE;
7035
[email protected]3fe8d2f82013-10-17 08:56:077036 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277037 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277039
[email protected]1c773ea12009-04-28 19:58:427040 MockWrite data_writes[] = {
7041 MockWrite("GET / HTTP/1.1\r\n"
7042 "Host: www.google.com\r\n"
7043 "Connection: keep-alive\r\n"
7044 "Pragma: no-cache\r\n"
7045 "Cache-Control: no-cache\r\n\r\n"),
7046 };
7047
7048 // Lastly, the server responds with the actual content.
7049 MockRead data_reads[] = {
7050 MockRead("HTTP/1.0 200 OK\r\n"),
7051 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7052 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067053 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427054 };
7055
[email protected]31a2bfe2010-02-09 08:03:397056 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7057 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077058 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427059
[email protected]49639fa2011-12-20 23:22:417060 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427061
[email protected]49639fa2011-12-20 23:22:417062 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427063 EXPECT_EQ(ERR_IO_PENDING, rv);
7064
7065 rv = callback.WaitForResult();
7066 EXPECT_EQ(OK, rv);
7067}
7068
[email protected]23e482282013-06-14 16:08:027069TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427070 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427071 HttpRequestInfo request;
7072 request.method = "GET";
7073 request.url = GURL("http://www.google.com/");
7074 request.load_flags = LOAD_VALIDATE_CACHE;
7075
[email protected]3fe8d2f82013-10-17 08:56:077076 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277077 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077078 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277079
[email protected]1c773ea12009-04-28 19:58:427080 MockWrite data_writes[] = {
7081 MockWrite("GET / HTTP/1.1\r\n"
7082 "Host: www.google.com\r\n"
7083 "Connection: keep-alive\r\n"
7084 "Cache-Control: max-age=0\r\n\r\n"),
7085 };
7086
7087 // Lastly, the server responds with the actual content.
7088 MockRead data_reads[] = {
7089 MockRead("HTTP/1.0 200 OK\r\n"),
7090 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7091 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067092 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427093 };
7094
[email protected]31a2bfe2010-02-09 08:03:397095 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7096 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077097 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427098
[email protected]49639fa2011-12-20 23:22:417099 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427100
[email protected]49639fa2011-12-20 23:22:417101 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427102 EXPECT_EQ(ERR_IO_PENDING, rv);
7103
7104 rv = callback.WaitForResult();
7105 EXPECT_EQ(OK, rv);
7106}
7107
[email protected]23e482282013-06-14 16:08:027108TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427109 HttpRequestInfo request;
7110 request.method = "GET";
7111 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437112 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427113
[email protected]3fe8d2f82013-10-17 08:56:077114 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277115 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277117
[email protected]1c773ea12009-04-28 19:58:427118 MockWrite data_writes[] = {
7119 MockWrite("GET / HTTP/1.1\r\n"
7120 "Host: www.google.com\r\n"
7121 "Connection: keep-alive\r\n"
7122 "FooHeader: Bar\r\n\r\n"),
7123 };
7124
7125 // Lastly, the server responds with the actual content.
7126 MockRead data_reads[] = {
7127 MockRead("HTTP/1.0 200 OK\r\n"),
7128 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7129 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067130 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427131 };
7132
[email protected]31a2bfe2010-02-09 08:03:397133 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7134 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077135 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427136
[email protected]49639fa2011-12-20 23:22:417137 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427138
[email protected]49639fa2011-12-20 23:22:417139 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427140 EXPECT_EQ(ERR_IO_PENDING, rv);
7141
7142 rv = callback.WaitForResult();
7143 EXPECT_EQ(OK, rv);
7144}
7145
[email protected]23e482282013-06-14 16:08:027146TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477147 HttpRequestInfo request;
7148 request.method = "GET";
7149 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437150 request.extra_headers.SetHeader("referer", "www.foo.com");
7151 request.extra_headers.SetHeader("hEllo", "Kitty");
7152 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477153
[email protected]3fe8d2f82013-10-17 08:56:077154 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277155 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077156 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277157
[email protected]270c6412010-03-29 22:02:477158 MockWrite data_writes[] = {
7159 MockWrite("GET / HTTP/1.1\r\n"
7160 "Host: www.google.com\r\n"
7161 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:167162 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:477163 "hEllo: Kitty\r\n"
7164 "FoO: bar\r\n\r\n"),
7165 };
7166
7167 // Lastly, the server responds with the actual content.
7168 MockRead data_reads[] = {
7169 MockRead("HTTP/1.0 200 OK\r\n"),
7170 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7171 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067172 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477173 };
7174
7175 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7176 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077177 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477178
[email protected]49639fa2011-12-20 23:22:417179 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477180
[email protected]49639fa2011-12-20 23:22:417181 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477182 EXPECT_EQ(ERR_IO_PENDING, rv);
7183
7184 rv = callback.WaitForResult();
7185 EXPECT_EQ(OK, rv);
7186}
7187
[email protected]23e482282013-06-14 16:08:027188TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277189 HttpRequestInfo request;
7190 request.method = "GET";
7191 request.url = GURL("http://www.google.com/");
7192 request.load_flags = 0;
7193
[email protected]bb88e1d32013-05-03 23:11:077194 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207195 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7196 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077197 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027198
[email protected]3fe8d2f82013-10-17 08:56:077199 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027200 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077201 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027202
[email protected]3cd17242009-06-23 02:59:027203 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7204 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7205
7206 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067207 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027208 MockWrite("GET / HTTP/1.1\r\n"
7209 "Host: www.google.com\r\n"
7210 "Connection: keep-alive\r\n\r\n")
7211 };
7212
7213 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067214 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027215 MockRead("HTTP/1.0 200 OK\r\n"),
7216 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7217 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067218 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027219 };
7220
[email protected]31a2bfe2010-02-09 08:03:397221 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7222 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077223 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027224
[email protected]49639fa2011-12-20 23:22:417225 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027226
[email protected]49639fa2011-12-20 23:22:417227 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027228 EXPECT_EQ(ERR_IO_PENDING, rv);
7229
7230 rv = callback.WaitForResult();
7231 EXPECT_EQ(OK, rv);
7232
7233 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507234 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027235
[email protected]029c83b62013-01-24 05:28:207236 LoadTimingInfo load_timing_info;
7237 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7238 TestLoadTimingNotReusedWithPac(load_timing_info,
7239 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7240
[email protected]3cd17242009-06-23 02:59:027241 std::string response_text;
7242 rv = ReadTransaction(trans.get(), &response_text);
7243 EXPECT_EQ(OK, rv);
7244 EXPECT_EQ("Payload", response_text);
7245}
7246
[email protected]23e482282013-06-14 16:08:027247TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277248 HttpRequestInfo request;
7249 request.method = "GET";
7250 request.url = GURL("https://www.google.com/");
7251 request.load_flags = 0;
7252
[email protected]bb88e1d32013-05-03 23:11:077253 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207254 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7255 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077256 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027257
[email protected]3fe8d2f82013-10-17 08:56:077258 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027259 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027261
[email protected]3cd17242009-06-23 02:59:027262 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7263 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7264
7265 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067266 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:357267 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027268 MockWrite("GET / HTTP/1.1\r\n"
7269 "Host: www.google.com\r\n"
7270 "Connection: keep-alive\r\n\r\n")
7271 };
7272
7273 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017274 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7275 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357276 MockRead("HTTP/1.0 200 OK\r\n"),
7277 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7278 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067279 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357280 };
7281
[email protected]31a2bfe2010-02-09 08:03:397282 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7283 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077284 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357285
[email protected]8ddf8322012-02-23 18:08:067286 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077287 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357288
[email protected]49639fa2011-12-20 23:22:417289 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357290
[email protected]49639fa2011-12-20 23:22:417291 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357292 EXPECT_EQ(ERR_IO_PENDING, rv);
7293
7294 rv = callback.WaitForResult();
7295 EXPECT_EQ(OK, rv);
7296
[email protected]029c83b62013-01-24 05:28:207297 LoadTimingInfo load_timing_info;
7298 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7299 TestLoadTimingNotReusedWithPac(load_timing_info,
7300 CONNECT_TIMING_HAS_SSL_TIMES);
7301
[email protected]e0c27be2009-07-15 13:09:357302 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507303 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357304
7305 std::string response_text;
7306 rv = ReadTransaction(trans.get(), &response_text);
7307 EXPECT_EQ(OK, rv);
7308 EXPECT_EQ("Payload", response_text);
7309}
7310
[email protected]23e482282013-06-14 16:08:027311TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207312 HttpRequestInfo request;
7313 request.method = "GET";
7314 request.url = GURL("http://www.google.com/");
7315 request.load_flags = 0;
7316
[email protected]bb88e1d32013-05-03 23:11:077317 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207318 ProxyService::CreateFixed("socks4://myproxy:1080"));
7319 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077320 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207321
[email protected]3fe8d2f82013-10-17 08:56:077322 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207323 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077324 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]029c83b62013-01-24 05:28:207325
7326 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7327 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7328
7329 MockWrite data_writes[] = {
7330 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7331 MockWrite("GET / HTTP/1.1\r\n"
7332 "Host: www.google.com\r\n"
7333 "Connection: keep-alive\r\n\r\n")
7334 };
7335
7336 MockRead data_reads[] = {
7337 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7338 MockRead("HTTP/1.0 200 OK\r\n"),
7339 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7340 MockRead("Payload"),
7341 MockRead(SYNCHRONOUS, OK)
7342 };
7343
7344 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7345 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077346 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207347
7348 TestCompletionCallback callback;
7349
7350 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7351 EXPECT_EQ(ERR_IO_PENDING, rv);
7352
7353 rv = callback.WaitForResult();
7354 EXPECT_EQ(OK, rv);
7355
7356 const HttpResponseInfo* response = trans->GetResponseInfo();
7357 ASSERT_TRUE(response != NULL);
7358
7359 LoadTimingInfo load_timing_info;
7360 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7361 TestLoadTimingNotReused(load_timing_info,
7362 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7363
7364 std::string response_text;
7365 rv = ReadTransaction(trans.get(), &response_text);
7366 EXPECT_EQ(OK, rv);
7367 EXPECT_EQ("Payload", response_text);
7368}
7369
[email protected]23e482282013-06-14 16:08:027370TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277371 HttpRequestInfo request;
7372 request.method = "GET";
7373 request.url = GURL("http://www.google.com/");
7374 request.load_flags = 0;
7375
[email protected]bb88e1d32013-05-03 23:11:077376 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207377 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7378 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077379 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357380
[email protected]3fe8d2f82013-10-17 08:56:077381 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357382 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357384
[email protected]e0c27be2009-07-15 13:09:357385 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7386 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377387 const char kSOCKS5OkRequest[] = {
7388 0x05, // Version
7389 0x01, // Command (CONNECT)
7390 0x00, // Reserved.
7391 0x03, // Address type (DOMAINNAME).
7392 0x0E, // Length of domain (14)
7393 // Domain string:
7394 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7395 0x00, 0x50, // 16-bit port (80)
7396 };
[email protected]e0c27be2009-07-15 13:09:357397 const char kSOCKS5OkResponse[] =
7398 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7399
7400 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067401 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7402 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357403 MockWrite("GET / HTTP/1.1\r\n"
7404 "Host: www.google.com\r\n"
7405 "Connection: keep-alive\r\n\r\n")
7406 };
7407
7408 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017409 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7410 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357411 MockRead("HTTP/1.0 200 OK\r\n"),
7412 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7413 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067414 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357415 };
7416
[email protected]31a2bfe2010-02-09 08:03:397417 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7418 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077419 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357420
[email protected]49639fa2011-12-20 23:22:417421 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357422
[email protected]49639fa2011-12-20 23:22:417423 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357424 EXPECT_EQ(ERR_IO_PENDING, rv);
7425
7426 rv = callback.WaitForResult();
7427 EXPECT_EQ(OK, rv);
7428
7429 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507430 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357431
[email protected]029c83b62013-01-24 05:28:207432 LoadTimingInfo load_timing_info;
7433 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7434 TestLoadTimingNotReusedWithPac(load_timing_info,
7435 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7436
[email protected]e0c27be2009-07-15 13:09:357437 std::string response_text;
7438 rv = ReadTransaction(trans.get(), &response_text);
7439 EXPECT_EQ(OK, rv);
7440 EXPECT_EQ("Payload", response_text);
7441}
7442
[email protected]23e482282013-06-14 16:08:027443TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277444 HttpRequestInfo request;
7445 request.method = "GET";
7446 request.url = GURL("https://www.google.com/");
7447 request.load_flags = 0;
7448
[email protected]bb88e1d32013-05-03 23:11:077449 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207450 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7451 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077452 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357453
[email protected]3fe8d2f82013-10-17 08:56:077454 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357455 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077456 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357457
[email protected]e0c27be2009-07-15 13:09:357458 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7459 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377460 const unsigned char kSOCKS5OkRequest[] = {
7461 0x05, // Version
7462 0x01, // Command (CONNECT)
7463 0x00, // Reserved.
7464 0x03, // Address type (DOMAINNAME).
7465 0x0E, // Length of domain (14)
7466 // Domain string:
7467 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7468 0x01, 0xBB, // 16-bit port (443)
7469 };
7470
[email protected]e0c27be2009-07-15 13:09:357471 const char kSOCKS5OkResponse[] =
7472 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7473
7474 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067475 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7476 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357477 arraysize(kSOCKS5OkRequest)),
7478 MockWrite("GET / HTTP/1.1\r\n"
7479 "Host: www.google.com\r\n"
7480 "Connection: keep-alive\r\n\r\n")
7481 };
7482
7483 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017484 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7485 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027486 MockRead("HTTP/1.0 200 OK\r\n"),
7487 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7488 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067489 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027490 };
7491
[email protected]31a2bfe2010-02-09 08:03:397492 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7493 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077494 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027495
[email protected]8ddf8322012-02-23 18:08:067496 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077497 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027498
[email protected]49639fa2011-12-20 23:22:417499 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027500
[email protected]49639fa2011-12-20 23:22:417501 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027502 EXPECT_EQ(ERR_IO_PENDING, rv);
7503
7504 rv = callback.WaitForResult();
7505 EXPECT_EQ(OK, rv);
7506
7507 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507508 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027509
[email protected]029c83b62013-01-24 05:28:207510 LoadTimingInfo load_timing_info;
7511 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7512 TestLoadTimingNotReusedWithPac(load_timing_info,
7513 CONNECT_TIMING_HAS_SSL_TIMES);
7514
[email protected]3cd17242009-06-23 02:59:027515 std::string response_text;
7516 rv = ReadTransaction(trans.get(), &response_text);
7517 EXPECT_EQ(OK, rv);
7518 EXPECT_EQ("Payload", response_text);
7519}
7520
[email protected]448d4ca52012-03-04 04:12:237521namespace {
7522
[email protected]04e5be32009-06-26 20:00:317523// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067524
7525struct GroupNameTest {
7526 std::string proxy_server;
7527 std::string url;
7528 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187529 bool ssl;
[email protected]2d731a32010-04-29 01:04:067530};
7531
7532scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437533 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077534 SpdySessionDependencies* session_deps_) {
7535 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067536
[email protected]30d4c022013-07-18 22:58:167537 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537538 session->http_server_properties();
7539 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067540 HostPortPair("host.with.alternate", 80), 443,
[email protected]287d9412014-07-08 23:01:007541 AlternateProtocolFromNextProto(next_proto), 1);
[email protected]2d731a32010-04-29 01:04:067542
7543 return session;
7544}
7545
7546int GroupNameTransactionHelper(
7547 const std::string& url,
7548 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067549 HttpRequestInfo request;
7550 request.method = "GET";
7551 request.url = GURL(url);
7552 request.load_flags = 0;
7553
[email protected]262eec82013-03-19 21:01:367554 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277556
[email protected]49639fa2011-12-20 23:22:417557 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067558
7559 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417560 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067561}
7562
[email protected]448d4ca52012-03-04 04:12:237563} // namespace
7564
[email protected]23e482282013-06-14 16:08:027565TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067566 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317567 {
[email protected]2d731a32010-04-29 01:04:067568 "", // unused
[email protected]04e5be32009-06-26 20:00:317569 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547570 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187571 false,
[email protected]2ff8b312010-04-26 22:20:547572 },
7573 {
[email protected]2d731a32010-04-29 01:04:067574 "", // unused
[email protected]2ff8b312010-04-26 22:20:547575 "http://[2001:1418:13:1::25]/direct",
7576 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187577 false,
[email protected]04e5be32009-06-26 20:00:317578 },
[email protected]04e5be32009-06-26 20:00:317579
7580 // SSL Tests
7581 {
[email protected]2d731a32010-04-29 01:04:067582 "", // unused
[email protected]04e5be32009-06-26 20:00:317583 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027584 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187585 true,
[email protected]04e5be32009-06-26 20:00:317586 },
7587 {
[email protected]2d731a32010-04-29 01:04:067588 "", // unused
7589 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027590 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187591 true,
[email protected]04e5be32009-06-26 20:00:317592 },
7593 {
[email protected]2d731a32010-04-29 01:04:067594 "", // unused
[email protected]2ff8b312010-04-26 22:20:547595 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027596 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187597 true,
[email protected]2ff8b312010-04-26 22:20:547598 },
[email protected]2d731a32010-04-29 01:04:067599 };
[email protected]2ff8b312010-04-26 22:20:547600
[email protected]d7599122014-05-24 03:37:237601 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067602
7603 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077604 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027605 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067606 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437607 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067608
7609 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287610 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7611 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137612 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347613 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447614 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7615 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027616 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7617 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447618 peer.SetClientSocketPoolManager(
7619 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067620
7621 EXPECT_EQ(ERR_IO_PENDING,
7622 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187623 if (tests[i].ssl)
7624 EXPECT_EQ(tests[i].expected_group_name,
7625 ssl_conn_pool->last_group_name_received());
7626 else
7627 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287628 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067629 }
7630
[email protected]2d731a32010-04-29 01:04:067631}
7632
[email protected]23e482282013-06-14 16:08:027633TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067634 const GroupNameTest tests[] = {
7635 {
7636 "http_proxy",
7637 "http://www.google.com/http_proxy_normal",
7638 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187639 false,
[email protected]2d731a32010-04-29 01:04:067640 },
7641
7642 // SSL Tests
7643 {
7644 "http_proxy",
7645 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027646 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187647 true,
[email protected]2d731a32010-04-29 01:04:067648 },
[email protected]af3490e2010-10-16 21:02:297649
[email protected]9faeded92010-04-29 20:03:057650 {
7651 "http_proxy",
7652 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027653 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187654 true,
[email protected]9faeded92010-04-29 20:03:057655 },
[email protected]45499252013-01-23 17:12:567656
7657 {
7658 "http_proxy",
7659 "ftp://ftp.google.com/http_proxy_normal",
7660 "ftp/ftp.google.com:21",
7661 false,
7662 },
[email protected]2d731a32010-04-29 01:04:067663 };
7664
[email protected]d7599122014-05-24 03:37:237665 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067666
7667 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077668 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027669 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067670 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437671 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067672
7673 HttpNetworkSessionPeer peer(session);
7674
[email protected]e60e47a2010-07-14 03:37:187675 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137676 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347677 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137678 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347679 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027680
[email protected]831e4a32013-11-14 02:14:447681 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7682 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027683 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7684 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447685 peer.SetClientSocketPoolManager(
7686 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067687
7688 EXPECT_EQ(ERR_IO_PENDING,
7689 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187690 if (tests[i].ssl)
7691 EXPECT_EQ(tests[i].expected_group_name,
7692 ssl_conn_pool->last_group_name_received());
7693 else
7694 EXPECT_EQ(tests[i].expected_group_name,
7695 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067696 }
[email protected]2d731a32010-04-29 01:04:067697}
7698
[email protected]23e482282013-06-14 16:08:027699TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067700 const GroupNameTest tests[] = {
7701 {
7702 "socks4://socks_proxy:1080",
7703 "http://www.google.com/socks4_direct",
7704 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187705 false,
[email protected]2d731a32010-04-29 01:04:067706 },
7707 {
7708 "socks5://socks_proxy:1080",
7709 "http://www.google.com/socks5_direct",
7710 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187711 false,
[email protected]2d731a32010-04-29 01:04:067712 },
7713
7714 // SSL Tests
7715 {
7716 "socks4://socks_proxy:1080",
7717 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027718 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187719 true,
[email protected]2d731a32010-04-29 01:04:067720 },
7721 {
7722 "socks5://socks_proxy:1080",
7723 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027724 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187725 true,
[email protected]2d731a32010-04-29 01:04:067726 },
[email protected]af3490e2010-10-16 21:02:297727
[email protected]9faeded92010-04-29 20:03:057728 {
7729 "socks4://socks_proxy:1080",
7730 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027731 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187732 true,
[email protected]9faeded92010-04-29 20:03:057733 },
[email protected]04e5be32009-06-26 20:00:317734 };
7735
[email protected]d7599122014-05-24 03:37:237736 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:547737
[email protected]04e5be32009-06-26 20:00:317738 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077739 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027740 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067741 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437742 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027743
[email protected]2d731a32010-04-29 01:04:067744 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317745
[email protected]e60e47a2010-07-14 03:37:187746 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137747 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347748 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137749 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347750 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027751
[email protected]831e4a32013-11-14 02:14:447752 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7753 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027754 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7755 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447756 peer.SetClientSocketPoolManager(
7757 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]04e5be32009-06-26 20:00:317758
[email protected]262eec82013-03-19 21:01:367759 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317761
[email protected]2d731a32010-04-29 01:04:067762 EXPECT_EQ(ERR_IO_PENDING,
7763 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187764 if (tests[i].ssl)
7765 EXPECT_EQ(tests[i].expected_group_name,
7766 ssl_conn_pool->last_group_name_received());
7767 else
7768 EXPECT_EQ(tests[i].expected_group_name,
7769 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317770 }
7771}
7772
[email protected]23e482282013-06-14 16:08:027773TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277774 HttpRequestInfo request;
7775 request.method = "GET";
7776 request.url = GURL("http://www.google.com/");
7777
[email protected]bb88e1d32013-05-03 23:11:077778 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007779 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327780
[email protected]69719062010-01-05 20:09:217781 // This simulates failure resolving all hostnames; that means we will fail
7782 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077783 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327784
[email protected]3fe8d2f82013-10-17 08:56:077785 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257786 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077787 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]9172a982009-06-06 00:30:257788
[email protected]49639fa2011-12-20 23:22:417789 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257790
[email protected]49639fa2011-12-20 23:22:417791 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257792 EXPECT_EQ(ERR_IO_PENDING, rv);
7793
[email protected]9172a982009-06-06 00:30:257794 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017795 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257796}
7797
[email protected]685af592010-05-11 19:31:247798// Base test to make sure that when the load flags for a request specify to
7799// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027800void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077801 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277802 // Issue a request, asking to bypass the cache(s).
7803 HttpRequestInfo request;
7804 request.method = "GET";
7805 request.load_flags = load_flags;
7806 request.url = GURL("http://www.google.com/");
7807
[email protected]a2c2fb92009-07-18 07:31:047808 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077809 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327810
[email protected]3fe8d2f82013-10-17 08:56:077811 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7812 scoped_ptr<HttpTransaction> trans(
7813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3b9cca42009-06-16 01:08:287814
[email protected]6e78dfb2011-07-28 21:34:477815 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287816 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297817 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077818 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107819 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7820 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417821 &addrlist,
7822 callback.callback(),
7823 NULL,
7824 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477825 EXPECT_EQ(ERR_IO_PENDING, rv);
7826 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287827 EXPECT_EQ(OK, rv);
7828
7829 // Verify that it was added to host cache, by doing a subsequent async lookup
7830 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077831 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107832 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7833 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417834 &addrlist,
7835 callback.callback(),
7836 NULL,
7837 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327838 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287839
7840 // Inject a failure the next time that "www.google.com" is resolved. This way
7841 // we can tell if the next lookup hit the cache, or the "network".
7842 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077843 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287844
7845 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7846 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067847 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397848 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077849 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287850
[email protected]3b9cca42009-06-16 01:08:287851 // Run the request.
[email protected]49639fa2011-12-20 23:22:417852 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287853 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417854 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287855
7856 // If we bypassed the cache, we would have gotten a failure while resolving
7857 // "www.google.com".
7858 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7859}
7860
[email protected]685af592010-05-11 19:31:247861// There are multiple load flags that should trigger the host cache bypass.
7862// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027863TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247864 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7865}
7866
[email protected]23e482282013-06-14 16:08:027867TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247868 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7869}
7870
[email protected]23e482282013-06-14 16:08:027871TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247872 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7873}
7874
[email protected]0877e3d2009-10-17 22:29:577875// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027876TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577877 HttpRequestInfo request;
7878 request.method = "GET";
7879 request.url = GURL("http://www.foo.com/");
7880 request.load_flags = 0;
7881
7882 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067883 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577884 };
[email protected]31a2bfe2010-02-09 08:03:397885 StaticSocketDataProvider data(NULL, 0,
7886 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077887 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077888 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577889
[email protected]49639fa2011-12-20 23:22:417890 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577891
7892 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577894
[email protected]49639fa2011-12-20 23:22:417895 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577896 EXPECT_EQ(ERR_IO_PENDING, rv);
7897
7898 rv = callback.WaitForResult();
7899 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7900}
7901
7902// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027903TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577904 HttpRequestInfo request;
7905 request.method = "GET";
7906 request.url = GURL("http://www.foo.com/");
7907 request.load_flags = 0;
7908
7909 MockRead data_reads[] = {
7910 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067911 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577912 };
7913
[email protected]31a2bfe2010-02-09 08:03:397914 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077915 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577917
[email protected]49639fa2011-12-20 23:22:417918 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577919
7920 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077921 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577922
[email protected]49639fa2011-12-20 23:22:417923 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577924 EXPECT_EQ(ERR_IO_PENDING, rv);
7925
7926 rv = callback.WaitForResult();
7927 EXPECT_EQ(OK, rv);
7928
7929 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507930 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577931
[email protected]90499482013-06-01 00:39:507932 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577933 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7934
7935 std::string response_data;
7936 rv = ReadTransaction(trans.get(), &response_data);
7937 EXPECT_EQ(OK, rv);
7938 EXPECT_EQ("", response_data);
7939}
7940
7941// Make sure that a dropped connection while draining the body for auth
7942// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027943TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577944 HttpRequestInfo request;
7945 request.method = "GET";
7946 request.url = GURL("http://www.google.com/");
7947 request.load_flags = 0;
7948
7949 MockWrite data_writes1[] = {
7950 MockWrite("GET / HTTP/1.1\r\n"
7951 "Host: www.google.com\r\n"
7952 "Connection: keep-alive\r\n\r\n"),
7953 };
7954
7955 MockRead data_reads1[] = {
7956 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7957 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7959 MockRead("Content-Length: 14\r\n\r\n"),
7960 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067961 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577962 };
7963
[email protected]31a2bfe2010-02-09 08:03:397964 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7965 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077966 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577967
7968 // After calling trans->RestartWithAuth(), this is the request we should
7969 // be issuing -- the final header line contains the credentials.
7970 MockWrite data_writes2[] = {
7971 MockWrite("GET / HTTP/1.1\r\n"
7972 "Host: www.google.com\r\n"
7973 "Connection: keep-alive\r\n"
7974 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7975 };
7976
7977 // Lastly, the server responds with the actual content.
7978 MockRead data_reads2[] = {
7979 MockRead("HTTP/1.1 200 OK\r\n"),
7980 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7981 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067982 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577983 };
7984
[email protected]31a2bfe2010-02-09 08:03:397985 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7986 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077987 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077988 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577989
[email protected]49639fa2011-12-20 23:22:417990 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577991
[email protected]262eec82013-03-19 21:01:367992 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507994
[email protected]49639fa2011-12-20 23:22:417995 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577996 EXPECT_EQ(ERR_IO_PENDING, rv);
7997
7998 rv = callback1.WaitForResult();
7999 EXPECT_EQ(OK, rv);
8000
8001 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508002 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048003 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578004
[email protected]49639fa2011-12-20 23:22:418005 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578006
[email protected]49639fa2011-12-20 23:22:418007 rv = trans->RestartWithAuth(
8008 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578009 EXPECT_EQ(ERR_IO_PENDING, rv);
8010
8011 rv = callback2.WaitForResult();
8012 EXPECT_EQ(OK, rv);
8013
8014 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508015 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578016 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8017 EXPECT_EQ(100, response->headers->GetContentLength());
8018}
8019
8020// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028021TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078022 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578023
8024 HttpRequestInfo request;
8025 request.method = "GET";
8026 request.url = GURL("https://www.google.com/");
8027 request.load_flags = 0;
8028
8029 MockRead proxy_reads[] = {
8030 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068031 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578032 };
8033
[email protected]31a2bfe2010-02-09 08:03:398034 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068035 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578036
[email protected]bb88e1d32013-05-03 23:11:078037 session_deps_.socket_factory->AddSocketDataProvider(&data);
8038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578039
[email protected]49639fa2011-12-20 23:22:418040 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578041
[email protected]bb88e1d32013-05-03 23:11:078042 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578043
[email protected]3fe8d2f82013-10-17 08:56:078044 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578045 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078046 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:578047
[email protected]49639fa2011-12-20 23:22:418048 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578049 EXPECT_EQ(ERR_IO_PENDING, rv);
8050
8051 rv = callback.WaitForResult();
8052 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8053}
8054
[email protected]23e482282013-06-14 16:08:028055TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468056 HttpRequestInfo request;
8057 request.method = "GET";
8058 request.url = GURL("http://www.google.com/");
8059 request.load_flags = 0;
8060
[email protected]3fe8d2f82013-10-17 08:56:078061 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278062 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078063 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:278064
[email protected]e22e1362009-11-23 21:31:128065 MockRead data_reads[] = {
8066 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068067 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128068 };
[email protected]9492e4a2010-02-24 00:58:468069
8070 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078071 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468072
[email protected]49639fa2011-12-20 23:22:418073 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468074
[email protected]49639fa2011-12-20 23:22:418075 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468076 EXPECT_EQ(ERR_IO_PENDING, rv);
8077
8078 EXPECT_EQ(OK, callback.WaitForResult());
8079
8080 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508081 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468082
[email protected]90499482013-06-01 00:39:508083 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468084 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8085
8086 std::string response_data;
8087 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238088 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128089}
8090
[email protected]23e482282013-06-14 16:08:028091TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158092 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528093 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338094 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218095 UploadFileElementReader::ScopedOverridingContentLengthForTests
8096 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338097
[email protected]b2d26cfd2012-12-11 10:36:068098 ScopedVector<UploadElementReader> element_readers;
8099 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368100 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8101 temp_file_path,
8102 0,
8103 kuint64max,
8104 base::Time()));
[email protected]96c77a72013-09-24 09:49:208105 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278106
8107 HttpRequestInfo request;
8108 request.method = "POST";
8109 request.url = GURL("http://www.google.com/upload");
8110 request.upload_data_stream = &upload_data_stream;
8111 request.load_flags = 0;
8112
[email protected]3fe8d2f82013-10-17 08:56:078113 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278114 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078115 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]95d88ffe2010-02-04 21:25:338116
8117 MockRead data_reads[] = {
8118 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8119 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068120 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338121 };
[email protected]31a2bfe2010-02-09 08:03:398122 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078123 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338124
[email protected]49639fa2011-12-20 23:22:418125 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338126
[email protected]49639fa2011-12-20 23:22:418127 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338128 EXPECT_EQ(ERR_IO_PENDING, rv);
8129
8130 rv = callback.WaitForResult();
8131 EXPECT_EQ(OK, rv);
8132
8133 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508134 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338135
[email protected]90499482013-06-01 00:39:508136 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338137 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8138
8139 std::string response_data;
8140 rv = ReadTransaction(trans.get(), &response_data);
8141 EXPECT_EQ(OK, rv);
8142 EXPECT_EQ("hello world", response_data);
8143
[email protected]dd3aa792013-07-16 19:10:238144 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338145}
8146
[email protected]23e482282013-06-14 16:08:028147TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158148 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528149 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368150 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308151 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368152 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118153 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368154
[email protected]b2d26cfd2012-12-11 10:36:068155 ScopedVector<UploadElementReader> element_readers;
8156 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368157 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8158 temp_file,
8159 0,
8160 kuint64max,
8161 base::Time()));
[email protected]96c77a72013-09-24 09:49:208162 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278163
8164 HttpRequestInfo request;
8165 request.method = "POST";
8166 request.url = GURL("http://www.google.com/upload");
8167 request.upload_data_stream = &upload_data_stream;
8168 request.load_flags = 0;
8169
[email protected]999dd8c2013-11-12 06:45:548170 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078171 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278172 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078173 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]6624b4622010-03-29 19:58:368174
[email protected]999dd8c2013-11-12 06:45:548175 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078176 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368177
[email protected]49639fa2011-12-20 23:22:418178 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368179
[email protected]49639fa2011-12-20 23:22:418180 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368181 EXPECT_EQ(ERR_IO_PENDING, rv);
8182
8183 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548184 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368185
8186 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548187 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368188
[email protected]dd3aa792013-07-16 19:10:238189 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368190}
8191
[email protected]02cad5d2013-10-02 08:14:038192TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8193 class FakeUploadElementReader : public UploadElementReader {
8194 public:
8195 FakeUploadElementReader() {}
8196 virtual ~FakeUploadElementReader() {}
8197
8198 const CompletionCallback& callback() const { return callback_; }
8199
8200 // UploadElementReader overrides:
8201 virtual int Init(const CompletionCallback& callback) OVERRIDE {
8202 callback_ = callback;
8203 return ERR_IO_PENDING;
8204 }
8205 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
8206 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
8207 virtual int Read(IOBuffer* buf,
8208 int buf_length,
8209 const CompletionCallback& callback) OVERRIDE {
8210 return ERR_FAILED;
8211 }
8212
8213 private:
8214 CompletionCallback callback_;
8215 };
8216
8217 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8218 ScopedVector<UploadElementReader> element_readers;
8219 element_readers.push_back(fake_reader);
8220 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8221
8222 HttpRequestInfo request;
8223 request.method = "POST";
8224 request.url = GURL("http://www.google.com/upload");
8225 request.upload_data_stream = &upload_data_stream;
8226 request.load_flags = 0;
8227
[email protected]3fe8d2f82013-10-17 08:56:078228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038229 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078230 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]02cad5d2013-10-02 08:14:038231
8232 StaticSocketDataProvider data;
8233 session_deps_.socket_factory->AddSocketDataProvider(&data);
8234
8235 TestCompletionCallback callback;
8236 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8237 EXPECT_EQ(ERR_IO_PENDING, rv);
8238 base::MessageLoop::current()->RunUntilIdle();
8239
8240 // Transaction is pending on request body initialization.
8241 ASSERT_FALSE(fake_reader->callback().is_null());
8242
8243 // Return Init()'s result after the transaction gets destroyed.
8244 trans.reset();
8245 fake_reader->callback().Run(OK); // Should not crash.
8246}
8247
[email protected]aeefc9e82010-02-19 16:18:278248// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028249TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278250
8251 HttpRequestInfo request;
8252 request.method = "GET";
8253 request.url = GURL("http://www.google.com/");
8254 request.load_flags = 0;
8255
8256 // First transaction will request a resource and receive a Basic challenge
8257 // with realm="first_realm".
8258 MockWrite data_writes1[] = {
8259 MockWrite("GET / HTTP/1.1\r\n"
8260 "Host: www.google.com\r\n"
8261 "Connection: keep-alive\r\n"
8262 "\r\n"),
8263 };
8264 MockRead data_reads1[] = {
8265 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8266 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8267 "\r\n"),
8268 };
8269
8270 // After calling trans->RestartWithAuth(), provide an Authentication header
8271 // for first_realm. The server will reject and provide a challenge with
8272 // second_realm.
8273 MockWrite data_writes2[] = {
8274 MockWrite("GET / HTTP/1.1\r\n"
8275 "Host: www.google.com\r\n"
8276 "Connection: keep-alive\r\n"
8277 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8278 "\r\n"),
8279 };
8280 MockRead data_reads2[] = {
8281 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8282 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8283 "\r\n"),
8284 };
8285
8286 // This again fails, and goes back to first_realm. Make sure that the
8287 // entry is removed from cache.
8288 MockWrite data_writes3[] = {
8289 MockWrite("GET / HTTP/1.1\r\n"
8290 "Host: www.google.com\r\n"
8291 "Connection: keep-alive\r\n"
8292 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8293 "\r\n"),
8294 };
8295 MockRead data_reads3[] = {
8296 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8297 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8298 "\r\n"),
8299 };
8300
8301 // Try one last time (with the correct password) and get the resource.
8302 MockWrite data_writes4[] = {
8303 MockWrite("GET / HTTP/1.1\r\n"
8304 "Host: www.google.com\r\n"
8305 "Connection: keep-alive\r\n"
8306 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8307 "\r\n"),
8308 };
8309 MockRead data_reads4[] = {
8310 MockRead("HTTP/1.1 200 OK\r\n"
8311 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508312 "Content-Length: 5\r\n"
8313 "\r\n"
8314 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278315 };
8316
8317 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8318 data_writes1, arraysize(data_writes1));
8319 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8320 data_writes2, arraysize(data_writes2));
8321 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8322 data_writes3, arraysize(data_writes3));
8323 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8324 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8326 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8327 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8328 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278329
[email protected]49639fa2011-12-20 23:22:418330 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278331
[email protected]3fe8d2f82013-10-17 08:56:078332 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508333 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0b0bf032010-09-21 18:08:508335
[email protected]aeefc9e82010-02-19 16:18:278336 // Issue the first request with Authorize headers. There should be a
8337 // password prompt for first_realm waiting to be filled in after the
8338 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418339 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278340 EXPECT_EQ(ERR_IO_PENDING, rv);
8341 rv = callback1.WaitForResult();
8342 EXPECT_EQ(OK, rv);
8343 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508344 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048345 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8346 ASSERT_FALSE(challenge == NULL);
8347 EXPECT_FALSE(challenge->is_proxy);
8348 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8349 EXPECT_EQ("first_realm", challenge->realm);
8350 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278351
8352 // Issue the second request with an incorrect password. There should be a
8353 // password prompt for second_realm waiting to be filled in after the
8354 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418355 TestCompletionCallback callback2;
8356 rv = trans->RestartWithAuth(
8357 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278358 EXPECT_EQ(ERR_IO_PENDING, rv);
8359 rv = callback2.WaitForResult();
8360 EXPECT_EQ(OK, rv);
8361 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508362 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048363 challenge = response->auth_challenge.get();
8364 ASSERT_FALSE(challenge == NULL);
8365 EXPECT_FALSE(challenge->is_proxy);
8366 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8367 EXPECT_EQ("second_realm", challenge->realm);
8368 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278369
8370 // Issue the third request with another incorrect password. There should be
8371 // a password prompt for first_realm waiting to be filled in. If the password
8372 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8373 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418374 TestCompletionCallback callback3;
8375 rv = trans->RestartWithAuth(
8376 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278377 EXPECT_EQ(ERR_IO_PENDING, rv);
8378 rv = callback3.WaitForResult();
8379 EXPECT_EQ(OK, rv);
8380 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508381 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048382 challenge = response->auth_challenge.get();
8383 ASSERT_FALSE(challenge == NULL);
8384 EXPECT_FALSE(challenge->is_proxy);
8385 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8386 EXPECT_EQ("first_realm", challenge->realm);
8387 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278388
8389 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418390 TestCompletionCallback callback4;
8391 rv = trans->RestartWithAuth(
8392 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278393 EXPECT_EQ(ERR_IO_PENDING, rv);
8394 rv = callback4.WaitForResult();
8395 EXPECT_EQ(OK, rv);
8396 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508397 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278398 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8399}
8400
[email protected]23e482282013-06-14 16:08:028401TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238402 session_deps_.next_protos = SpdyNextProtos();
8403 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428404
[email protected]8a0fc822013-06-27 20:52:438405 std::string alternate_protocol_http_header =
8406 GetAlternateProtocolHttpHeader();
8407
[email protected]564b4912010-03-09 16:30:428408 MockRead data_reads[] = {
8409 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438410 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428411 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068412 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428413 };
8414
8415 HttpRequestInfo request;
8416 request.method = "GET";
8417 request.url = GURL("http://www.google.com/");
8418 request.load_flags = 0;
8419
8420 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8421
[email protected]bb88e1d32013-05-03 23:11:078422 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428423
[email protected]49639fa2011-12-20 23:22:418424 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428425
[email protected]bb88e1d32013-05-03 23:11:078426 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368427 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508428 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428429
[email protected]49639fa2011-12-20 23:22:418430 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428431 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538432
[email protected]2fbaecf22010-07-22 22:20:358433 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558434 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538435 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428436 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538437 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428438
8439 EXPECT_EQ(OK, callback.WaitForResult());
8440
8441 const HttpResponseInfo* response = trans->GetResponseInfo();
8442 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508443 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428444 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538445 EXPECT_FALSE(response->was_fetched_via_spdy);
8446 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428447
8448 std::string response_data;
8449 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8450 EXPECT_EQ("hello world", response_data);
8451
[email protected]17291a022011-10-10 07:32:538452 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]287d9412014-07-08 23:01:008453 const AlternateProtocolInfo alternate =
[email protected]17291a022011-10-10 07:32:538454 http_server_properties.GetAlternateProtocol(http_host_port_pair);
[email protected]287d9412014-07-08 23:01:008455 AlternateProtocolInfo expected_alternate(
8456 443, AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]564b4912010-03-09 16:30:428457 EXPECT_TRUE(expected_alternate.Equals(alternate));
8458}
8459
[email protected]23e482282013-06-14 16:08:028460TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238461 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238462 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428463
8464 HttpRequestInfo request;
8465 request.method = "GET";
8466 request.url = GURL("http://www.google.com/");
8467 request.load_flags = 0;
8468
[email protected]d973e99a2012-02-17 21:02:368469 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428470 StaticSocketDataProvider first_data;
8471 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078472 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428473
8474 MockRead data_reads[] = {
8475 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8476 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068477 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428478 };
8479 StaticSocketDataProvider second_data(
8480 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078481 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428482
[email protected]bb88e1d32013-05-03 23:11:078483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428484
[email protected]30d4c022013-07-18 22:58:168485 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538486 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118487 // Port must be < 1024, or the header will be ignored (since initial port was
8488 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538489 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118490 HostPortPair::FromURL(request.url),
8491 666 /* port is ignored by MockConnect anyway */,
[email protected]287d9412014-07-08 23:01:008492 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]564b4912010-03-09 16:30:428493
[email protected]262eec82013-03-19 21:01:368494 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508495 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418496 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428497
[email protected]49639fa2011-12-20 23:22:418498 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428499 EXPECT_EQ(ERR_IO_PENDING, rv);
8500 EXPECT_EQ(OK, callback.WaitForResult());
8501
8502 const HttpResponseInfo* response = trans->GetResponseInfo();
8503 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508504 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428505 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8506
8507 std::string response_data;
8508 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8509 EXPECT_EQ("hello world", response_data);
8510
[email protected]17291a022011-10-10 07:32:538511 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118512 HostPortPair::FromURL(request.url)));
[email protected]287d9412014-07-08 23:01:008513 const AlternateProtocolInfo alternate =
[email protected]17291a022011-10-10 07:32:538514 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118515 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538516 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428517}
8518
[email protected]23e482282013-06-14 16:08:028519TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238520 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118521 // Ensure that we're not allowed to redirect traffic via an alternate
8522 // protocol to an unrestricted (port >= 1024) when the original traffic was
8523 // on a restricted port (port < 1024). Ensure that we can redirect in all
8524 // other cases.
[email protected]d7599122014-05-24 03:37:238525 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118526
8527 HttpRequestInfo restricted_port_request;
8528 restricted_port_request.method = "GET";
8529 restricted_port_request.url = GURL("http://www.google.com:1023/");
8530 restricted_port_request.load_flags = 0;
8531
[email protected]d973e99a2012-02-17 21:02:368532 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118533 StaticSocketDataProvider first_data;
8534 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078535 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118536
8537 MockRead data_reads[] = {
8538 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8539 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068540 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118541 };
8542 StaticSocketDataProvider second_data(
8543 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078544 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118545
[email protected]bb88e1d32013-05-03 23:11:078546 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118547
[email protected]30d4c022013-07-18 22:58:168548 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538549 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118550 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538551 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118552 HostPortPair::FromURL(restricted_port_request.url),
8553 kUnrestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008554 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118555
[email protected]262eec82013-03-19 21:01:368556 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508557 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418558 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118559
[email protected]49639fa2011-12-20 23:22:418560 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368561 &restricted_port_request,
8562 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118563 EXPECT_EQ(ERR_IO_PENDING, rv);
8564 // Invalid change to unrestricted port should fail.
8565 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198566}
[email protected]3912662a32011-10-04 00:51:118567
[email protected]23e482282013-06-14 16:08:028568TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198569 AlternateProtocolPortRestrictedPermitted) {
8570 // Ensure that we're allowed to redirect traffic via an alternate
8571 // protocol to an unrestricted (port >= 1024) when the original traffic was
8572 // on a restricted port (port < 1024) if we set
8573 // enable_user_alternate_protocol_ports.
8574
[email protected]d7599122014-05-24 03:37:238575 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078576 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198577
8578 HttpRequestInfo restricted_port_request;
8579 restricted_port_request.method = "GET";
8580 restricted_port_request.url = GURL("http://www.google.com:1023/");
8581 restricted_port_request.load_flags = 0;
8582
8583 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8584 StaticSocketDataProvider first_data;
8585 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078586 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198587
8588 MockRead data_reads[] = {
8589 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8590 MockRead("hello world"),
8591 MockRead(ASYNC, OK),
8592 };
8593 StaticSocketDataProvider second_data(
8594 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078595 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198596
[email protected]bb88e1d32013-05-03 23:11:078597 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198598
[email protected]30d4c022013-07-18 22:58:168599 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198600 session->http_server_properties();
8601 const int kUnrestrictedAlternatePort = 1024;
8602 http_server_properties->SetAlternateProtocol(
8603 HostPortPair::FromURL(restricted_port_request.url),
8604 kUnrestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008605 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]c54c6962013-02-01 04:53:198606
[email protected]262eec82013-03-19 21:01:368607 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198609 TestCompletionCallback callback;
8610
8611 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368612 &restricted_port_request,
8613 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198614 // Change to unrestricted port should succeed.
8615 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118616}
8617
[email protected]23e482282013-06-14 16:08:028618TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238619 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118620 // Ensure that we're not allowed to redirect traffic via an alternate
8621 // protocol to an unrestricted (port >= 1024) when the original traffic was
8622 // on a restricted port (port < 1024). Ensure that we can redirect in all
8623 // other cases.
[email protected]d7599122014-05-24 03:37:238624 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118625
8626 HttpRequestInfo restricted_port_request;
8627 restricted_port_request.method = "GET";
8628 restricted_port_request.url = GURL("http://www.google.com:1023/");
8629 restricted_port_request.load_flags = 0;
8630
[email protected]d973e99a2012-02-17 21:02:368631 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118632 StaticSocketDataProvider first_data;
8633 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078634 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118635
8636 MockRead data_reads[] = {
8637 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8638 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068639 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118640 };
8641 StaticSocketDataProvider second_data(
8642 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078643 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118644
[email protected]bb88e1d32013-05-03 23:11:078645 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118646
[email protected]30d4c022013-07-18 22:58:168647 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538648 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118649 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538650 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118651 HostPortPair::FromURL(restricted_port_request.url),
8652 kRestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008653 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118654
[email protected]262eec82013-03-19 21:01:368655 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508656 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418657 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118658
[email protected]49639fa2011-12-20 23:22:418659 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368660 &restricted_port_request,
8661 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118662 EXPECT_EQ(ERR_IO_PENDING, rv);
8663 // Valid change to restricted port should pass.
8664 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118665}
8666
[email protected]23e482282013-06-14 16:08:028667TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238668 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118669 // Ensure that we're not allowed to redirect traffic via an alternate
8670 // protocol to an unrestricted (port >= 1024) when the original traffic was
8671 // on a restricted port (port < 1024). Ensure that we can redirect in all
8672 // other cases.
[email protected]d7599122014-05-24 03:37:238673 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118674
8675 HttpRequestInfo unrestricted_port_request;
8676 unrestricted_port_request.method = "GET";
8677 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8678 unrestricted_port_request.load_flags = 0;
8679
[email protected]d973e99a2012-02-17 21:02:368680 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118681 StaticSocketDataProvider first_data;
8682 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078683 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118684
8685 MockRead data_reads[] = {
8686 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8687 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068688 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118689 };
8690 StaticSocketDataProvider second_data(
8691 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078692 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118693
[email protected]bb88e1d32013-05-03 23:11:078694 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118695
[email protected]30d4c022013-07-18 22:58:168696 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538697 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118698 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538699 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118700 HostPortPair::FromURL(unrestricted_port_request.url),
8701 kRestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008702 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118703
[email protected]262eec82013-03-19 21:01:368704 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508705 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418706 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118707
[email protected]49639fa2011-12-20 23:22:418708 int rv = trans->Start(
8709 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118710 EXPECT_EQ(ERR_IO_PENDING, rv);
8711 // Valid change to restricted port should pass.
8712 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118713}
8714
[email protected]23e482282013-06-14 16:08:028715TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238716 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118717 // Ensure that we're not allowed to redirect traffic via an alternate
8718 // protocol to an unrestricted (port >= 1024) when the original traffic was
8719 // on a restricted port (port < 1024). Ensure that we can redirect in all
8720 // other cases.
[email protected]d7599122014-05-24 03:37:238721 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118722
8723 HttpRequestInfo unrestricted_port_request;
8724 unrestricted_port_request.method = "GET";
8725 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8726 unrestricted_port_request.load_flags = 0;
8727
[email protected]d973e99a2012-02-17 21:02:368728 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118729 StaticSocketDataProvider first_data;
8730 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078731 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118732
8733 MockRead data_reads[] = {
8734 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8735 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068736 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118737 };
8738 StaticSocketDataProvider second_data(
8739 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078740 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118741
[email protected]bb88e1d32013-05-03 23:11:078742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118743
[email protected]30d4c022013-07-18 22:58:168744 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538745 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118746 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538747 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118748 HostPortPair::FromURL(unrestricted_port_request.url),
8749 kUnrestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008750 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118751
[email protected]262eec82013-03-19 21:01:368752 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508753 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418754 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118755
[email protected]49639fa2011-12-20 23:22:418756 int rv = trans->Start(
8757 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118758 EXPECT_EQ(ERR_IO_PENDING, rv);
8759 // Valid change to an unrestricted port should pass.
8760 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118761}
8762
[email protected]d7599122014-05-24 03:37:238763TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028764 // Ensure that we're not allowed to redirect traffic via an alternate
8765 // protocol to an unsafe port, and that we resume the second
8766 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:238767 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:028768
8769 HttpRequestInfo request;
8770 request.method = "GET";
8771 request.url = GURL("http://www.google.com/");
8772 request.load_flags = 0;
8773
8774 // The alternate protocol request will error out before we attempt to connect,
8775 // so only the standard HTTP request will try to connect.
8776 MockRead data_reads[] = {
8777 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8778 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068779 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028780 };
8781 StaticSocketDataProvider data(
8782 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078783 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028784
[email protected]bb88e1d32013-05-03 23:11:078785 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028786
[email protected]30d4c022013-07-18 22:58:168787 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028788 session->http_server_properties();
8789 const int kUnsafePort = 7;
8790 http_server_properties->SetAlternateProtocol(
8791 HostPortPair::FromURL(request.url),
8792 kUnsafePort,
[email protected]287d9412014-07-08 23:01:008793 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]eb6234e2012-01-19 01:50:028794
[email protected]262eec82013-03-19 21:01:368795 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508796 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028797 TestCompletionCallback callback;
8798
8799 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8800 EXPECT_EQ(ERR_IO_PENDING, rv);
8801 // The HTTP request should succeed.
8802 EXPECT_EQ(OK, callback.WaitForResult());
8803
8804 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:238805 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:028806
8807 const HttpResponseInfo* response = trans->GetResponseInfo();
8808 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508809 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028810 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8811
8812 std::string response_data;
8813 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8814 EXPECT_EQ("hello world", response_data);
8815}
8816
[email protected]23e482282013-06-14 16:08:028817TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:238818 session_deps_.use_alternate_protocols = true;
8819 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:548820
8821 HttpRequestInfo request;
8822 request.method = "GET";
8823 request.url = GURL("http://www.google.com/");
8824 request.load_flags = 0;
8825
[email protected]8a0fc822013-06-27 20:52:438826 std::string alternate_protocol_http_header =
8827 GetAlternateProtocolHttpHeader();
8828
[email protected]2ff8b312010-04-26 22:20:548829 MockRead data_reads[] = {
8830 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438831 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548832 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178833 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8834 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548835 };
8836
8837 StaticSocketDataProvider first_transaction(
8838 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078839 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548840
[email protected]8ddf8322012-02-23 18:08:068841 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028842 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078843 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548844
[email protected]cdf8f7e72013-05-23 10:56:468845 scoped_ptr<SpdyFrame> req(
8846 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138847 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548848
[email protected]23e482282013-06-14 16:08:028849 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8850 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548851 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138852 CreateMockRead(*resp),
8853 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068854 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548855 };
8856
[email protected]dd54bd82012-07-19 23:44:578857 DelayedSocketData spdy_data(
8858 1, // wait for one write to finish before reading.
8859 spdy_reads, arraysize(spdy_reads),
8860 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078861 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548862
[email protected]d973e99a2012-02-17 21:02:368863 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558864 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8865 NULL, 0, NULL, 0);
8866 hanging_non_alternate_protocol_socket.set_connect_data(
8867 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078868 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558869 &hanging_non_alternate_protocol_socket);
8870
[email protected]49639fa2011-12-20 23:22:418871 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548872
[email protected]bb88e1d32013-05-03 23:11:078873 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368874 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548876
[email protected]49639fa2011-12-20 23:22:418877 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548878 EXPECT_EQ(ERR_IO_PENDING, rv);
8879 EXPECT_EQ(OK, callback.WaitForResult());
8880
8881 const HttpResponseInfo* response = trans->GetResponseInfo();
8882 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508883 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548884 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8885
8886 std::string response_data;
8887 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8888 EXPECT_EQ("hello world", response_data);
8889
[email protected]90499482013-06-01 00:39:508890 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548891
[email protected]49639fa2011-12-20 23:22:418892 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548893 EXPECT_EQ(ERR_IO_PENDING, rv);
8894 EXPECT_EQ(OK, callback.WaitForResult());
8895
8896 response = trans->GetResponseInfo();
8897 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508898 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548899 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538900 EXPECT_TRUE(response->was_fetched_via_spdy);
8901 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548902
8903 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8904 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548905}
8906
[email protected]23e482282013-06-14 16:08:028907TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:238908 session_deps_.use_alternate_protocols = true;
8909 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:558910
8911 HttpRequestInfo request;
8912 request.method = "GET";
8913 request.url = GURL("http://www.google.com/");
8914 request.load_flags = 0;
8915
[email protected]8a0fc822013-06-27 20:52:438916 std::string alternate_protocol_http_header =
8917 GetAlternateProtocolHttpHeader();
8918
[email protected]2d6728692011-03-12 01:39:558919 MockRead data_reads[] = {
8920 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438921 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558922 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178923 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068924 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558925 };
8926
8927 StaticSocketDataProvider first_transaction(
8928 data_reads, arraysize(data_reads), NULL, 0);
8929 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078930 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558931
[email protected]d973e99a2012-02-17 21:02:368932 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558933 StaticSocketDataProvider hanging_socket(
8934 NULL, 0, NULL, 0);
8935 hanging_socket.set_connect_data(never_finishing_connect);
8936 // Socket 2 and 3 are the hanging Alternate-Protocol and
8937 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078938 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8939 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558940
[email protected]8ddf8322012-02-23 18:08:068941 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028942 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078943 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558944
[email protected]cdf8f7e72013-05-23 10:56:468945 scoped_ptr<SpdyFrame> req1(
8946 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8947 scoped_ptr<SpdyFrame> req2(
8948 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558949 MockWrite spdy_writes[] = {
8950 CreateMockWrite(*req1),
8951 CreateMockWrite(*req2),
8952 };
[email protected]23e482282013-06-14 16:08:028953 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8954 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8955 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8956 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558957 MockRead spdy_reads[] = {
8958 CreateMockRead(*resp1),
8959 CreateMockRead(*data1),
8960 CreateMockRead(*resp2),
8961 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068962 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558963 };
8964
[email protected]dd54bd82012-07-19 23:44:578965 DelayedSocketData spdy_data(
8966 2, // wait for writes to finish before reading.
8967 spdy_reads, arraysize(spdy_reads),
8968 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558969 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078970 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558971
8972 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078973 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558974
[email protected]bb88e1d32013-05-03 23:11:078975 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418976 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508977 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558978
[email protected]49639fa2011-12-20 23:22:418979 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558980 EXPECT_EQ(ERR_IO_PENDING, rv);
8981 EXPECT_EQ(OK, callback1.WaitForResult());
8982
8983 const HttpResponseInfo* response = trans1.GetResponseInfo();
8984 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508985 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558986 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8987
8988 std::string response_data;
8989 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8990 EXPECT_EQ("hello world", response_data);
8991
[email protected]49639fa2011-12-20 23:22:418992 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508993 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418994 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558995 EXPECT_EQ(ERR_IO_PENDING, rv);
8996
[email protected]49639fa2011-12-20 23:22:418997 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508998 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418999 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559000 EXPECT_EQ(ERR_IO_PENDING, rv);
9001
9002 EXPECT_EQ(OK, callback2.WaitForResult());
9003 EXPECT_EQ(OK, callback3.WaitForResult());
9004
9005 response = trans2.GetResponseInfo();
9006 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509007 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559008 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9009 EXPECT_TRUE(response->was_fetched_via_spdy);
9010 EXPECT_TRUE(response->was_npn_negotiated);
9011 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9012 EXPECT_EQ("hello!", response_data);
9013
9014 response = trans3.GetResponseInfo();
9015 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509016 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559017 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9018 EXPECT_TRUE(response->was_fetched_via_spdy);
9019 EXPECT_TRUE(response->was_npn_negotiated);
9020 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9021 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559022}
9023
[email protected]23e482282013-06-14 16:08:029024TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239025 session_deps_.use_alternate_protocols = true;
9026 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559027
9028 HttpRequestInfo request;
9029 request.method = "GET";
9030 request.url = GURL("http://www.google.com/");
9031 request.load_flags = 0;
9032
[email protected]8a0fc822013-06-27 20:52:439033 std::string alternate_protocol_http_header =
9034 GetAlternateProtocolHttpHeader();
9035
[email protected]2d6728692011-03-12 01:39:559036 MockRead data_reads[] = {
9037 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439038 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559039 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179040 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069041 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559042 };
9043
9044 StaticSocketDataProvider first_transaction(
9045 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079046 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559047
[email protected]8ddf8322012-02-23 18:08:069048 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029049 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559051
[email protected]d973e99a2012-02-17 21:02:369052 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559053 StaticSocketDataProvider hanging_alternate_protocol_socket(
9054 NULL, 0, NULL, 0);
9055 hanging_alternate_protocol_socket.set_connect_data(
9056 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079057 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559058 &hanging_alternate_protocol_socket);
9059
9060 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079061 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559062
[email protected]49639fa2011-12-20 23:22:419063 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559064
[email protected]bb88e1d32013-05-03 23:11:079065 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369066 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559068
[email protected]49639fa2011-12-20 23:22:419069 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559070 EXPECT_EQ(ERR_IO_PENDING, rv);
9071 EXPECT_EQ(OK, callback.WaitForResult());
9072
9073 const HttpResponseInfo* response = trans->GetResponseInfo();
9074 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509075 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559076 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9077
9078 std::string response_data;
9079 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9080 EXPECT_EQ("hello world", response_data);
9081
[email protected]90499482013-06-01 00:39:509082 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559083
[email protected]49639fa2011-12-20 23:22:419084 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559085 EXPECT_EQ(ERR_IO_PENDING, rv);
9086 EXPECT_EQ(OK, callback.WaitForResult());
9087
9088 response = trans->GetResponseInfo();
9089 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509090 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559091 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9092 EXPECT_FALSE(response->was_fetched_via_spdy);
9093 EXPECT_FALSE(response->was_npn_negotiated);
9094
9095 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9096 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559097}
9098
[email protected]631f1322010-04-30 17:59:119099class CapturingProxyResolver : public ProxyResolver {
9100 public:
9101 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
9102 virtual ~CapturingProxyResolver() {}
9103
9104 virtual int GetProxyForURL(const GURL& url,
9105 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:319106 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:119107 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:169108 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:409109 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9110 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429111 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119112 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429113 return OK;
[email protected]631f1322010-04-30 17:59:119114 }
9115
[email protected]46fadfd2013-02-06 09:40:169116 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:119117 NOTREACHED();
9118 }
9119
[email protected]f2c971f2011-11-08 00:33:179120 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
9121 NOTREACHED();
9122 return LOAD_STATE_IDLE;
9123 }
9124
[email protected]46fadfd2013-02-06 09:40:169125 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:409126 NOTREACHED();
9127 }
9128
[email protected]24476402010-07-20 20:55:179129 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:169130 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:429131 return OK;
[email protected]631f1322010-04-30 17:59:119132 }
9133
[email protected]24476402010-07-20 20:55:179134 const std::vector<GURL>& resolved() const { return resolved_; }
9135
9136 private:
[email protected]631f1322010-04-30 17:59:119137 std::vector<GURL> resolved_;
9138
9139 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9140};
9141
[email protected]23e482282013-06-14 16:08:029142TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239143 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239144 session_deps_.use_alternate_protocols = true;
9145 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119146
9147 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429148 proxy_config.set_auto_detect(true);
9149 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119150
[email protected]631f1322010-04-30 17:59:119151 CapturingProxyResolver* capturing_proxy_resolver =
9152 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:079153 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:389154 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9155 NULL));
[email protected]029c83b62013-01-24 05:28:209156 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079157 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119158
9159 HttpRequestInfo request;
9160 request.method = "GET";
9161 request.url = GURL("http://www.google.com/");
9162 request.load_flags = 0;
9163
[email protected]8a0fc822013-06-27 20:52:439164 std::string alternate_protocol_http_header =
9165 GetAlternateProtocolHttpHeader();
9166
[email protected]631f1322010-04-30 17:59:119167 MockRead data_reads[] = {
9168 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439169 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119170 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179171 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069172 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119173 };
9174
9175 StaticSocketDataProvider first_transaction(
9176 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079177 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119178
[email protected]8ddf8322012-02-23 18:08:069179 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029180 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079181 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119182
[email protected]cdf8f7e72013-05-23 10:56:469183 scoped_ptr<SpdyFrame> req(
9184 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119185 MockWrite spdy_writes[] = {
9186 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9187 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:429188 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:469189 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:119190 };
9191
[email protected]d911f1b2010-05-05 22:39:429192 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9193
[email protected]23e482282013-06-14 16:08:029194 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9195 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119196 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069197 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:139198 CreateMockRead(*resp.get(), 4), // 2, 4
9199 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:069200 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:119201 };
9202
[email protected]dd54bd82012-07-19 23:44:579203 OrderedSocketData spdy_data(
9204 spdy_reads, arraysize(spdy_reads),
9205 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079206 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119207
[email protected]d973e99a2012-02-17 21:02:369208 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559209 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9210 NULL, 0, NULL, 0);
9211 hanging_non_alternate_protocol_socket.set_connect_data(
9212 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079213 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559214 &hanging_non_alternate_protocol_socket);
9215
[email protected]49639fa2011-12-20 23:22:419216 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119217
[email protected]bb88e1d32013-05-03 23:11:079218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369219 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509220 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119221
[email protected]49639fa2011-12-20 23:22:419222 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119223 EXPECT_EQ(ERR_IO_PENDING, rv);
9224 EXPECT_EQ(OK, callback.WaitForResult());
9225
9226 const HttpResponseInfo* response = trans->GetResponseInfo();
9227 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509228 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119229 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539230 EXPECT_FALSE(response->was_fetched_via_spdy);
9231 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119232
9233 std::string response_data;
9234 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9235 EXPECT_EQ("hello world", response_data);
9236
[email protected]90499482013-06-01 00:39:509237 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119238
[email protected]49639fa2011-12-20 23:22:419239 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119240 EXPECT_EQ(ERR_IO_PENDING, rv);
9241 EXPECT_EQ(OK, callback.WaitForResult());
9242
9243 response = trans->GetResponseInfo();
9244 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509245 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119246 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539247 EXPECT_TRUE(response->was_fetched_via_spdy);
9248 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119249
9250 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9251 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559252 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:429253 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:119254 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:429255 EXPECT_EQ("https://www.google.com/",
9256 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119257
[email protected]029c83b62013-01-24 05:28:209258 LoadTimingInfo load_timing_info;
9259 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9260 TestLoadTimingNotReusedWithPac(load_timing_info,
9261 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119262}
[email protected]631f1322010-04-30 17:59:119263
[email protected]23e482282013-06-14 16:08:029264TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549265 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239266 session_deps_.use_alternate_protocols = true;
9267 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549268
9269 HttpRequestInfo request;
9270 request.method = "GET";
9271 request.url = GURL("http://www.google.com/");
9272 request.load_flags = 0;
9273
[email protected]8a0fc822013-06-27 20:52:439274 std::string alternate_protocol_http_header =
9275 GetAlternateProtocolHttpHeader();
9276
[email protected]2ff8b312010-04-26 22:20:549277 MockRead data_reads[] = {
9278 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439279 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549280 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069281 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549282 };
9283
9284 StaticSocketDataProvider first_transaction(
9285 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079286 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549287
[email protected]8ddf8322012-02-23 18:08:069288 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029289 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549291
[email protected]cdf8f7e72013-05-23 10:56:469292 scoped_ptr<SpdyFrame> req(
9293 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139294 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549295
[email protected]23e482282013-06-14 16:08:029296 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9297 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549298 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139299 CreateMockRead(*resp),
9300 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069301 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549302 };
9303
[email protected]dd54bd82012-07-19 23:44:579304 DelayedSocketData spdy_data(
9305 1, // wait for one write to finish before reading.
9306 spdy_reads, arraysize(spdy_reads),
9307 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079308 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549309
[email protected]83039bb2011-12-09 18:43:559310 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549311
[email protected]bb88e1d32013-05-03 23:11:079312 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549313
[email protected]262eec82013-03-19 21:01:369314 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509315 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549316
[email protected]49639fa2011-12-20 23:22:419317 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549318 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419319 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549320
9321 const HttpResponseInfo* response = trans->GetResponseInfo();
9322 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509323 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549324 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9325
9326 std::string response_data;
9327 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9328 EXPECT_EQ("hello world", response_data);
9329
9330 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389331 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409332 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539333 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279334 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269335 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389336
[email protected]90499482013-06-01 00:39:509337 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549338
[email protected]49639fa2011-12-20 23:22:419339 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549340 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419341 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549342
9343 response = trans->GetResponseInfo();
9344 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509345 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549346 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539347 EXPECT_TRUE(response->was_fetched_via_spdy);
9348 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549349
9350 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9351 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429352}
9353
[email protected]044de0642010-06-17 10:42:159354// GenerateAuthToken is a mighty big test.
9355// It tests all permutation of GenerateAuthToken behavior:
9356// - Synchronous and Asynchronous completion.
9357// - OK or error on completion.
9358// - Direct connection, non-authenticating proxy, and authenticating proxy.
9359// - HTTP or HTTPS backend (to include proxy tunneling).
9360// - Non-authenticating and authenticating backend.
9361//
[email protected]fe3b7dc2012-02-03 19:52:099362// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159363// problems generating an auth token for an authenticating proxy, we don't
9364// need to test all permutations of the backend server).
9365//
9366// The test proceeds by going over each of the configuration cases, and
9367// potentially running up to three rounds in each of the tests. The TestConfig
9368// specifies both the configuration for the test as well as the expectations
9369// for the results.
[email protected]23e482282013-06-14 16:08:029370TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509371 static const char kServer[] = "http://www.example.com";
9372 static const char kSecureServer[] = "https://www.example.com";
9373 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159374 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9375
9376 enum AuthTiming {
9377 AUTH_NONE,
9378 AUTH_SYNC,
9379 AUTH_ASYNC,
9380 };
9381
9382 const MockWrite kGet(
9383 "GET / HTTP/1.1\r\n"
9384 "Host: www.example.com\r\n"
9385 "Connection: keep-alive\r\n\r\n");
9386 const MockWrite kGetProxy(
9387 "GET http://www.example.com/ HTTP/1.1\r\n"
9388 "Host: www.example.com\r\n"
9389 "Proxy-Connection: keep-alive\r\n\r\n");
9390 const MockWrite kGetAuth(
9391 "GET / HTTP/1.1\r\n"
9392 "Host: www.example.com\r\n"
9393 "Connection: keep-alive\r\n"
9394 "Authorization: auth_token\r\n\r\n");
9395 const MockWrite kGetProxyAuth(
9396 "GET http://www.example.com/ HTTP/1.1\r\n"
9397 "Host: www.example.com\r\n"
9398 "Proxy-Connection: keep-alive\r\n"
9399 "Proxy-Authorization: auth_token\r\n\r\n");
9400 const MockWrite kGetAuthThroughProxy(
9401 "GET http://www.example.com/ HTTP/1.1\r\n"
9402 "Host: www.example.com\r\n"
9403 "Proxy-Connection: keep-alive\r\n"
9404 "Authorization: auth_token\r\n\r\n");
9405 const MockWrite kGetAuthWithProxyAuth(
9406 "GET http://www.example.com/ HTTP/1.1\r\n"
9407 "Host: www.example.com\r\n"
9408 "Proxy-Connection: keep-alive\r\n"
9409 "Proxy-Authorization: auth_token\r\n"
9410 "Authorization: auth_token\r\n\r\n");
9411 const MockWrite kConnect(
9412 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9413 "Host: www.example.com\r\n"
9414 "Proxy-Connection: keep-alive\r\n\r\n");
9415 const MockWrite kConnectProxyAuth(
9416 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9417 "Host: www.example.com\r\n"
9418 "Proxy-Connection: keep-alive\r\n"
9419 "Proxy-Authorization: auth_token\r\n\r\n");
9420
9421 const MockRead kSuccess(
9422 "HTTP/1.1 200 OK\r\n"
9423 "Content-Type: text/html; charset=iso-8859-1\r\n"
9424 "Content-Length: 3\r\n\r\n"
9425 "Yes");
9426 const MockRead kFailure(
9427 "Should not be called.");
9428 const MockRead kServerChallenge(
9429 "HTTP/1.1 401 Unauthorized\r\n"
9430 "WWW-Authenticate: Mock realm=server\r\n"
9431 "Content-Type: text/html; charset=iso-8859-1\r\n"
9432 "Content-Length: 14\r\n\r\n"
9433 "Unauthorized\r\n");
9434 const MockRead kProxyChallenge(
9435 "HTTP/1.1 407 Unauthorized\r\n"
9436 "Proxy-Authenticate: Mock realm=proxy\r\n"
9437 "Proxy-Connection: close\r\n"
9438 "Content-Type: text/html; charset=iso-8859-1\r\n"
9439 "Content-Length: 14\r\n\r\n"
9440 "Unauthorized\r\n");
9441 const MockRead kProxyConnected(
9442 "HTTP/1.1 200 Connection Established\r\n\r\n");
9443
9444 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9445 // no constructors, but the C++ compiler on Windows warns about
9446 // unspecified data in compound literals. So, moved to using constructors,
9447 // and TestRound's created with the default constructor should not be used.
9448 struct TestRound {
9449 TestRound()
9450 : expected_rv(ERR_UNEXPECTED),
9451 extra_write(NULL),
9452 extra_read(NULL) {
9453 }
9454 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9455 int expected_rv_arg)
9456 : write(write_arg),
9457 read(read_arg),
9458 expected_rv(expected_rv_arg),
9459 extra_write(NULL),
9460 extra_read(NULL) {
9461 }
9462 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9463 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019464 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159465 : write(write_arg),
9466 read(read_arg),
9467 expected_rv(expected_rv_arg),
9468 extra_write(extra_write_arg),
9469 extra_read(extra_read_arg) {
9470 }
9471 MockWrite write;
9472 MockRead read;
9473 int expected_rv;
9474 const MockWrite* extra_write;
9475 const MockRead* extra_read;
9476 };
9477
9478 static const int kNoSSL = 500;
9479
9480 struct TestConfig {
9481 const char* proxy_url;
9482 AuthTiming proxy_auth_timing;
9483 int proxy_auth_rv;
9484 const char* server_url;
9485 AuthTiming server_auth_timing;
9486 int server_auth_rv;
9487 int num_auth_rounds;
9488 int first_ssl_round;
9489 TestRound rounds[3];
9490 } test_configs[] = {
9491 // Non-authenticating HTTP server with a direct connection.
9492 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9493 { TestRound(kGet, kSuccess, OK)}},
9494 // Authenticating HTTP server with a direct connection.
9495 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9496 { TestRound(kGet, kServerChallenge, OK),
9497 TestRound(kGetAuth, kSuccess, OK)}},
9498 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9499 { TestRound(kGet, kServerChallenge, OK),
9500 TestRound(kGetAuth, kFailure, kAuthErr)}},
9501 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9502 { TestRound(kGet, kServerChallenge, OK),
9503 TestRound(kGetAuth, kSuccess, OK)}},
9504 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9505 { TestRound(kGet, kServerChallenge, OK),
9506 TestRound(kGetAuth, kFailure, kAuthErr)}},
9507 // Non-authenticating HTTP server through a non-authenticating proxy.
9508 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9509 { TestRound(kGetProxy, kSuccess, OK)}},
9510 // Authenticating HTTP server through a non-authenticating proxy.
9511 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9512 { TestRound(kGetProxy, kServerChallenge, OK),
9513 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9514 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9515 { TestRound(kGetProxy, kServerChallenge, OK),
9516 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9517 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9518 { TestRound(kGetProxy, kServerChallenge, OK),
9519 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9520 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9521 { TestRound(kGetProxy, kServerChallenge, OK),
9522 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9523 // Non-authenticating HTTP server through an authenticating proxy.
9524 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9525 { TestRound(kGetProxy, kProxyChallenge, OK),
9526 TestRound(kGetProxyAuth, kSuccess, OK)}},
9527 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9528 { TestRound(kGetProxy, kProxyChallenge, OK),
9529 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9530 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9531 { TestRound(kGetProxy, kProxyChallenge, OK),
9532 TestRound(kGetProxyAuth, kSuccess, OK)}},
9533 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9534 { TestRound(kGetProxy, kProxyChallenge, OK),
9535 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9536 // Authenticating HTTP server through an authenticating proxy.
9537 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9538 { TestRound(kGetProxy, kProxyChallenge, OK),
9539 TestRound(kGetProxyAuth, kServerChallenge, OK),
9540 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9541 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9542 { TestRound(kGetProxy, kProxyChallenge, OK),
9543 TestRound(kGetProxyAuth, kServerChallenge, OK),
9544 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9545 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9546 { TestRound(kGetProxy, kProxyChallenge, OK),
9547 TestRound(kGetProxyAuth, kServerChallenge, OK),
9548 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9549 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9550 { TestRound(kGetProxy, kProxyChallenge, OK),
9551 TestRound(kGetProxyAuth, kServerChallenge, OK),
9552 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9553 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9554 { TestRound(kGetProxy, kProxyChallenge, OK),
9555 TestRound(kGetProxyAuth, kServerChallenge, OK),
9556 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9557 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9558 { TestRound(kGetProxy, kProxyChallenge, OK),
9559 TestRound(kGetProxyAuth, kServerChallenge, OK),
9560 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9561 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9562 { TestRound(kGetProxy, kProxyChallenge, OK),
9563 TestRound(kGetProxyAuth, kServerChallenge, OK),
9564 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9565 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9566 { TestRound(kGetProxy, kProxyChallenge, OK),
9567 TestRound(kGetProxyAuth, kServerChallenge, OK),
9568 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9569 // Non-authenticating HTTPS server with a direct connection.
9570 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9571 { TestRound(kGet, kSuccess, OK)}},
9572 // Authenticating HTTPS server with a direct connection.
9573 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9574 { TestRound(kGet, kServerChallenge, OK),
9575 TestRound(kGetAuth, kSuccess, OK)}},
9576 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9577 { TestRound(kGet, kServerChallenge, OK),
9578 TestRound(kGetAuth, kFailure, kAuthErr)}},
9579 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9580 { TestRound(kGet, kServerChallenge, OK),
9581 TestRound(kGetAuth, kSuccess, OK)}},
9582 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9583 { TestRound(kGet, kServerChallenge, OK),
9584 TestRound(kGetAuth, kFailure, kAuthErr)}},
9585 // Non-authenticating HTTPS server with a non-authenticating proxy.
9586 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9587 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9588 // Authenticating HTTPS server through a non-authenticating proxy.
9589 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9590 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9591 TestRound(kGetAuth, kSuccess, OK)}},
9592 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9593 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9594 TestRound(kGetAuth, kFailure, kAuthErr)}},
9595 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9596 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9597 TestRound(kGetAuth, kSuccess, OK)}},
9598 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9599 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9600 TestRound(kGetAuth, kFailure, kAuthErr)}},
9601 // Non-Authenticating HTTPS server through an authenticating proxy.
9602 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9603 { TestRound(kConnect, kProxyChallenge, OK),
9604 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9605 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9606 { TestRound(kConnect, kProxyChallenge, OK),
9607 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9608 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9609 { TestRound(kConnect, kProxyChallenge, OK),
9610 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9611 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9612 { TestRound(kConnect, kProxyChallenge, OK),
9613 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9614 // Authenticating HTTPS server through an authenticating proxy.
9615 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9616 { TestRound(kConnect, kProxyChallenge, OK),
9617 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9618 &kGet, &kServerChallenge),
9619 TestRound(kGetAuth, kSuccess, OK)}},
9620 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9621 { TestRound(kConnect, kProxyChallenge, OK),
9622 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9623 &kGet, &kServerChallenge),
9624 TestRound(kGetAuth, kFailure, kAuthErr)}},
9625 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9626 { TestRound(kConnect, kProxyChallenge, OK),
9627 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9628 &kGet, &kServerChallenge),
9629 TestRound(kGetAuth, kSuccess, OK)}},
9630 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9631 { TestRound(kConnect, kProxyChallenge, OK),
9632 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9633 &kGet, &kServerChallenge),
9634 TestRound(kGetAuth, kFailure, kAuthErr)}},
9635 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9636 { TestRound(kConnect, kProxyChallenge, OK),
9637 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9638 &kGet, &kServerChallenge),
9639 TestRound(kGetAuth, kSuccess, OK)}},
9640 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9641 { TestRound(kConnect, kProxyChallenge, OK),
9642 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9643 &kGet, &kServerChallenge),
9644 TestRound(kGetAuth, kFailure, kAuthErr)}},
9645 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9646 { TestRound(kConnect, kProxyChallenge, OK),
9647 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9648 &kGet, &kServerChallenge),
9649 TestRound(kGetAuth, kSuccess, OK)}},
9650 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9651 { TestRound(kConnect, kProxyChallenge, OK),
9652 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9653 &kGet, &kServerChallenge),
9654 TestRound(kGetAuth, kFailure, kAuthErr)}},
9655 };
9656
[email protected]044de0642010-06-17 10:42:159657 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089658 HttpAuthHandlerMock::Factory* auth_factory(
9659 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079660 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159661 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269662
9663 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159664 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089665 for (int n = 0; n < 2; n++) {
9666 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9667 std::string auth_challenge = "Mock realm=proxy";
9668 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:249669 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9670 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:089671 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9672 origin, BoundNetLog());
9673 auth_handler->SetGenerateExpectation(
9674 test_config.proxy_auth_timing == AUTH_ASYNC,
9675 test_config.proxy_auth_rv);
9676 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9677 }
[email protected]044de0642010-06-17 10:42:159678 }
9679 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009680 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159681 std::string auth_challenge = "Mock realm=server";
9682 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:249683 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9684 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:159685 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9686 origin, BoundNetLog());
9687 auth_handler->SetGenerateExpectation(
9688 test_config.server_auth_timing == AUTH_ASYNC,
9689 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089690 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159691 }
9692 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079693 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129694 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159695 } else {
[email protected]bb88e1d32013-05-03 23:11:079696 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159697 }
9698
9699 HttpRequestInfo request;
9700 request.method = "GET";
9701 request.url = GURL(test_config.server_url);
9702 request.load_flags = 0;
9703
[email protected]bb88e1d32013-05-03 23:11:079704 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:079705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]044de0642010-06-17 10:42:159706
9707 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9708 const TestRound& read_write_round = test_config.rounds[round];
9709
9710 // Set up expected reads and writes.
9711 MockRead reads[2];
9712 reads[0] = read_write_round.read;
9713 size_t length_reads = 1;
9714 if (read_write_round.extra_read) {
9715 reads[1] = *read_write_round.extra_read;
9716 length_reads = 2;
9717 }
9718
9719 MockWrite writes[2];
9720 writes[0] = read_write_round.write;
9721 size_t length_writes = 1;
9722 if (read_write_round.extra_write) {
9723 writes[1] = *read_write_round.extra_write;
9724 length_writes = 2;
9725 }
9726 StaticSocketDataProvider data_provider(
9727 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079728 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159729
9730 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069731 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159732 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079733 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159734 &ssl_socket_data_provider);
9735
9736 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419737 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159738 int rv;
9739 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419740 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159741 } else {
[email protected]49639fa2011-12-20 23:22:419742 rv = trans.RestartWithAuth(
9743 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159744 }
9745 if (rv == ERR_IO_PENDING)
9746 rv = callback.WaitForResult();
9747
9748 // Compare results with expected data.
9749 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509750 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159751 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509752 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159753 } else {
9754 EXPECT_TRUE(response == NULL);
9755 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9756 continue;
9757 }
9758 if (round + 1 < test_config.num_auth_rounds) {
9759 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9760 } else {
9761 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9762 }
9763 }
[email protected]e5ae96a2010-04-14 20:12:459764 }
9765}
9766
[email protected]23e482282013-06-14 16:08:029767TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149768 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149769 HttpAuthHandlerMock::Factory* auth_factory(
9770 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079771 session_deps_.http_auth_handler_factory.reset(auth_factory);
9772 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9773 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9774 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149775
9776 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9777 auth_handler->set_connection_based(true);
9778 std::string auth_challenge = "Mock realm=server";
9779 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:249780 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9781 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:149782 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9783 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089784 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149785
[email protected]c871bce92010-07-15 21:51:149786 int rv = OK;
9787 const HttpResponseInfo* response = NULL;
9788 HttpRequestInfo request;
9789 request.method = "GET";
9790 request.url = origin;
9791 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279792
[email protected]bb88e1d32013-05-03 23:11:079793 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109794
9795 // Use a TCP Socket Pool with only one connection per group. This is used
9796 // to validate that the TCP socket is not released to the pool between
9797 // each round of multi-round authentication.
9798 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289799 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9800 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109801 50, // Max sockets for pool
9802 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289803 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079804 session_deps_.host_resolver.get(),
9805 session_deps_.socket_factory.get(),
9806 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449807 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9808 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029809 mock_pool_manager->SetTransportSocketPool(transport_pool);
[email protected]831e4a32013-11-14 02:14:449810 session_peer.SetClientSocketPoolManager(
9811 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]7ef4cbbb2011-02-06 11:19:109812
[email protected]262eec82013-03-19 21:01:369813 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509814 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419815 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149816
9817 const MockWrite kGet(
9818 "GET / HTTP/1.1\r\n"
9819 "Host: www.example.com\r\n"
9820 "Connection: keep-alive\r\n\r\n");
9821 const MockWrite kGetAuth(
9822 "GET / HTTP/1.1\r\n"
9823 "Host: www.example.com\r\n"
9824 "Connection: keep-alive\r\n"
9825 "Authorization: auth_token\r\n\r\n");
9826
9827 const MockRead kServerChallenge(
9828 "HTTP/1.1 401 Unauthorized\r\n"
9829 "WWW-Authenticate: Mock realm=server\r\n"
9830 "Content-Type: text/html; charset=iso-8859-1\r\n"
9831 "Content-Length: 14\r\n\r\n"
9832 "Unauthorized\r\n");
9833 const MockRead kSuccess(
9834 "HTTP/1.1 200 OK\r\n"
9835 "Content-Type: text/html; charset=iso-8859-1\r\n"
9836 "Content-Length: 3\r\n\r\n"
9837 "Yes");
9838
9839 MockWrite writes[] = {
9840 // First round
9841 kGet,
9842 // Second round
9843 kGetAuth,
9844 // Third round
9845 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309846 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109847 kGetAuth,
9848 // Competing request
9849 kGet,
[email protected]c871bce92010-07-15 21:51:149850 };
9851 MockRead reads[] = {
9852 // First round
9853 kServerChallenge,
9854 // Second round
9855 kServerChallenge,
9856 // Third round
[email protected]eca50e122010-09-11 14:03:309857 kServerChallenge,
9858 // Fourth round
[email protected]c871bce92010-07-15 21:51:149859 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109860 // Competing response
9861 kSuccess,
[email protected]c871bce92010-07-15 21:51:149862 };
9863 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9864 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079865 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149866
[email protected]7ef4cbbb2011-02-06 11:19:109867 const char* const kSocketGroup = "www.example.com:80";
9868
9869 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149870 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419871 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149872 if (rv == ERR_IO_PENDING)
9873 rv = callback.WaitForResult();
9874 EXPECT_EQ(OK, rv);
9875 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509876 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149877 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289878 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149879
[email protected]7ef4cbbb2011-02-06 11:19:109880 // In between rounds, another request comes in for the same domain.
9881 // It should not be able to grab the TCP socket that trans has already
9882 // claimed.
9883 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509884 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419885 TestCompletionCallback callback_compete;
9886 rv = trans_compete->Start(
9887 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109888 EXPECT_EQ(ERR_IO_PENDING, rv);
9889 // callback_compete.WaitForResult at this point would stall forever,
9890 // since the HttpNetworkTransaction does not release the request back to
9891 // the pool until after authentication completes.
9892
9893 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149894 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419895 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149896 if (rv == ERR_IO_PENDING)
9897 rv = callback.WaitForResult();
9898 EXPECT_EQ(OK, rv);
9899 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509900 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149901 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289902 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149903
[email protected]7ef4cbbb2011-02-06 11:19:109904 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149905 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419906 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149907 if (rv == ERR_IO_PENDING)
9908 rv = callback.WaitForResult();
9909 EXPECT_EQ(OK, rv);
9910 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509911 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149912 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289913 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309914
[email protected]7ef4cbbb2011-02-06 11:19:109915 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309916 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419917 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309918 if (rv == ERR_IO_PENDING)
9919 rv = callback.WaitForResult();
9920 EXPECT_EQ(OK, rv);
9921 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509922 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309923 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289924 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109925
9926 // Read the body since the fourth round was successful. This will also
9927 // release the socket back to the pool.
9928 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509929 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109930 if (rv == ERR_IO_PENDING)
9931 rv = callback.WaitForResult();
9932 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509933 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109934 EXPECT_EQ(0, rv);
9935 // There are still 0 idle sockets, since the trans_compete transaction
9936 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289937 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109938
9939 // The competing request can now finish. Wait for the headers and then
9940 // read the body.
9941 rv = callback_compete.WaitForResult();
9942 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509943 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109944 if (rv == ERR_IO_PENDING)
9945 rv = callback.WaitForResult();
9946 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509947 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109948 EXPECT_EQ(0, rv);
9949
9950 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289951 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149952}
9953
[email protected]65041fa2010-05-21 06:56:539954// This tests the case that a request is issued via http instead of spdy after
9955// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029956TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:239957 session_deps_.use_alternate_protocols = true;
9958 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:169959 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:239960 session_deps_.next_protos = next_protos;
9961
[email protected]65041fa2010-05-21 06:56:539962 HttpRequestInfo request;
9963 request.method = "GET";
9964 request.url = GURL("https://www.google.com/");
9965 request.load_flags = 0;
9966
9967 MockWrite data_writes[] = {
9968 MockWrite("GET / HTTP/1.1\r\n"
9969 "Host: www.google.com\r\n"
9970 "Connection: keep-alive\r\n\r\n"),
9971 };
9972
[email protected]8a0fc822013-06-27 20:52:439973 std::string alternate_protocol_http_header =
9974 GetAlternateProtocolHttpHeader();
9975
[email protected]65041fa2010-05-21 06:56:539976 MockRead data_reads[] = {
9977 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439978 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539979 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069980 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539981 };
9982
[email protected]8ddf8322012-02-23 18:08:069983 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539984 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9985 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469986 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539987
[email protected]bb88e1d32013-05-03 23:11:079988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539989
9990 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9991 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079992 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539993
[email protected]49639fa2011-12-20 23:22:419994 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539995
[email protected]bb88e1d32013-05-03 23:11:079996 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369997 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509998 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539999
[email protected]49639fa2011-12-20 23:22:4110000 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310001
10002 EXPECT_EQ(ERR_IO_PENDING, rv);
10003 EXPECT_EQ(OK, callback.WaitForResult());
10004
10005 const HttpResponseInfo* response = trans->GetResponseInfo();
10006 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010007 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310008 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10009
10010 std::string response_data;
10011 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10012 EXPECT_EQ("hello world", response_data);
10013
10014 EXPECT_FALSE(response->was_fetched_via_spdy);
10015 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310016}
[email protected]26ef6582010-06-24 02:30:4710017
[email protected]23e482282013-06-14 16:08:0210018TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710019 // Simulate the SSL handshake completing with an NPN negotiation
10020 // followed by an immediate server closing of the socket.
10021 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310022 session_deps_.use_alternate_protocols = true;
10023 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710024
10025 HttpRequestInfo request;
10026 request.method = "GET";
10027 request.url = GURL("https://www.google.com/");
10028 request.load_flags = 0;
10029
[email protected]8ddf8322012-02-23 18:08:0610030 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210031 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710032 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710033
[email protected]cdf8f7e72013-05-23 10:56:4610034 scoped_ptr<SpdyFrame> req(
10035 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:1310036 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:4710037
10038 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610039 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710040 };
10041
[email protected]dd54bd82012-07-19 23:44:5710042 DelayedSocketData spdy_data(
10043 0, // don't wait in this case, immediate hangup.
10044 spdy_reads, arraysize(spdy_reads),
10045 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710046 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710047
[email protected]49639fa2011-12-20 23:22:4110048 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710049
[email protected]bb88e1d32013-05-03 23:11:0710050 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610051 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710053
[email protected]49639fa2011-12-20 23:22:4110054 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710055 EXPECT_EQ(ERR_IO_PENDING, rv);
10056 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710057}
[email protected]65d34382010-07-01 18:12:2610058
[email protected]795cbf82013-07-22 09:37:2710059// A subclass of HttpAuthHandlerMock that records the request URL when
10060// it gets it. This is needed since the auth handler may get destroyed
10061// before we get a chance to query it.
10062class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10063 public:
10064 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10065
10066 virtual ~UrlRecordingHttpAuthHandlerMock() {}
10067
10068 protected:
10069 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10070 const HttpRequestInfo* request,
10071 const CompletionCallback& callback,
10072 std::string* auth_token) OVERRIDE {
10073 *url_ = request->url;
10074 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10075 credentials, request, callback, auth_token);
10076 }
10077
10078 private:
10079 GURL* url_;
10080};
10081
[email protected]23e482282013-06-14 16:08:0210082TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010083 // This test ensures that the URL passed into the proxy is upgraded
10084 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310085 session_deps_.use_alternate_protocols = true;
10086 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010087
[email protected]bb88e1d32013-05-03 23:11:0710088 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010089 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10090 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710091 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710092 GURL request_url;
10093 {
10094 HttpAuthHandlerMock::Factory* auth_factory =
10095 new HttpAuthHandlerMock::Factory();
10096 UrlRecordingHttpAuthHandlerMock* auth_handler =
10097 new UrlRecordingHttpAuthHandlerMock(&request_url);
10098 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10099 auth_factory->set_do_init_from_challenge(true);
10100 session_deps_.http_auth_handler_factory.reset(auth_factory);
10101 }
[email protected]f45c1ee2010-08-03 00:54:3010102
10103 HttpRequestInfo request;
10104 request.method = "GET";
10105 request.url = GURL("http://www.google.com");
10106 request.load_flags = 0;
10107
10108 // First round goes unauthenticated through the proxy.
10109 MockWrite data_writes_1[] = {
10110 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10111 "Host: www.google.com\r\n"
10112 "Proxy-Connection: keep-alive\r\n"
10113 "\r\n"),
10114 };
10115 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610116 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:3010117 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:2310118 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:3010119 "Proxy-Connection: close\r\n"
10120 "\r\n"),
10121 };
10122 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10123 data_writes_1, arraysize(data_writes_1));
10124
10125 // Second round tries to tunnel to www.google.com due to the
10126 // Alternate-Protocol announcement in the first round. It fails due
10127 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:5910128 // After the failure, a tunnel is established to www.google.com using
10129 // Proxy-Authorization headers. There is then a SPDY request round.
10130 //
[email protected]fe3b7dc2012-02-03 19:52:0910131 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10132 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10133 // does a Disconnect and Connect on the same socket, rather than trying
10134 // to obtain a new one.
10135 //
[email protected]394816e92010-08-03 07:38:5910136 // NOTE: Originally, the proxy response to the second CONNECT request
10137 // simply returned another 407 so the unit test could skip the SSL connection
10138 // establishment and SPDY framing issues. Alas, the
10139 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010140 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910141
[email protected]cdf8f7e72013-05-23 10:56:4610142 scoped_ptr<SpdyFrame> req(
10143 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210144 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10145 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010146
[email protected]394816e92010-08-03 07:38:5910147 MockWrite data_writes_2[] = {
10148 // First connection attempt without Proxy-Authorization.
10149 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10150 "Host: www.google.com\r\n"
10151 "Proxy-Connection: keep-alive\r\n"
10152 "\r\n"),
10153
10154 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:3010155 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10156 "Host: www.google.com\r\n"
10157 "Proxy-Connection: keep-alive\r\n"
10158 "Proxy-Authorization: auth_token\r\n"
10159 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010160
[email protected]394816e92010-08-03 07:38:5910161 // SPDY request
10162 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:3010163 };
[email protected]394816e92010-08-03 07:38:5910164 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10165 "Proxy-Authenticate: Mock\r\n"
10166 "Proxy-Connection: close\r\n"
10167 "\r\n");
10168 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10169 MockRead data_reads_2[] = {
10170 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:0610171 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10172 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:5910173 arraysize(kRejectConnectResponse) - 1, 1),
10174
10175 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:0610176 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:0910177 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:5910178
10179 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:0910180 CreateMockRead(*resp.get(), 6),
10181 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:0610182 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:5910183 };
[email protected]dd54bd82012-07-19 23:44:5710184 OrderedSocketData data_2(
10185 data_reads_2, arraysize(data_reads_2),
10186 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010187
[email protected]8ddf8322012-02-23 18:08:0610188 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210189 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:3010190
[email protected]d973e99a2012-02-17 21:02:3610191 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510192 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10193 NULL, 0, NULL, 0);
10194 hanging_non_alternate_protocol_socket.set_connect_data(
10195 never_finishing_connect);
10196
[email protected]bb88e1d32013-05-03 23:11:0710197 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10198 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10200 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510201 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710202 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010203
10204 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110205 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610206 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010207 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110208 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010209 EXPECT_EQ(ERR_IO_PENDING, rv);
10210 EXPECT_EQ(OK, callback_1.WaitForResult());
10211
10212 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110213 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610214 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110216 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010217 EXPECT_EQ(ERR_IO_PENDING, rv);
10218 EXPECT_EQ(OK, callback_2.WaitForResult());
10219 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010220 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010221 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10222
10223 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110224 TestCompletionCallback callback_3;
10225 rv = trans_2->RestartWithAuth(
10226 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010227 EXPECT_EQ(ERR_IO_PENDING, rv);
10228 EXPECT_EQ(OK, callback_3.WaitForResult());
10229
10230 // After all that work, these two lines (or actually, just the scheme) are
10231 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010232 EXPECT_EQ("https", request_url.scheme());
10233 EXPECT_EQ("www.google.com", request_url.host());
10234
[email protected]029c83b62013-01-24 05:28:2010235 LoadTimingInfo load_timing_info;
10236 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10237 TestLoadTimingNotReusedWithPac(load_timing_info,
10238 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810239}
10240
10241// Test that if we cancel the transaction as the connection is completing, that
10242// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210243TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810244 // Setup everything about the connection to complete synchronously, so that
10245 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10246 // for is the callback from the HttpStreamRequest.
10247 // Then cancel the transaction.
10248 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610249 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810250 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610251 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10252 MockRead(SYNCHRONOUS, "hello world"),
10253 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810254 };
10255
[email protected]8e6441ca2010-08-19 05:56:3810256 HttpRequestInfo request;
10257 request.method = "GET";
10258 request.url = GURL("http://www.google.com/");
10259 request.load_flags = 0;
10260
[email protected]bb88e1d32013-05-03 23:11:0710261 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710262 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710263 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0710264 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:2710265
[email protected]8e6441ca2010-08-19 05:56:3810266 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10267 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710268 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810269
[email protected]49639fa2011-12-20 23:22:4110270 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810271
[email protected]333bdf62012-06-08 22:57:2910272 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:4110273 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810274 EXPECT_EQ(ERR_IO_PENDING, rv);
10275 trans.reset(); // Cancel the transaction here.
10276
[email protected]2da659e2013-05-23 20:51:3410277 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010278}
10279
[email protected]ecab6e052014-05-16 14:58:1210280// Test that if a transaction is cancelled after receiving the headers, the
10281// stream is drained properly and added back to the socket pool. The main
10282// purpose of this test is to make sure that an HttpStreamParser can be read
10283// from after the HttpNetworkTransaction and the objects it owns have been
10284// deleted.
10285// See http://crbug.com/368418
10286TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10287 MockRead data_reads[] = {
10288 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10289 MockRead(ASYNC, "Content-Length: 2\r\n"),
10290 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10291 MockRead(ASYNC, "1"),
10292 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10293 // HttpNetworkTransaction has been deleted.
10294 MockRead(ASYNC, "2"),
10295 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10296 };
10297 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10298 session_deps_.socket_factory->AddSocketDataProvider(&data);
10299
10300 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10301
10302 {
10303 HttpRequestInfo request;
10304 request.method = "GET";
10305 request.url = GURL("http://www.google.com/");
10306 request.load_flags = 0;
10307
10308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
10309 TestCompletionCallback callback;
10310
10311 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10312 EXPECT_EQ(ERR_IO_PENDING, rv);
10313 callback.WaitForResult();
10314
10315 const HttpResponseInfo* response = trans.GetResponseInfo();
10316 ASSERT_TRUE(response != NULL);
10317 EXPECT_TRUE(response->headers.get() != NULL);
10318 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10319
10320 // The transaction and HttpRequestInfo are deleted.
10321 }
10322
10323 // Let the HttpResponseBodyDrainer drain the socket.
10324 base::MessageLoop::current()->RunUntilIdle();
10325
10326 // Socket should now be idle, waiting to be reused.
10327 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
10328}
10329
[email protected]76a505b2010-08-25 06:23:0010330// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210331TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710332 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010333 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910334 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710335 session_deps_.net_log = log.bound().net_log();
10336 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010337
[email protected]76a505b2010-08-25 06:23:0010338 HttpRequestInfo request;
10339 request.method = "GET";
10340 request.url = GURL("http://www.google.com/");
10341
10342 MockWrite data_writes1[] = {
10343 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10344 "Host: www.google.com\r\n"
10345 "Proxy-Connection: keep-alive\r\n\r\n"),
10346 };
10347
10348 MockRead data_reads1[] = {
10349 MockRead("HTTP/1.1 200 OK\r\n"),
10350 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10351 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610352 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010353 };
10354
10355 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10356 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710357 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010358
[email protected]49639fa2011-12-20 23:22:4110359 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010360
[email protected]262eec82013-03-19 21:01:3610361 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010362 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710363 BeforeProxyHeadersSentHandler proxy_headers_handler;
10364 trans->SetBeforeProxyHeadersSentCallback(
10365 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10366 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010367
[email protected]49639fa2011-12-20 23:22:4110368 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010369 EXPECT_EQ(ERR_IO_PENDING, rv);
10370
10371 rv = callback1.WaitForResult();
10372 EXPECT_EQ(OK, rv);
10373
10374 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010375 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010376
10377 EXPECT_TRUE(response->headers->IsKeepAlive());
10378 EXPECT_EQ(200, response->headers->response_code());
10379 EXPECT_EQ(100, response->headers->GetContentLength());
10380 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510381 EXPECT_TRUE(
10382 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710383 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10384 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010385 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010386
10387 LoadTimingInfo load_timing_info;
10388 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10389 TestLoadTimingNotReusedWithPac(load_timing_info,
10390 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010391}
10392
10393// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210394TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710395 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010396 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910397 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710398 session_deps_.net_log = log.bound().net_log();
10399 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010400
[email protected]76a505b2010-08-25 06:23:0010401 HttpRequestInfo request;
10402 request.method = "GET";
10403 request.url = GURL("https://www.google.com/");
10404
10405 // Since we have proxy, should try to establish tunnel.
10406 MockWrite data_writes1[] = {
10407 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10408 "Host: www.google.com\r\n"
10409 "Proxy-Connection: keep-alive\r\n\r\n"),
10410
10411 MockWrite("GET / HTTP/1.1\r\n"
10412 "Host: www.google.com\r\n"
10413 "Connection: keep-alive\r\n\r\n"),
10414 };
10415
10416 MockRead data_reads1[] = {
10417 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10418
10419 MockRead("HTTP/1.1 200 OK\r\n"),
10420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10421 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610422 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010423 };
10424
10425 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10426 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610428 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010430
[email protected]49639fa2011-12-20 23:22:4110431 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010432
[email protected]262eec82013-03-19 21:01:3610433 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010435
[email protected]49639fa2011-12-20 23:22:4110436 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010437 EXPECT_EQ(ERR_IO_PENDING, rv);
10438
10439 rv = callback1.WaitForResult();
10440 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710441 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010442 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010443 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010444 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010445 NetLog::PHASE_NONE);
10446 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010447 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010448 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10449 NetLog::PHASE_NONE);
10450
10451 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010452 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010453
10454 EXPECT_TRUE(response->headers->IsKeepAlive());
10455 EXPECT_EQ(200, response->headers->response_code());
10456 EXPECT_EQ(100, response->headers->GetContentLength());
10457 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10458 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510459 EXPECT_TRUE(
10460 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010461
10462 LoadTimingInfo load_timing_info;
10463 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10464 TestLoadTimingNotReusedWithPac(load_timing_info,
10465 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010466}
10467
10468// Test a basic HTTPS GET request through a proxy, but the server hangs up
10469// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210470TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710471 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910472 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710473 session_deps_.net_log = log.bound().net_log();
10474 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010475
[email protected]76a505b2010-08-25 06:23:0010476 HttpRequestInfo request;
10477 request.method = "GET";
10478 request.url = GURL("https://www.google.com/");
10479
10480 // Since we have proxy, should try to establish tunnel.
10481 MockWrite data_writes1[] = {
10482 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10483 "Host: www.google.com\r\n"
10484 "Proxy-Connection: keep-alive\r\n\r\n"),
10485
10486 MockWrite("GET / HTTP/1.1\r\n"
10487 "Host: www.google.com\r\n"
10488 "Connection: keep-alive\r\n\r\n"),
10489 };
10490
10491 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610492 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010493 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610494 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010495 };
10496
10497 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10498 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710499 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610500 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010502
[email protected]49639fa2011-12-20 23:22:4110503 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010504
[email protected]262eec82013-03-19 21:01:3610505 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010506 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010507
[email protected]49639fa2011-12-20 23:22:4110508 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010509 EXPECT_EQ(ERR_IO_PENDING, rv);
10510
10511 rv = callback1.WaitForResult();
10512 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710513 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010514 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010515 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010516 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010517 NetLog::PHASE_NONE);
10518 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010519 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010520 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10521 NetLog::PHASE_NONE);
10522}
10523
[email protected]749eefa82010-09-13 22:14:0310524// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210525TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610526 scoped_ptr<SpdyFrame> req(
10527 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310528 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10529
[email protected]23e482282013-06-14 16:08:0210530 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10531 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310532 MockRead spdy_reads[] = {
10533 CreateMockRead(*resp),
10534 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610535 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310536 };
10537
[email protected]dd54bd82012-07-19 23:44:5710538 DelayedSocketData spdy_data(
10539 1, // wait for one write to finish before reading.
10540 spdy_reads, arraysize(spdy_reads),
10541 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710542 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310543
[email protected]8ddf8322012-02-23 18:08:0610544 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210545 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710546 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310547
[email protected]bb88e1d32013-05-03 23:11:0710548 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310549
10550 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810551 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010552 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310553 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710554 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610555 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310556
10557 HttpRequestInfo request;
10558 request.method = "GET";
10559 request.url = GURL("https://www.google.com/");
10560 request.load_flags = 0;
10561
10562 // This is the important line that marks this as a preconnect.
10563 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10564
[email protected]262eec82013-03-19 21:01:3610565 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010566 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310567
[email protected]41d64e82013-07-03 22:44:2610568 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110569 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310570 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110571 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310572}
10573
[email protected]73b8dd222010-11-11 19:55:2410574// Given a net error, cause that error to be returned from the first Write()
10575// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210576void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710577 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710578 net::HttpRequestInfo request_info;
10579 request_info.url = GURL("https://www.example.com/");
10580 request_info.method = "GET";
10581 request_info.load_flags = net::LOAD_NORMAL;
10582
[email protected]8ddf8322012-02-23 18:08:0610583 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410584 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610585 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410586 };
10587 net::StaticSocketDataProvider data(NULL, 0,
10588 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710589 session_deps_.socket_factory->AddSocketDataProvider(&data);
10590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410591
[email protected]bb88e1d32013-05-03 23:11:0710592 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610593 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010594 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410595
[email protected]49639fa2011-12-20 23:22:4110596 TestCompletionCallback callback;
10597 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410598 if (rv == net::ERR_IO_PENDING)
10599 rv = callback.WaitForResult();
10600 ASSERT_EQ(error, rv);
10601}
10602
[email protected]23e482282013-06-14 16:08:0210603TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410604 // Just check a grab bag of cert errors.
10605 static const int kErrors[] = {
10606 ERR_CERT_COMMON_NAME_INVALID,
10607 ERR_CERT_AUTHORITY_INVALID,
10608 ERR_CERT_DATE_INVALID,
10609 };
10610 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610611 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10612 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410613 }
10614}
10615
[email protected]bd0b6772011-01-11 19:59:3010616// Ensure that a client certificate is removed from the SSL client auth
10617// cache when:
10618// 1) No proxy is involved.
10619// 2) TLS False Start is disabled.
10620// 3) The initial TLS handshake requests a client certificate.
10621// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210622TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310623 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710624 net::HttpRequestInfo request_info;
10625 request_info.url = GURL("https://www.example.com/");
10626 request_info.method = "GET";
10627 request_info.load_flags = net::LOAD_NORMAL;
10628
[email protected]bd0b6772011-01-11 19:59:3010629 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110630 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010631
10632 // [ssl_]data1 contains the data for the first SSL handshake. When a
10633 // CertificateRequest is received for the first time, the handshake will
10634 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610635 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010636 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710637 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010638 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710639 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010640
10641 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10642 // False Start is not being used, the result of the SSL handshake will be
10643 // returned as part of the SSLClientSocket::Connect() call. This test
10644 // matches the result of a server sending a handshake_failure alert,
10645 // rather than a Finished message, because it requires a client
10646 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610647 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010648 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710649 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010650 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710651 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010652
10653 // [ssl_]data3 contains the data for the third SSL handshake. When a
10654 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710655 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10656 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010657 // of the HttpNetworkTransaction. Because this test failure is due to
10658 // requiring a client certificate, this fallback handshake should also
10659 // fail.
[email protected]8ddf8322012-02-23 18:08:0610660 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010661 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710662 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010663 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710664 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010665
[email protected]80c75f682012-05-26 16:22:1710666 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10667 // connection to a server fails during an SSL handshake,
10668 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10669 // connection was attempted with TLSv1. This is transparent to the caller
10670 // of the HttpNetworkTransaction. Because this test failure is due to
10671 // requiring a client certificate, this fallback handshake should also
10672 // fail.
10673 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10674 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710676 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710677 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710678
[email protected]7799de12013-05-30 05:52:5110679 // Need one more if TLSv1.2 is enabled.
10680 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10681 ssl_data5.cert_request_info = cert_request.get();
10682 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10683 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10684 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10685
[email protected]bb88e1d32013-05-03 23:11:0710686 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610687 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010689
[email protected]bd0b6772011-01-11 19:59:3010690 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110691 TestCompletionCallback callback;
10692 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010693 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10694
10695 // Complete the SSL handshake, which should abort due to requiring a
10696 // client certificate.
10697 rv = callback.WaitForResult();
10698 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10699
10700 // Indicate that no certificate should be supplied. From the perspective
10701 // of SSLClientCertCache, NULL is just as meaningful as a real
10702 // certificate, so this is the same as supply a
10703 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110704 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010705 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10706
10707 // Ensure the certificate was added to the client auth cache before
10708 // allowing the connection to continue restarting.
10709 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110710 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10711 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010712 ASSERT_EQ(NULL, client_cert.get());
10713
10714 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710715 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10716 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010717 rv = callback.WaitForResult();
10718 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10719
10720 // Ensure that the client certificate is removed from the cache on a
10721 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110722 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10723 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010724}
10725
10726// Ensure that a client certificate is removed from the SSL client auth
10727// cache when:
10728// 1) No proxy is involved.
10729// 2) TLS False Start is enabled.
10730// 3) The initial TLS handshake requests a client certificate.
10731// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210732TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310733 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710734 net::HttpRequestInfo request_info;
10735 request_info.url = GURL("https://www.example.com/");
10736 request_info.method = "GET";
10737 request_info.load_flags = net::LOAD_NORMAL;
10738
[email protected]bd0b6772011-01-11 19:59:3010739 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110740 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010741
10742 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10743 // return successfully after reading up to the peer's Certificate message.
10744 // This is to allow the caller to call SSLClientSocket::Write(), which can
10745 // enqueue application data to be sent in the same packet as the
10746 // ChangeCipherSpec and Finished messages.
10747 // The actual handshake will be finished when SSLClientSocket::Read() is
10748 // called, which expects to process the peer's ChangeCipherSpec and
10749 // Finished messages. If there was an error negotiating with the peer,
10750 // such as due to the peer requiring a client certificate when none was
10751 // supplied, the alert sent by the peer won't be processed until Read() is
10752 // called.
10753
10754 // Like the non-False Start case, when a client certificate is requested by
10755 // the peer, the handshake is aborted during the Connect() call.
10756 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610757 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010758 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010760 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710761 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010762
10763 // When a client certificate is supplied, Connect() will not be aborted
10764 // when the peer requests the certificate. Instead, the handshake will
10765 // artificially succeed, allowing the caller to write the HTTP request to
10766 // the socket. The handshake messages are not processed until Read() is
10767 // called, which then detects that the handshake was aborted, due to the
10768 // peer sending a handshake_failure because it requires a client
10769 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610770 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010771 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710772 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010773 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610774 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010775 };
10776 net::StaticSocketDataProvider data2(
10777 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710778 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010779
10780 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710781 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10782 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610783 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010784 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710785 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010786 net::StaticSocketDataProvider data3(
10787 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710788 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010789
[email protected]80c75f682012-05-26 16:22:1710790 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10791 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10792 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10793 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710794 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710795 net::StaticSocketDataProvider data4(
10796 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710797 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710798
[email protected]7799de12013-05-30 05:52:5110799 // Need one more if TLSv1.2 is enabled.
10800 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10801 ssl_data5.cert_request_info = cert_request.get();
10802 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10803 net::StaticSocketDataProvider data5(
10804 data2_reads, arraysize(data2_reads), NULL, 0);
10805 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10806
[email protected]bb88e1d32013-05-03 23:11:0710807 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610808 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010810
[email protected]bd0b6772011-01-11 19:59:3010811 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110812 TestCompletionCallback callback;
10813 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010814 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10815
10816 // Complete the SSL handshake, which should abort due to requiring a
10817 // client certificate.
10818 rv = callback.WaitForResult();
10819 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10820
10821 // Indicate that no certificate should be supplied. From the perspective
10822 // of SSLClientCertCache, NULL is just as meaningful as a real
10823 // certificate, so this is the same as supply a
10824 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110825 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010826 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10827
10828 // Ensure the certificate was added to the client auth cache before
10829 // allowing the connection to continue restarting.
10830 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110831 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10832 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010833 ASSERT_EQ(NULL, client_cert.get());
10834
[email protected]bd0b6772011-01-11 19:59:3010835 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710836 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10837 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010838 rv = callback.WaitForResult();
10839 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10840
10841 // Ensure that the client certificate is removed from the cache on a
10842 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110843 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10844 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010845}
10846
[email protected]8c405132011-01-11 22:03:1810847// Ensure that a client certificate is removed from the SSL client auth
10848// cache when:
10849// 1) An HTTPS proxy is involved.
10850// 3) The HTTPS proxy requests a client certificate.
10851// 4) The client supplies an invalid/unacceptable certificate for the
10852// proxy.
10853// The test is repeated twice, first for connecting to an HTTPS endpoint,
10854// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210855TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710856 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810857 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910858 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710859 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810860
10861 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110862 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1810863
10864 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10865 // [ssl_]data[1-3]. Rather than represending the endpoint
10866 // (www.example.com:443), they represent failures with the HTTPS proxy
10867 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610868 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810869 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810871 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810873
[email protected]8ddf8322012-02-23 18:08:0610874 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810875 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710876 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810877 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710878 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810879
[email protected]80c75f682012-05-26 16:22:1710880 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10881#if 0
[email protected]8ddf8322012-02-23 18:08:0610882 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810883 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710884 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810885 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710886 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710887#endif
[email protected]8c405132011-01-11 22:03:1810888
10889 net::HttpRequestInfo requests[2];
10890 requests[0].url = GURL("https://www.example.com/");
10891 requests[0].method = "GET";
10892 requests[0].load_flags = net::LOAD_NORMAL;
10893
10894 requests[1].url = GURL("http://www.example.com/");
10895 requests[1].method = "GET";
10896 requests[1].load_flags = net::LOAD_NORMAL;
10897
10898 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710899 session_deps_.socket_factory->ResetNextMockIndexes();
10900 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810901 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010902 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810903
10904 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110905 TestCompletionCallback callback;
10906 int rv = trans->Start(
10907 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810908 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10909
10910 // Complete the SSL handshake, which should abort due to requiring a
10911 // client certificate.
10912 rv = callback.WaitForResult();
10913 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10914
10915 // Indicate that no certificate should be supplied. From the perspective
10916 // of SSLClientCertCache, NULL is just as meaningful as a real
10917 // certificate, so this is the same as supply a
10918 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110919 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810920 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10921
10922 // Ensure the certificate was added to the client auth cache before
10923 // allowing the connection to continue restarting.
10924 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110925 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10926 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1810927 ASSERT_EQ(NULL, client_cert.get());
10928 // Ensure the certificate was NOT cached for the endpoint. This only
10929 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4110930 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10931 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810932
10933 // Restart the handshake. This will consume ssl_data2, which fails, and
10934 // then consume ssl_data3, which should also fail. The result code is
10935 // checked against what ssl_data3 should return.
10936 rv = callback.WaitForResult();
10937 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10938
10939 // Now that the new handshake has failed, ensure that the client
10940 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4110941 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10942 HostPortPair("proxy", 70), &client_cert));
10943 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10944 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810945 }
10946}
10947
[email protected]23e482282013-06-14 16:08:0210948// Unlike TEST/TEST_F, which are macros that expand to further macros,
10949// TEST_P is a macro that expands directly to code that stringizes the
10950// arguments. As a result, macros passed as parameters (such as prefix
10951// or test_case_name) will not be expanded by the preprocessor. To
10952// work around this, indirect the macro for TEST_P, so that the
10953// pre-processor will expand macros such as MAYBE_test_name before
10954// instantiating the test.
10955#define WRAPPED_TEST_P(test_case_name, test_name) \
10956 TEST_P(test_case_name, test_name)
10957
[email protected]45b170822012-05-04 21:18:1410958// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10959#if defined(OS_WIN)
10960#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10961#else
10962#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10963#endif
[email protected]23e482282013-06-14 16:08:0210964WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2310965 session_deps_.use_alternate_protocols = true;
10966 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4610967
10968 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710969 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10970 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610971 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10972 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610973
[email protected]8ddf8322012-02-23 18:08:0610974 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210975 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710976 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610977
[email protected]cdf8f7e72013-05-23 10:56:4610978 scoped_ptr<SpdyFrame> host1_req(
10979 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10980 scoped_ptr<SpdyFrame> host2_req(
10981 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610982 MockWrite spdy_writes[] = {
10983 CreateMockWrite(*host1_req, 1),
10984 CreateMockWrite(*host2_req, 4),
10985 };
[email protected]23e482282013-06-14 16:08:0210986 scoped_ptr<SpdyFrame> host1_resp(
10987 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10988 scoped_ptr<SpdyFrame> host1_resp_body(
10989 spdy_util_.ConstructSpdyBodyFrame(1, true));
10990 scoped_ptr<SpdyFrame> host2_resp(
10991 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10992 scoped_ptr<SpdyFrame> host2_resp_body(
10993 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610994 MockRead spdy_reads[] = {
10995 CreateMockRead(*host1_resp, 2),
10996 CreateMockRead(*host1_resp_body, 3),
10997 CreateMockRead(*host2_resp, 5),
10998 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610999 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611000 };
11001
[email protected]d2b5f092012-06-08 23:55:0211002 IPAddressNumber ip;
11003 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11004 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11005 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711006 OrderedSocketData spdy_data(
11007 connect,
11008 spdy_reads, arraysize(spdy_reads),
11009 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711010 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611011
[email protected]aa22b242011-11-16 18:58:2911012 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611013 HttpRequestInfo request1;
11014 request1.method = "GET";
11015 request1.url = GURL("https://www.google.com/");
11016 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011017 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611018
[email protected]49639fa2011-12-20 23:22:4111019 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611020 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111021 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611022
11023 const HttpResponseInfo* response = trans1.GetResponseInfo();
11024 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011025 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611026 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11027
11028 std::string response_data;
11029 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11030 EXPECT_EQ("hello!", response_data);
11031
11032 // Preload www.gmail.com into HostCache.
11033 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011034 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611035 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011036 rv = session_deps_.host_resolver->Resolve(resolve_info,
11037 DEFAULT_PRIORITY,
11038 &ignored,
11039 callback.callback(),
11040 NULL,
11041 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711042 EXPECT_EQ(ERR_IO_PENDING, rv);
11043 rv = callback.WaitForResult();
11044 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611045
11046 HttpRequestInfo request2;
11047 request2.method = "GET";
11048 request2.url = GURL("https://www.gmail.com/");
11049 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011050 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611051
[email protected]49639fa2011-12-20 23:22:4111052 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611053 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111054 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611055
11056 response = trans2.GetResponseInfo();
11057 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011058 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611059 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11060 EXPECT_TRUE(response->was_fetched_via_spdy);
11061 EXPECT_TRUE(response->was_npn_negotiated);
11062 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11063 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611064}
[email protected]45b170822012-05-04 21:18:1411065#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4611066
[email protected]23e482282013-06-14 16:08:0211067TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311068 session_deps_.use_alternate_protocols = true;
11069 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211070
11071 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711072 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11073 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211074 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11075 pool_peer.DisableDomainAuthenticationVerification();
11076
11077 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211078 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211080
[email protected]cdf8f7e72013-05-23 10:56:4611081 scoped_ptr<SpdyFrame> host1_req(
11082 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11083 scoped_ptr<SpdyFrame> host2_req(
11084 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211085 MockWrite spdy_writes[] = {
11086 CreateMockWrite(*host1_req, 1),
11087 CreateMockWrite(*host2_req, 4),
11088 };
[email protected]23e482282013-06-14 16:08:0211089 scoped_ptr<SpdyFrame> host1_resp(
11090 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11091 scoped_ptr<SpdyFrame> host1_resp_body(
11092 spdy_util_.ConstructSpdyBodyFrame(1, true));
11093 scoped_ptr<SpdyFrame> host2_resp(
11094 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11095 scoped_ptr<SpdyFrame> host2_resp_body(
11096 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211097 MockRead spdy_reads[] = {
11098 CreateMockRead(*host1_resp, 2),
11099 CreateMockRead(*host1_resp_body, 3),
11100 CreateMockRead(*host2_resp, 5),
11101 CreateMockRead(*host2_resp_body, 6),
11102 MockRead(ASYNC, 0, 7),
11103 };
11104
11105 IPAddressNumber ip;
11106 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11107 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11108 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711109 OrderedSocketData spdy_data(
11110 connect,
11111 spdy_reads, arraysize(spdy_reads),
11112 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711113 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211114
11115 TestCompletionCallback callback;
11116 HttpRequestInfo request1;
11117 request1.method = "GET";
11118 request1.url = GURL("https://www.google.com/");
11119 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011120 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211121
11122 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11123 EXPECT_EQ(ERR_IO_PENDING, rv);
11124 EXPECT_EQ(OK, callback.WaitForResult());
11125
11126 const HttpResponseInfo* response = trans1.GetResponseInfo();
11127 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011128 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211129 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11130
11131 std::string response_data;
11132 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11133 EXPECT_EQ("hello!", response_data);
11134
11135 HttpRequestInfo request2;
11136 request2.method = "GET";
11137 request2.url = GURL("https://www.gmail.com/");
11138 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011139 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211140
11141 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11142 EXPECT_EQ(ERR_IO_PENDING, rv);
11143 EXPECT_EQ(OK, callback.WaitForResult());
11144
11145 response = trans2.GetResponseInfo();
11146 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011147 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211148 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11149 EXPECT_TRUE(response->was_fetched_via_spdy);
11150 EXPECT_TRUE(response->was_npn_negotiated);
11151 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11152 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211153}
11154
[email protected]e3ceb682011-06-28 23:55:4611155class OneTimeCachingHostResolver : public net::HostResolver {
11156 public:
11157 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11158 : host_port_(host_port) {}
11159 virtual ~OneTimeCachingHostResolver() {}
11160
11161 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11162
11163 // HostResolver methods:
11164 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1011165 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4611166 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2911167 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4611168 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4011169 const BoundNetLog& net_log) OVERRIDE {
11170 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011171 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011172 }
11173
11174 virtual int ResolveFromCache(const RequestInfo& info,
11175 AddressList* addresses,
11176 const BoundNetLog& net_log) OVERRIDE {
11177 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11178 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911179 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611180 return rv;
11181 }
11182
[email protected]95a214c2011-08-04 21:50:4011183 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4611184 host_resolver_.CancelRequest(req);
11185 }
11186
[email protected]46da33be2011-07-19 21:58:0411187 MockCachingHostResolver* GetMockHostResolver() {
11188 return &host_resolver_;
11189 }
11190
[email protected]e3ceb682011-06-28 23:55:4611191 private:
11192 MockCachingHostResolver host_resolver_;
11193 const HostPortPair host_port_;
11194};
11195
[email protected]45b170822012-05-04 21:18:1411196// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11197#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711198#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11199 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411200#else
[email protected]bb88e1d32013-05-03 23:11:0711201#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11202 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411203#endif
[email protected]23e482282013-06-14 16:08:0211204WRAPPED_TEST_P(HttpNetworkTransactionTest,
11205 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211206// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11207// prefix doesn't work with parametrized tests).
11208#if defined(OS_WIN)
11209 return;
[email protected]88c7b4be2014-03-19 23:04:0111210#else
[email protected]d7599122014-05-24 03:37:2311211 session_deps_.use_alternate_protocols = true;
11212 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611213
11214 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611215 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411216 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711217 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611218 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711219 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611220 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11221 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611222
[email protected]8ddf8322012-02-23 18:08:0611223 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211224 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711225 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611226
[email protected]cdf8f7e72013-05-23 10:56:4611227 scoped_ptr<SpdyFrame> host1_req(
11228 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11229 scoped_ptr<SpdyFrame> host2_req(
11230 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611231 MockWrite spdy_writes[] = {
11232 CreateMockWrite(*host1_req, 1),
11233 CreateMockWrite(*host2_req, 4),
11234 };
[email protected]23e482282013-06-14 16:08:0211235 scoped_ptr<SpdyFrame> host1_resp(
11236 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11237 scoped_ptr<SpdyFrame> host1_resp_body(
11238 spdy_util_.ConstructSpdyBodyFrame(1, true));
11239 scoped_ptr<SpdyFrame> host2_resp(
11240 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11241 scoped_ptr<SpdyFrame> host2_resp_body(
11242 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611243 MockRead spdy_reads[] = {
11244 CreateMockRead(*host1_resp, 2),
11245 CreateMockRead(*host1_resp_body, 3),
11246 CreateMockRead(*host2_resp, 5),
11247 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611248 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611249 };
11250
[email protected]d2b5f092012-06-08 23:55:0211251 IPAddressNumber ip;
11252 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11253 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11254 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711255 OrderedSocketData spdy_data(
11256 connect,
11257 spdy_reads, arraysize(spdy_reads),
11258 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711259 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611260
[email protected]aa22b242011-11-16 18:58:2911261 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611262 HttpRequestInfo request1;
11263 request1.method = "GET";
11264 request1.url = GURL("https://www.google.com/");
11265 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011266 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611267
[email protected]49639fa2011-12-20 23:22:4111268 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611269 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111270 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611271
11272 const HttpResponseInfo* response = trans1.GetResponseInfo();
11273 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011274 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611275 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11276
11277 std::string response_data;
11278 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11279 EXPECT_EQ("hello!", response_data);
11280
11281 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011282 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611283 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011284 rv = host_resolver.Resolve(resolve_info,
11285 DEFAULT_PRIORITY,
11286 &ignored,
11287 callback.callback(),
11288 NULL,
11289 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711290 EXPECT_EQ(ERR_IO_PENDING, rv);
11291 rv = callback.WaitForResult();
11292 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611293
11294 HttpRequestInfo request2;
11295 request2.method = "GET";
11296 request2.url = GURL("https://www.gmail.com/");
11297 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011298 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611299
[email protected]49639fa2011-12-20 23:22:4111300 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611301 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111302 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611303
11304 response = trans2.GetResponseInfo();
11305 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011306 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611307 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11308 EXPECT_TRUE(response->was_fetched_via_spdy);
11309 EXPECT_TRUE(response->was_npn_negotiated);
11310 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11311 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111312#endif
[email protected]e3ceb682011-06-28 23:55:4611313}
[email protected]45b170822012-05-04 21:18:1411314#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611315
[email protected]23e482282013-06-14 16:08:0211316TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0411317 const std::string https_url = "https://www.google.com/";
11318 const std::string http_url = "http://www.google.com:443/";
11319
11320 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611321 scoped_ptr<SpdyFrame> req1(
11322 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411323
11324 MockWrite writes1[] = {
11325 CreateMockWrite(*req1, 0),
11326 };
11327
[email protected]23e482282013-06-14 16:08:0211328 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11329 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411330 MockRead reads1[] = {
11331 CreateMockRead(*resp1, 1),
11332 CreateMockRead(*body1, 2),
11333 MockRead(ASYNC, ERR_IO_PENDING, 3)
11334 };
11335
[email protected]dd54bd82012-07-19 23:44:5711336 DelayedSocketData data1(
11337 1, reads1, arraysize(reads1),
11338 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411339 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711340 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411341
11342 // HTTP GET for the HTTP URL
11343 MockWrite writes2[] = {
11344 MockWrite(ASYNC, 4,
11345 "GET / HTTP/1.1\r\n"
11346 "Host: www.google.com:443\r\n"
11347 "Connection: keep-alive\r\n\r\n"),
11348 };
11349
11350 MockRead reads2[] = {
11351 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11352 MockRead(ASYNC, 6, "hello"),
11353 MockRead(ASYNC, 7, OK),
11354 };
11355
[email protected]dd54bd82012-07-19 23:44:5711356 DelayedSocketData data2(
11357 1, reads2, arraysize(reads2),
11358 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411359
[email protected]8450d722012-07-02 19:14:0411360 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211361 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11363 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11364 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411365
[email protected]bb88e1d32013-05-03 23:11:0711366 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411367
11368 // Start the first transaction to set up the SpdySession
11369 HttpRequestInfo request1;
11370 request1.method = "GET";
11371 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411372 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011373 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411374 TestCompletionCallback callback1;
11375 EXPECT_EQ(ERR_IO_PENDING,
11376 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411377 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411378
11379 EXPECT_EQ(OK, callback1.WaitForResult());
11380 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11381
11382 // Now, start the HTTP request
11383 HttpRequestInfo request2;
11384 request2.method = "GET";
11385 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411386 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011387 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411388 TestCompletionCallback callback2;
11389 EXPECT_EQ(ERR_IO_PENDING,
11390 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411391 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411392
11393 EXPECT_EQ(OK, callback2.WaitForResult());
11394 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11395}
11396
[email protected]23e482282013-06-14 16:08:0211397TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0411398 const std::string https_url = "https://www.google.com/";
11399 const std::string http_url = "http://www.google.com:443/";
11400
11401 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5411402 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11403 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611404 scoped_ptr<SpdyFrame> req1(
11405 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0211406 scoped_ptr<SpdyFrame> wrapped_req1(
11407 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3911408
11409 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2911410 SpdyHeaderBlock req2_block;
11411 req2_block[spdy_util_.GetMethodKey()] = "GET";
11412 req2_block[spdy_util_.GetPathKey()] =
11413 spdy_util_.is_spdy2() ? http_url.c_str() : "/";
11414 req2_block[spdy_util_.GetHostKey()] = "www.google.com:443";
11415 req2_block[spdy_util_.GetSchemeKey()] = "http";
11416 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3911417 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2911418 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0411419
11420 MockWrite writes1[] = {
11421 CreateMockWrite(*connect, 0),
11422 CreateMockWrite(*wrapped_req1, 2),
11423 CreateMockWrite(*req2, 5),
11424 };
11425
[email protected]23e482282013-06-14 16:08:0211426 scoped_ptr<SpdyFrame> conn_resp(
11427 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11428 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11429 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11430 scoped_ptr<SpdyFrame> wrapped_resp1(
11431 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11432 scoped_ptr<SpdyFrame> wrapped_body1(
11433 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11434 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11435 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411436 MockRead reads1[] = {
11437 CreateMockRead(*conn_resp, 1),
11438 CreateMockRead(*wrapped_resp1, 3),
11439 CreateMockRead(*wrapped_body1, 4),
11440 CreateMockRead(*resp2, 6),
11441 CreateMockRead(*body2, 7),
11442 MockRead(ASYNC, ERR_IO_PENDING, 8)
11443 };
11444
[email protected]dd54bd82012-07-19 23:44:5711445 DeterministicSocketData data1(reads1, arraysize(reads1),
11446 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411447 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711448 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411449
[email protected]bb88e1d32013-05-03 23:11:0711450 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211451 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11452 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711453 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411454 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211455 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711456 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411457 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211458 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711459 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11460 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411461
11462 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711463 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411464
11465 // Start the first transaction to set up the SpdySession
11466 HttpRequestInfo request1;
11467 request1.method = "GET";
11468 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411469 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011470 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411471 TestCompletionCallback callback1;
11472 EXPECT_EQ(ERR_IO_PENDING,
11473 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411474 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711475 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411476
11477 EXPECT_EQ(OK, callback1.WaitForResult());
11478 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11479
[email protected]f6c63db52013-02-02 00:35:2211480 LoadTimingInfo load_timing_info1;
11481 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11482 TestLoadTimingNotReusedWithPac(load_timing_info1,
11483 CONNECT_TIMING_HAS_SSL_TIMES);
11484
[email protected]8450d722012-07-02 19:14:0411485 // Now, start the HTTP request
11486 HttpRequestInfo request2;
11487 request2.method = "GET";
11488 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411489 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011490 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411491 TestCompletionCallback callback2;
11492 EXPECT_EQ(ERR_IO_PENDING,
11493 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411494 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711495 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411496
11497 EXPECT_EQ(OK, callback2.WaitForResult());
11498 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211499
11500 LoadTimingInfo load_timing_info2;
11501 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11502 // The established SPDY sessions is considered reused by the HTTP request.
11503 TestLoadTimingReusedWithPac(load_timing_info2);
11504 // HTTP requests over a SPDY session should have a different connection
11505 // socket_log_id than requests over a tunnel.
11506 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411507}
11508
[email protected]23e482282013-06-14 16:08:0211509TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]d7599122014-05-24 03:37:2311510 session_deps_.force_spdy_always = true;
[email protected]8450d722012-07-02 19:14:0411511 const std::string https_url = "https://www.google.com/";
11512 const std::string http_url = "http://www.google.com:443/";
11513
11514 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611515 scoped_ptr<SpdyFrame> req1(
11516 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411517 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611518 scoped_ptr<SpdyFrame> req2(
11519 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411520
11521 MockWrite writes[] = {
11522 CreateMockWrite(*req1, 1),
11523 CreateMockWrite(*req2, 4),
11524 };
11525
[email protected]23e482282013-06-14 16:08:0211526 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11527 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11528 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11529 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411530 MockRead reads[] = {
11531 CreateMockRead(*resp1, 2),
11532 CreateMockRead(*body1, 3),
11533 CreateMockRead(*resp2, 5),
11534 CreateMockRead(*body2, 6),
11535 MockRead(ASYNC, ERR_IO_PENDING, 7)
11536 };
11537
[email protected]dd54bd82012-07-19 23:44:5711538 OrderedSocketData data(reads, arraysize(reads),
11539 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411540
[email protected]8450d722012-07-02 19:14:0411541 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211542 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711543 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11544 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411545
[email protected]bb88e1d32013-05-03 23:11:0711546 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411547
11548 // Start the first transaction to set up the SpdySession
11549 HttpRequestInfo request1;
11550 request1.method = "GET";
11551 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411552 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011553 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411554 TestCompletionCallback callback1;
11555 EXPECT_EQ(ERR_IO_PENDING,
11556 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411557 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411558
11559 EXPECT_EQ(OK, callback1.WaitForResult());
11560 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11561
11562 // Now, start the HTTP request
11563 HttpRequestInfo request2;
11564 request2.method = "GET";
11565 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411566 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011567 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411568 TestCompletionCallback callback2;
11569 EXPECT_EQ(ERR_IO_PENDING,
11570 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411571 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411572
11573 EXPECT_EQ(OK, callback2.WaitForResult());
11574 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11575}
11576
[email protected]2d88e7d2012-07-19 17:55:1711577// Test that in the case where we have a SPDY session to a SPDY proxy
11578// that we do not pool other origins that resolve to the same IP when
11579// the certificate does not match the new origin.
11580// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211581TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711582 const std::string url1 = "http://www.google.com/";
11583 const std::string url2 = "https://mail.google.com/";
11584 const std::string ip_addr = "1.2.3.4";
11585
11586 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211587 scoped_ptr<SpdyHeaderBlock> headers(
11588 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:2911589 scoped_ptr<SpdyFrame> req1(
11590 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1711591
11592 MockWrite writes1[] = {
11593 CreateMockWrite(*req1, 0),
11594 };
11595
[email protected]23e482282013-06-14 16:08:0211596 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11597 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711598 MockRead reads1[] = {
11599 CreateMockRead(*resp1, 1),
11600 CreateMockRead(*body1, 2),
11601 MockRead(ASYNC, OK, 3) // EOF
11602 };
11603
11604 scoped_ptr<DeterministicSocketData> data1(
11605 new DeterministicSocketData(reads1, arraysize(reads1),
11606 writes1, arraysize(writes1)));
11607 IPAddressNumber ip;
11608 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11609 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11610 MockConnect connect_data1(ASYNC, OK, peer_addr);
11611 data1->set_connect_data(connect_data1);
11612
11613 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611614 scoped_ptr<SpdyFrame> req2(
11615 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711616
11617 MockWrite writes2[] = {
11618 CreateMockWrite(*req2, 0),
11619 };
11620
[email protected]23e482282013-06-14 16:08:0211621 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11622 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711623 MockRead reads2[] = {
11624 CreateMockRead(*resp2, 1),
11625 CreateMockRead(*body2, 2),
11626 MockRead(ASYNC, OK, 3) // EOF
11627 };
11628
11629 scoped_ptr<DeterministicSocketData> data2(
11630 new DeterministicSocketData(reads2, arraysize(reads2),
11631 writes2, arraysize(writes2)));
11632 MockConnect connect_data2(ASYNC, OK);
11633 data2->set_connect_data(connect_data2);
11634
11635 // Set up a proxy config that sends HTTP requests to a proxy, and
11636 // all others direct.
11637 ProxyConfig proxy_config;
11638 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11639 CapturingProxyResolver* capturing_proxy_resolver =
11640 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711641 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711642 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11643 NULL));
11644
11645 // Load a valid cert. Note, that this does not need to
11646 // be valid for proxy because the MockSSLClientSocket does
11647 // not actually verify it. But SpdySession will use this
11648 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511649 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711650 scoped_refptr<X509Certificate> server_cert(
11651 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11652 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11653
11654 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211655 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711656 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711657 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11658 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11659 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711660
11661 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211662 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711663 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11664 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11665 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711666
[email protected]bb88e1d32013-05-03 23:11:0711667 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11668 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11669 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711670
11671 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711672 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711673
11674 // Start the first transaction to set up the SpdySession
11675 HttpRequestInfo request1;
11676 request1.method = "GET";
11677 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711678 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011679 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711680 TestCompletionCallback callback1;
11681 ASSERT_EQ(ERR_IO_PENDING,
11682 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11683 data1->RunFor(3);
11684
11685 ASSERT_TRUE(callback1.have_result());
11686 EXPECT_EQ(OK, callback1.WaitForResult());
11687 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11688
11689 // Now, start the HTTP request
11690 HttpRequestInfo request2;
11691 request2.method = "GET";
11692 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711693 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011694 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711695 TestCompletionCallback callback2;
11696 EXPECT_EQ(ERR_IO_PENDING,
11697 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411698 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711699 data2->RunFor(3);
11700
11701 ASSERT_TRUE(callback2.have_result());
11702 EXPECT_EQ(OK, callback2.WaitForResult());
11703 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11704}
11705
[email protected]85f97342013-04-17 06:12:2411706// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11707// error) in SPDY session, removes the socket from pool and closes the SPDY
11708// session. Verify that new url's from the same HttpNetworkSession (and a new
11709// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211710TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411711 const std::string https_url = "https://www.google.com/";
11712
11713 MockRead reads1[] = {
11714 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11715 };
11716
11717 scoped_ptr<DeterministicSocketData> data1(
11718 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11719 data1->SetStop(1);
11720
[email protected]cdf8f7e72013-05-23 10:56:4611721 scoped_ptr<SpdyFrame> req2(
11722 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411723 MockWrite writes2[] = {
11724 CreateMockWrite(*req2, 0),
11725 };
11726
[email protected]23e482282013-06-14 16:08:0211727 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11728 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411729 MockRead reads2[] = {
11730 CreateMockRead(*resp2, 1),
11731 CreateMockRead(*body2, 2),
11732 MockRead(ASYNC, OK, 3) // EOF
11733 };
11734
11735 scoped_ptr<DeterministicSocketData> data2(
11736 new DeterministicSocketData(reads2, arraysize(reads2),
11737 writes2, arraysize(writes2)));
11738
[email protected]85f97342013-04-17 06:12:2411739 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211740 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711741 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11742 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11743 data1.get());
[email protected]85f97342013-04-17 06:12:2411744
11745 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211746 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711747 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11748 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11749 data2.get());
[email protected]85f97342013-04-17 06:12:2411750
11751 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711752 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411753
11754 // Start the first transaction to set up the SpdySession and verify that
11755 // connection was closed.
11756 HttpRequestInfo request1;
11757 request1.method = "GET";
11758 request1.url = GURL(https_url);
11759 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011760 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411761 TestCompletionCallback callback1;
11762 EXPECT_EQ(ERR_IO_PENDING,
11763 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411764 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411765 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11766
11767 // Now, start the second request and make sure it succeeds.
11768 HttpRequestInfo request2;
11769 request2.method = "GET";
11770 request2.url = GURL(https_url);
11771 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011772 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411773 TestCompletionCallback callback2;
11774 EXPECT_EQ(ERR_IO_PENDING,
11775 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411776 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411777 data2->RunFor(3);
11778
11779 ASSERT_TRUE(callback2.have_result());
11780 EXPECT_EQ(OK, callback2.WaitForResult());
11781 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11782}
11783
[email protected]23e482282013-06-14 16:08:0211784TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2311785 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0311786 ClientSocketPoolManager::set_max_sockets_per_group(
11787 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11788 ClientSocketPoolManager::set_max_sockets_per_pool(
11789 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11790
11791 // Use two different hosts with different IPs so they don't get pooled.
11792 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11793 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11794 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11795
11796 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211797 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311798 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211799 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311800 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11802
[email protected]cdf8f7e72013-05-23 10:56:4611803 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311804 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11805 MockWrite spdy1_writes[] = {
11806 CreateMockWrite(*host1_req, 1),
11807 };
[email protected]23e482282013-06-14 16:08:0211808 scoped_ptr<SpdyFrame> host1_resp(
11809 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11810 scoped_ptr<SpdyFrame> host1_resp_body(
11811 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311812 MockRead spdy1_reads[] = {
11813 CreateMockRead(*host1_resp, 2),
11814 CreateMockRead(*host1_resp_body, 3),
11815 MockRead(ASYNC, ERR_IO_PENDING, 4),
11816 };
11817
11818 scoped_ptr<OrderedSocketData> spdy1_data(
11819 new OrderedSocketData(
11820 spdy1_reads, arraysize(spdy1_reads),
11821 spdy1_writes, arraysize(spdy1_writes)));
11822 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11823
[email protected]cdf8f7e72013-05-23 10:56:4611824 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311825 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11826 MockWrite spdy2_writes[] = {
11827 CreateMockWrite(*host2_req, 1),
11828 };
[email protected]23e482282013-06-14 16:08:0211829 scoped_ptr<SpdyFrame> host2_resp(
11830 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11831 scoped_ptr<SpdyFrame> host2_resp_body(
11832 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311833 MockRead spdy2_reads[] = {
11834 CreateMockRead(*host2_resp, 2),
11835 CreateMockRead(*host2_resp_body, 3),
11836 MockRead(ASYNC, ERR_IO_PENDING, 4),
11837 };
11838
11839 scoped_ptr<OrderedSocketData> spdy2_data(
11840 new OrderedSocketData(
11841 spdy2_reads, arraysize(spdy2_reads),
11842 spdy2_writes, arraysize(spdy2_writes)));
11843 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11844
11845 MockWrite http_write[] = {
11846 MockWrite("GET / HTTP/1.1\r\n"
11847 "Host: www.a.com\r\n"
11848 "Connection: keep-alive\r\n\r\n"),
11849 };
11850
11851 MockRead http_read[] = {
11852 MockRead("HTTP/1.1 200 OK\r\n"),
11853 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11854 MockRead("Content-Length: 6\r\n\r\n"),
11855 MockRead("hello!"),
11856 };
11857 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11858 http_write, arraysize(http_write));
11859 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11860
11861 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011862 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5311863 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311864 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611865 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311866
11867 TestCompletionCallback callback;
11868 HttpRequestInfo request1;
11869 request1.method = "GET";
11870 request1.url = GURL("https://www.a.com/");
11871 request1.load_flags = 0;
11872 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011873 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311874
11875 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11876 EXPECT_EQ(ERR_IO_PENDING, rv);
11877 EXPECT_EQ(OK, callback.WaitForResult());
11878
11879 const HttpResponseInfo* response = trans->GetResponseInfo();
11880 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011881 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311882 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11883 EXPECT_TRUE(response->was_fetched_via_spdy);
11884 EXPECT_TRUE(response->was_npn_negotiated);
11885
11886 std::string response_data;
11887 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11888 EXPECT_EQ("hello!", response_data);
11889 trans.reset();
11890 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611891 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311892
11893 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011894 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5311895 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311896 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611897 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311898 HttpRequestInfo request2;
11899 request2.method = "GET";
11900 request2.url = GURL("https://www.b.com/");
11901 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011902 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311903
11904 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11905 EXPECT_EQ(ERR_IO_PENDING, rv);
11906 EXPECT_EQ(OK, callback.WaitForResult());
11907
11908 response = trans->GetResponseInfo();
11909 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011910 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311911 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11912 EXPECT_TRUE(response->was_fetched_via_spdy);
11913 EXPECT_TRUE(response->was_npn_negotiated);
11914 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11915 EXPECT_EQ("hello!", response_data);
11916 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611917 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311918 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611919 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311920
11921 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011922 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5311923 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311924 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611925 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311926 HttpRequestInfo request3;
11927 request3.method = "GET";
11928 request3.url = GURL("http://www.a.com/");
11929 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011930 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311931
11932 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11933 EXPECT_EQ(ERR_IO_PENDING, rv);
11934 EXPECT_EQ(OK, callback.WaitForResult());
11935
11936 response = trans->GetResponseInfo();
11937 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011938 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311939 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11940 EXPECT_FALSE(response->was_fetched_via_spdy);
11941 EXPECT_FALSE(response->was_npn_negotiated);
11942 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11943 EXPECT_EQ("hello!", response_data);
11944 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611945 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311946 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611947 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311948}
11949
[email protected]79e1fd62013-06-20 06:50:0411950TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11951 HttpRequestInfo request;
11952 request.method = "GET";
11953 request.url = GURL("http://www.google.com/");
11954 request.load_flags = 0;
11955
[email protected]3fe8d2f82013-10-17 08:56:0711956 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411957 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711958 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411959
11960 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11961 StaticSocketDataProvider data;
11962 data.set_connect_data(mock_connect);
11963 session_deps_.socket_factory->AddSocketDataProvider(&data);
11964
11965 TestCompletionCallback callback;
11966
11967 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11968 EXPECT_EQ(ERR_IO_PENDING, rv);
11969
11970 rv = callback.WaitForResult();
11971 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11972
11973 EXPECT_EQ(NULL, trans->GetResponseInfo());
11974
11975 // We don't care whether this succeeds or fails, but it shouldn't crash.
11976 HttpRequestHeaders request_headers;
11977 trans->GetFullRequestHeaders(&request_headers);
11978}
11979
11980TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11981 HttpRequestInfo request;
11982 request.method = "GET";
11983 request.url = GURL("http://www.google.com/");
11984 request.load_flags = 0;
11985
[email protected]3fe8d2f82013-10-17 08:56:0711986 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411987 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711988 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411989
11990 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11991 StaticSocketDataProvider data;
11992 data.set_connect_data(mock_connect);
11993 session_deps_.socket_factory->AddSocketDataProvider(&data);
11994
11995 TestCompletionCallback callback;
11996
11997 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11998 EXPECT_EQ(ERR_IO_PENDING, rv);
11999
12000 rv = callback.WaitForResult();
12001 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12002
12003 EXPECT_EQ(NULL, trans->GetResponseInfo());
12004
12005 // We don't care whether this succeeds or fails, but it shouldn't crash.
12006 HttpRequestHeaders request_headers;
12007 trans->GetFullRequestHeaders(&request_headers);
12008}
12009
12010TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12011 HttpRequestInfo request;
12012 request.method = "GET";
12013 request.url = GURL("http://www.google.com/");
12014 request.load_flags = 0;
12015
[email protected]3fe8d2f82013-10-17 08:56:0712016 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412017 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712018 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412019
12020 MockWrite data_writes[] = {
12021 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12022 };
12023 MockRead data_reads[] = {
12024 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12025 };
12026
12027 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12028 data_writes, arraysize(data_writes));
12029 session_deps_.socket_factory->AddSocketDataProvider(&data);
12030
12031 TestCompletionCallback callback;
12032
12033 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12034 EXPECT_EQ(ERR_IO_PENDING, rv);
12035
12036 rv = callback.WaitForResult();
12037 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12038
12039 EXPECT_EQ(NULL, trans->GetResponseInfo());
12040
12041 HttpRequestHeaders request_headers;
12042 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12043 EXPECT_TRUE(request_headers.HasHeader("Host"));
12044}
12045
12046TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12047 HttpRequestInfo request;
12048 request.method = "GET";
12049 request.url = GURL("http://www.google.com/");
12050 request.load_flags = 0;
12051
[email protected]3fe8d2f82013-10-17 08:56:0712052 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412053 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412055
12056 MockWrite data_writes[] = {
12057 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12058 };
12059 MockRead data_reads[] = {
12060 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12061 };
12062
12063 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12064 data_writes, arraysize(data_writes));
12065 session_deps_.socket_factory->AddSocketDataProvider(&data);
12066
12067 TestCompletionCallback callback;
12068
12069 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12070 EXPECT_EQ(ERR_IO_PENDING, rv);
12071
12072 rv = callback.WaitForResult();
12073 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12074
12075 EXPECT_EQ(NULL, trans->GetResponseInfo());
12076
12077 HttpRequestHeaders request_headers;
12078 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12079 EXPECT_TRUE(request_headers.HasHeader("Host"));
12080}
12081
12082TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12083 HttpRequestInfo request;
12084 request.method = "GET";
12085 request.url = GURL("http://www.google.com/");
12086 request.load_flags = 0;
12087
[email protected]3fe8d2f82013-10-17 08:56:0712088 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412089 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412091
12092 MockWrite data_writes[] = {
12093 MockWrite("GET / HTTP/1.1\r\n"
12094 "Host: www.google.com\r\n"
12095 "Connection: keep-alive\r\n\r\n"),
12096 };
12097 MockRead data_reads[] = {
12098 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12099 };
12100
12101 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12102 data_writes, arraysize(data_writes));
12103 session_deps_.socket_factory->AddSocketDataProvider(&data);
12104
12105 TestCompletionCallback callback;
12106
12107 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12108 EXPECT_EQ(ERR_IO_PENDING, rv);
12109
12110 rv = callback.WaitForResult();
12111 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12112
12113 EXPECT_EQ(NULL, trans->GetResponseInfo());
12114
12115 HttpRequestHeaders request_headers;
12116 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12117 EXPECT_TRUE(request_headers.HasHeader("Host"));
12118}
12119
12120TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12121 HttpRequestInfo request;
12122 request.method = "GET";
12123 request.url = GURL("http://www.google.com/");
12124 request.load_flags = 0;
12125
[email protected]3fe8d2f82013-10-17 08:56:0712126 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412127 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412129
12130 MockWrite data_writes[] = {
12131 MockWrite("GET / HTTP/1.1\r\n"
12132 "Host: www.google.com\r\n"
12133 "Connection: keep-alive\r\n\r\n"),
12134 };
12135 MockRead data_reads[] = {
12136 MockRead(ASYNC, ERR_CONNECTION_RESET),
12137 };
12138
12139 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12140 data_writes, arraysize(data_writes));
12141 session_deps_.socket_factory->AddSocketDataProvider(&data);
12142
12143 TestCompletionCallback callback;
12144
12145 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12146 EXPECT_EQ(ERR_IO_PENDING, rv);
12147
12148 rv = callback.WaitForResult();
12149 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12150
12151 EXPECT_EQ(NULL, trans->GetResponseInfo());
12152
12153 HttpRequestHeaders request_headers;
12154 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12155 EXPECT_TRUE(request_headers.HasHeader("Host"));
12156}
12157
12158TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12159 HttpRequestInfo request;
12160 request.method = "GET";
12161 request.url = GURL("http://www.google.com/");
12162 request.load_flags = 0;
12163 request.extra_headers.SetHeader("X-Foo", "bar");
12164
[email protected]3fe8d2f82013-10-17 08:56:0712165 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412166 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712167 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412168
12169 MockWrite data_writes[] = {
12170 MockWrite("GET / HTTP/1.1\r\n"
12171 "Host: www.google.com\r\n"
12172 "Connection: keep-alive\r\n"
12173 "X-Foo: bar\r\n\r\n"),
12174 };
12175 MockRead data_reads[] = {
12176 MockRead("HTTP/1.1 200 OK\r\n"
12177 "Content-Length: 5\r\n\r\n"
12178 "hello"),
12179 MockRead(ASYNC, ERR_UNEXPECTED),
12180 };
12181
12182 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12183 data_writes, arraysize(data_writes));
12184 session_deps_.socket_factory->AddSocketDataProvider(&data);
12185
12186 TestCompletionCallback callback;
12187
12188 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12189 EXPECT_EQ(ERR_IO_PENDING, rv);
12190
12191 rv = callback.WaitForResult();
12192 EXPECT_EQ(OK, rv);
12193
12194 HttpRequestHeaders request_headers;
12195 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12196 std::string foo;
12197 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12198 EXPECT_EQ("bar", foo);
12199}
12200
[email protected]bf828982013-08-14 18:01:4712201namespace {
12202
[email protected]e86839fd2013-08-14 18:29:0312203// Fake HttpStreamBase that simply records calls to SetPriority().
12204class FakeStream : public HttpStreamBase,
12205 public base::SupportsWeakPtr<FakeStream> {
12206 public:
12207 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
12208 virtual ~FakeStream() {}
12209
12210 RequestPriority priority() const { return priority_; }
12211
12212 virtual int InitializeStream(const HttpRequestInfo* request_info,
12213 RequestPriority priority,
12214 const BoundNetLog& net_log,
12215 const CompletionCallback& callback) OVERRIDE {
12216 return ERR_IO_PENDING;
12217 }
12218
12219 virtual int SendRequest(const HttpRequestHeaders& request_headers,
12220 HttpResponseInfo* response,
12221 const CompletionCallback& callback) OVERRIDE {
12222 ADD_FAILURE();
12223 return ERR_UNEXPECTED;
12224 }
12225
12226 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
12227 ADD_FAILURE();
12228 return ERR_UNEXPECTED;
12229 }
12230
[email protected]e86839fd2013-08-14 18:29:0312231 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
12232 const CompletionCallback& callback) OVERRIDE {
12233 ADD_FAILURE();
12234 return ERR_UNEXPECTED;
12235 }
12236
12237 virtual void Close(bool not_reusable) OVERRIDE {}
12238
12239 virtual bool IsResponseBodyComplete() const OVERRIDE {
12240 ADD_FAILURE();
12241 return false;
12242 }
12243
12244 virtual bool CanFindEndOfResponse() const OVERRIDE {
12245 return false;
12246 }
12247
12248 virtual bool IsConnectionReused() const OVERRIDE {
12249 ADD_FAILURE();
12250 return false;
12251 }
12252
12253 virtual void SetConnectionReused() OVERRIDE {
12254 ADD_FAILURE();
12255 }
12256
12257 virtual bool IsConnectionReusable() const OVERRIDE {
12258 ADD_FAILURE();
12259 return false;
12260 }
12261
[email protected]bc92bc972013-12-13 08:32:5912262 virtual int64 GetTotalReceivedBytes() const OVERRIDE {
12263 ADD_FAILURE();
12264 return 0;
12265 }
12266
[email protected]e86839fd2013-08-14 18:29:0312267 virtual bool GetLoadTimingInfo(
12268 LoadTimingInfo* load_timing_info) const OVERRIDE {
12269 ADD_FAILURE();
12270 return false;
12271 }
12272
12273 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
12274 ADD_FAILURE();
12275 }
12276
12277 virtual void GetSSLCertRequestInfo(
12278 SSLCertRequestInfo* cert_request_info) OVERRIDE {
12279 ADD_FAILURE();
12280 }
12281
12282 virtual bool IsSpdyHttpStream() const OVERRIDE {
12283 ADD_FAILURE();
12284 return false;
12285 }
12286
12287 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
12288 ADD_FAILURE();
12289 }
12290
12291 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12292 priority_ = priority;
12293 }
12294
12295 private:
12296 RequestPriority priority_;
12297
12298 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12299};
12300
12301// Fake HttpStreamRequest that simply records calls to SetPriority()
12302// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712303class FakeStreamRequest : public HttpStreamRequest,
12304 public base::SupportsWeakPtr<FakeStreamRequest> {
12305 public:
[email protected]e86839fd2013-08-14 18:29:0312306 FakeStreamRequest(RequestPriority priority,
12307 HttpStreamRequest::Delegate* delegate)
12308 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412309 delegate_(delegate),
12310 websocket_stream_create_helper_(NULL) {}
12311
12312 FakeStreamRequest(RequestPriority priority,
12313 HttpStreamRequest::Delegate* delegate,
12314 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12315 : priority_(priority),
12316 delegate_(delegate),
12317 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312318
[email protected]bf828982013-08-14 18:01:4712319 virtual ~FakeStreamRequest() {}
12320
12321 RequestPriority priority() const { return priority_; }
12322
[email protected]831e4a32013-11-14 02:14:4412323 const WebSocketHandshakeStreamBase::CreateHelper*
12324 websocket_stream_create_helper() const {
12325 return websocket_stream_create_helper_;
12326 }
12327
[email protected]e86839fd2013-08-14 18:29:0312328 // Create a new FakeStream and pass it to the request's
12329 // delegate. Returns a weak pointer to the FakeStream.
12330 base::WeakPtr<FakeStream> FinishStreamRequest() {
12331 FakeStream* fake_stream = new FakeStream(priority_);
12332 // Do this before calling OnStreamReady() as OnStreamReady() may
12333 // immediately delete |fake_stream|.
12334 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12335 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12336 return weak_stream;
12337 }
12338
[email protected]bf828982013-08-14 18:01:4712339 virtual int RestartTunnelWithProxyAuth(
12340 const AuthCredentials& credentials) OVERRIDE {
12341 ADD_FAILURE();
12342 return ERR_UNEXPECTED;
12343 }
12344
12345 virtual LoadState GetLoadState() const OVERRIDE {
12346 ADD_FAILURE();
12347 return LoadState();
12348 }
12349
12350 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12351 priority_ = priority;
12352 }
12353
12354 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712355 return false;
12356 }
12357
12358 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712359 return kProtoUnknown;
12360 }
12361
12362 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712363 return false;
12364 }
12365
12366 private:
12367 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312368 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412369 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712370
12371 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12372};
12373
12374// Fake HttpStreamFactory that vends FakeStreamRequests.
12375class FakeStreamFactory : public HttpStreamFactory {
12376 public:
12377 FakeStreamFactory() {}
12378 virtual ~FakeStreamFactory() {}
12379
12380 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12381 // RequestStream() (which may be NULL if it was destroyed already).
12382 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12383 return last_stream_request_;
12384 }
12385
12386 virtual HttpStreamRequest* RequestStream(
12387 const HttpRequestInfo& info,
12388 RequestPriority priority,
12389 const SSLConfig& server_ssl_config,
12390 const SSLConfig& proxy_ssl_config,
12391 HttpStreamRequest::Delegate* delegate,
12392 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0312393 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712394 last_stream_request_ = fake_request->AsWeakPtr();
12395 return fake_request;
12396 }
12397
[email protected]a9cf2b92013-10-30 12:08:4912398 virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712399 const HttpRequestInfo& info,
12400 RequestPriority priority,
12401 const SSLConfig& server_ssl_config,
12402 const SSLConfig& proxy_ssl_config,
12403 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612404 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
[email protected]bf828982013-08-14 18:01:4712405 const BoundNetLog& net_log) OVERRIDE {
[email protected]831e4a32013-11-14 02:14:4412406 FakeStreamRequest* fake_request =
12407 new FakeStreamRequest(priority, delegate, create_helper);
12408 last_stream_request_ = fake_request->AsWeakPtr();
12409 return fake_request;
[email protected]bf828982013-08-14 18:01:4712410 }
12411
12412 virtual void PreconnectStreams(int num_streams,
12413 const HttpRequestInfo& info,
12414 RequestPriority priority,
12415 const SSLConfig& server_ssl_config,
12416 const SSLConfig& proxy_ssl_config) OVERRIDE {
12417 ADD_FAILURE();
12418 }
12419
[email protected]bf828982013-08-14 18:01:4712420 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
12421 ADD_FAILURE();
12422 return NULL;
12423 }
12424
12425 private:
12426 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12427
12428 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12429};
12430
[email protected]831e4a32013-11-14 02:14:4412431// TODO(yhirano): Split this class out into a net/websockets file, if it is
12432// worth doing.
12433class FakeWebSocketStreamCreateHelper :
12434 public WebSocketHandshakeStreamBase::CreateHelper {
12435 public:
12436 virtual WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112437 scoped_ptr<ClientSocketHandle> connection,
[email protected]831e4a32013-11-14 02:14:4412438 bool using_proxy) OVERRIDE {
12439 NOTREACHED();
12440 return NULL;
12441 }
12442
12443 virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12444 const base::WeakPtr<SpdySession>& session,
12445 bool use_relative_url) OVERRIDE {
12446 NOTREACHED();
12447 return NULL;
12448 };
12449
12450 virtual ~FakeWebSocketStreamCreateHelper() {}
12451
12452 virtual scoped_ptr<WebSocketStream> Upgrade() {
12453 NOTREACHED();
12454 return scoped_ptr<WebSocketStream>();
12455 }
12456};
12457
[email protected]bf828982013-08-14 18:01:4712458} // namespace
12459
12460// Make sure that HttpNetworkTransaction passes on its priority to its
12461// stream request on start.
12462TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12463 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12464 HttpNetworkSessionPeer peer(session);
12465 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412466 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712467
12468 HttpNetworkTransaction trans(LOW, session);
12469
12470 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12471
12472 HttpRequestInfo request;
12473 TestCompletionCallback callback;
12474 EXPECT_EQ(ERR_IO_PENDING,
12475 trans.Start(&request, callback.callback(), BoundNetLog()));
12476
12477 base::WeakPtr<FakeStreamRequest> fake_request =
12478 fake_factory->last_stream_request();
12479 ASSERT_TRUE(fake_request != NULL);
12480 EXPECT_EQ(LOW, fake_request->priority());
12481}
12482
12483// Make sure that HttpNetworkTransaction passes on its priority
12484// updates to its stream request.
12485TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12486 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12487 HttpNetworkSessionPeer peer(session);
12488 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412489 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712490
12491 HttpNetworkTransaction trans(LOW, session);
12492
12493 HttpRequestInfo request;
12494 TestCompletionCallback callback;
12495 EXPECT_EQ(ERR_IO_PENDING,
12496 trans.Start(&request, callback.callback(), BoundNetLog()));
12497
12498 base::WeakPtr<FakeStreamRequest> fake_request =
12499 fake_factory->last_stream_request();
12500 ASSERT_TRUE(fake_request != NULL);
12501 EXPECT_EQ(LOW, fake_request->priority());
12502
12503 trans.SetPriority(LOWEST);
12504 ASSERT_TRUE(fake_request != NULL);
12505 EXPECT_EQ(LOWEST, fake_request->priority());
12506}
12507
[email protected]e86839fd2013-08-14 18:29:0312508// Make sure that HttpNetworkTransaction passes on its priority
12509// updates to its stream.
12510TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12511 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12512 HttpNetworkSessionPeer peer(session);
12513 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412514 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312515
12516 HttpNetworkTransaction trans(LOW, session);
12517
12518 HttpRequestInfo request;
12519 TestCompletionCallback callback;
12520 EXPECT_EQ(ERR_IO_PENDING,
12521 trans.Start(&request, callback.callback(), BoundNetLog()));
12522
12523 base::WeakPtr<FakeStreamRequest> fake_request =
12524 fake_factory->last_stream_request();
12525 ASSERT_TRUE(fake_request != NULL);
12526 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12527 ASSERT_TRUE(fake_stream != NULL);
12528 EXPECT_EQ(LOW, fake_stream->priority());
12529
12530 trans.SetPriority(LOWEST);
12531 EXPECT_EQ(LOWEST, fake_stream->priority());
12532}
12533
[email protected]831e4a32013-11-14 02:14:4412534TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12535 // The same logic needs to be tested for both ws: and wss: schemes, but this
12536 // test is already parameterised on NextProto, so it uses a loop to verify
12537 // that the different schemes work.
12538 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12539 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12540 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12541 HttpNetworkSessionPeer peer(session);
12542 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12543 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312544 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412545 scoped_ptr<HttpStreamFactory>(fake_factory));
12546
12547 HttpNetworkTransaction trans(LOW, session);
12548 trans.SetWebSocketHandshakeStreamCreateHelper(
12549 &websocket_stream_create_helper);
12550
12551 HttpRequestInfo request;
12552 TestCompletionCallback callback;
12553 request.method = "GET";
12554 request.url = GURL(test_cases[i]);
12555
12556 EXPECT_EQ(ERR_IO_PENDING,
12557 trans.Start(&request, callback.callback(), BoundNetLog()));
12558
12559 base::WeakPtr<FakeStreamRequest> fake_request =
12560 fake_factory->last_stream_request();
12561 ASSERT_TRUE(fake_request != NULL);
12562 EXPECT_EQ(&websocket_stream_create_helper,
12563 fake_request->websocket_stream_create_helper());
12564 }
12565}
12566
[email protected]043b68c82013-08-22 23:41:5212567// Tests that when a used socket is returned to the SSL socket pool, it's closed
12568// if the transport socket pool is stalled on the global socket limit.
12569TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12570 ClientSocketPoolManager::set_max_sockets_per_group(
12571 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12572 ClientSocketPoolManager::set_max_sockets_per_pool(
12573 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12574
12575 // Set up SSL request.
12576
12577 HttpRequestInfo ssl_request;
12578 ssl_request.method = "GET";
12579 ssl_request.url = GURL("https://www.google.com/");
12580
12581 MockWrite ssl_writes[] = {
12582 MockWrite("GET / HTTP/1.1\r\n"
12583 "Host: www.google.com\r\n"
12584 "Connection: keep-alive\r\n\r\n"),
12585 };
12586 MockRead ssl_reads[] = {
12587 MockRead("HTTP/1.1 200 OK\r\n"),
12588 MockRead("Content-Length: 11\r\n\r\n"),
12589 MockRead("hello world"),
12590 MockRead(SYNCHRONOUS, OK),
12591 };
12592 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12593 ssl_writes, arraysize(ssl_writes));
12594 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12595
12596 SSLSocketDataProvider ssl(ASYNC, OK);
12597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12598
12599 // Set up HTTP request.
12600
12601 HttpRequestInfo http_request;
12602 http_request.method = "GET";
12603 http_request.url = GURL("http://www.google.com/");
12604
12605 MockWrite http_writes[] = {
12606 MockWrite("GET / HTTP/1.1\r\n"
12607 "Host: www.google.com\r\n"
12608 "Connection: keep-alive\r\n\r\n"),
12609 };
12610 MockRead http_reads[] = {
12611 MockRead("HTTP/1.1 200 OK\r\n"),
12612 MockRead("Content-Length: 7\r\n\r\n"),
12613 MockRead("falafel"),
12614 MockRead(SYNCHRONOUS, OK),
12615 };
12616 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12617 http_writes, arraysize(http_writes));
12618 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12619
12620 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12621
12622 // Start the SSL request.
12623 TestCompletionCallback ssl_callback;
12624 scoped_ptr<HttpTransaction> ssl_trans(
12625 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12626 ASSERT_EQ(ERR_IO_PENDING,
12627 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12628 BoundNetLog()));
12629
12630 // Start the HTTP request. Pool should stall.
12631 TestCompletionCallback http_callback;
12632 scoped_ptr<HttpTransaction> http_trans(
12633 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12634 ASSERT_EQ(ERR_IO_PENDING,
12635 http_trans->Start(&http_request, http_callback.callback(),
12636 BoundNetLog()));
12637 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12638
12639 // Wait for response from SSL request.
12640 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12641 std::string response_data;
12642 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12643 EXPECT_EQ("hello world", response_data);
12644
12645 // The SSL socket should automatically be closed, so the HTTP request can
12646 // start.
12647 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12648 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12649
12650 // The HTTP request can now complete.
12651 ASSERT_EQ(OK, http_callback.WaitForResult());
12652 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12653 EXPECT_EQ("falafel", response_data);
12654
12655 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12656}
12657
12658// Tests that when a SSL connection is established but there's no corresponding
12659// request that needs it, the new socket is closed if the transport socket pool
12660// is stalled on the global socket limit.
12661TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12662 ClientSocketPoolManager::set_max_sockets_per_group(
12663 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12664 ClientSocketPoolManager::set_max_sockets_per_pool(
12665 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12666
12667 // Set up an ssl request.
12668
12669 HttpRequestInfo ssl_request;
12670 ssl_request.method = "GET";
12671 ssl_request.url = GURL("https://www.foopy.com/");
12672
12673 // No data will be sent on the SSL socket.
12674 StaticSocketDataProvider ssl_data;
12675 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12676
12677 SSLSocketDataProvider ssl(ASYNC, OK);
12678 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12679
12680 // Set up HTTP request.
12681
12682 HttpRequestInfo http_request;
12683 http_request.method = "GET";
12684 http_request.url = GURL("http://www.google.com/");
12685
12686 MockWrite http_writes[] = {
12687 MockWrite("GET / HTTP/1.1\r\n"
12688 "Host: www.google.com\r\n"
12689 "Connection: keep-alive\r\n\r\n"),
12690 };
12691 MockRead http_reads[] = {
12692 MockRead("HTTP/1.1 200 OK\r\n"),
12693 MockRead("Content-Length: 7\r\n\r\n"),
12694 MockRead("falafel"),
12695 MockRead(SYNCHRONOUS, OK),
12696 };
12697 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12698 http_writes, arraysize(http_writes));
12699 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12700
12701 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12702
12703 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12704 // cancelled when a normal transaction is cancelled.
12705 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12706 net::SSLConfig ssl_config;
12707 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12708 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12709 ssl_config, ssl_config);
12710 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12711
12712 // Start the HTTP request. Pool should stall.
12713 TestCompletionCallback http_callback;
12714 scoped_ptr<HttpTransaction> http_trans(
12715 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12716 ASSERT_EQ(ERR_IO_PENDING,
12717 http_trans->Start(&http_request, http_callback.callback(),
12718 BoundNetLog()));
12719 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12720
12721 // The SSL connection will automatically be closed once the connection is
12722 // established, to let the HTTP request start.
12723 ASSERT_EQ(OK, http_callback.WaitForResult());
12724 std::string response_data;
12725 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12726 EXPECT_EQ("falafel", response_data);
12727
12728 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12729}
12730
[email protected]02d74a02014-04-23 18:10:5412731TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
12732 ScopedVector<UploadElementReader> element_readers;
12733 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12734 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12735
12736 HttpRequestInfo request;
12737 request.method = "POST";
12738 request.url = GURL("http://www.foo.com/");
12739 request.upload_data_stream = &upload_data_stream;
12740 request.load_flags = 0;
12741
12742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12743 scoped_ptr<HttpTransaction> trans(
12744 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12745 // Send headers successfully, but get an error while sending the body.
12746 MockWrite data_writes[] = {
12747 MockWrite("POST / HTTP/1.1\r\n"
12748 "Host: www.foo.com\r\n"
12749 "Connection: keep-alive\r\n"
12750 "Content-Length: 3\r\n\r\n"),
12751 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12752 };
12753
12754 MockRead data_reads[] = {
12755 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12756 MockRead("hello world"),
12757 MockRead(SYNCHRONOUS, OK),
12758 };
12759 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12760 arraysize(data_writes));
12761 session_deps_.socket_factory->AddSocketDataProvider(&data);
12762
12763 TestCompletionCallback callback;
12764
12765 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12766 EXPECT_EQ(ERR_IO_PENDING, rv);
12767
12768 rv = callback.WaitForResult();
12769 EXPECT_EQ(OK, rv);
12770
12771 const HttpResponseInfo* response = trans->GetResponseInfo();
12772 ASSERT_TRUE(response != NULL);
12773
12774 EXPECT_TRUE(response->headers.get() != NULL);
12775 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12776
12777 std::string response_data;
12778 rv = ReadTransaction(trans.get(), &response_data);
12779 EXPECT_EQ(OK, rv);
12780 EXPECT_EQ("hello world", response_data);
12781}
12782
12783// This test makes sure the retry logic doesn't trigger when reading an error
12784// response from a server that rejected a POST with a CONNECTION_RESET.
12785TEST_P(HttpNetworkTransactionTest,
12786 PostReadsErrorResponseAfterResetOnReusedSocket) {
12787 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12788 MockWrite data_writes[] = {
12789 MockWrite("GET / HTTP/1.1\r\n"
12790 "Host: www.foo.com\r\n"
12791 "Connection: keep-alive\r\n\r\n"),
12792 MockWrite("POST / HTTP/1.1\r\n"
12793 "Host: www.foo.com\r\n"
12794 "Connection: keep-alive\r\n"
12795 "Content-Length: 3\r\n\r\n"),
12796 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12797 };
12798
12799 MockRead data_reads[] = {
12800 MockRead("HTTP/1.1 200 Peachy\r\n"
12801 "Content-Length: 14\r\n\r\n"),
12802 MockRead("first response"),
12803 MockRead("HTTP/1.1 400 Not OK\r\n"
12804 "Content-Length: 15\r\n\r\n"),
12805 MockRead("second response"),
12806 MockRead(SYNCHRONOUS, OK),
12807 };
12808 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12809 arraysize(data_writes));
12810 session_deps_.socket_factory->AddSocketDataProvider(&data);
12811
12812 TestCompletionCallback callback;
12813 HttpRequestInfo request1;
12814 request1.method = "GET";
12815 request1.url = GURL("http://www.foo.com/");
12816 request1.load_flags = 0;
12817
12818 scoped_ptr<HttpTransaction> trans1(
12819 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12820 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
12821 EXPECT_EQ(ERR_IO_PENDING, rv);
12822
12823 rv = callback.WaitForResult();
12824 EXPECT_EQ(OK, rv);
12825
12826 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12827 ASSERT_TRUE(response1 != NULL);
12828
12829 EXPECT_TRUE(response1->headers.get() != NULL);
12830 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
12831
12832 std::string response_data1;
12833 rv = ReadTransaction(trans1.get(), &response_data1);
12834 EXPECT_EQ(OK, rv);
12835 EXPECT_EQ("first response", response_data1);
12836 // Delete the transaction to release the socket back into the socket pool.
12837 trans1.reset();
12838
12839 ScopedVector<UploadElementReader> element_readers;
12840 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12841 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12842
12843 HttpRequestInfo request2;
12844 request2.method = "POST";
12845 request2.url = GURL("http://www.foo.com/");
12846 request2.upload_data_stream = &upload_data_stream;
12847 request2.load_flags = 0;
12848
12849 scoped_ptr<HttpTransaction> trans2(
12850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12851 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
12852 EXPECT_EQ(ERR_IO_PENDING, rv);
12853
12854 rv = callback.WaitForResult();
12855 EXPECT_EQ(OK, rv);
12856
12857 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
12858 ASSERT_TRUE(response2 != NULL);
12859
12860 EXPECT_TRUE(response2->headers.get() != NULL);
12861 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
12862
12863 std::string response_data2;
12864 rv = ReadTransaction(trans2.get(), &response_data2);
12865 EXPECT_EQ(OK, rv);
12866 EXPECT_EQ("second response", response_data2);
12867}
12868
12869TEST_P(HttpNetworkTransactionTest,
12870 PostReadsErrorResponseAfterResetPartialBodySent) {
12871 ScopedVector<UploadElementReader> element_readers;
12872 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12873 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12874
12875 HttpRequestInfo request;
12876 request.method = "POST";
12877 request.url = GURL("http://www.foo.com/");
12878 request.upload_data_stream = &upload_data_stream;
12879 request.load_flags = 0;
12880
12881 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12882 scoped_ptr<HttpTransaction> trans(
12883 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12884 // Send headers successfully, but get an error while sending the body.
12885 MockWrite data_writes[] = {
12886 MockWrite("POST / HTTP/1.1\r\n"
12887 "Host: www.foo.com\r\n"
12888 "Connection: keep-alive\r\n"
12889 "Content-Length: 3\r\n\r\n"
12890 "fo"),
12891 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12892 };
12893
12894 MockRead data_reads[] = {
12895 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12896 MockRead("hello world"),
12897 MockRead(SYNCHRONOUS, OK),
12898 };
12899 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12900 arraysize(data_writes));
12901 session_deps_.socket_factory->AddSocketDataProvider(&data);
12902
12903 TestCompletionCallback callback;
12904
12905 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12906 EXPECT_EQ(ERR_IO_PENDING, rv);
12907
12908 rv = callback.WaitForResult();
12909 EXPECT_EQ(OK, rv);
12910
12911 const HttpResponseInfo* response = trans->GetResponseInfo();
12912 ASSERT_TRUE(response != NULL);
12913
12914 EXPECT_TRUE(response->headers.get() != NULL);
12915 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12916
12917 std::string response_data;
12918 rv = ReadTransaction(trans.get(), &response_data);
12919 EXPECT_EQ(OK, rv);
12920 EXPECT_EQ("hello world", response_data);
12921}
12922
12923// This tests the more common case than the previous test, where headers and
12924// body are not merged into a single request.
12925TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
12926 ScopedVector<UploadElementReader> element_readers;
12927 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12928 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
12929
12930 HttpRequestInfo request;
12931 request.method = "POST";
12932 request.url = GURL("http://www.foo.com/");
12933 request.upload_data_stream = &upload_data_stream;
12934 request.load_flags = 0;
12935
12936 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12937 scoped_ptr<HttpTransaction> trans(
12938 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12939 // Send headers successfully, but get an error while sending the body.
12940 MockWrite data_writes[] = {
12941 MockWrite("POST / HTTP/1.1\r\n"
12942 "Host: www.foo.com\r\n"
12943 "Connection: keep-alive\r\n"
12944 "Transfer-Encoding: chunked\r\n\r\n"),
12945 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12946 };
12947
12948 MockRead data_reads[] = {
12949 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12950 MockRead("hello world"),
12951 MockRead(SYNCHRONOUS, OK),
12952 };
12953 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12954 arraysize(data_writes));
12955 session_deps_.socket_factory->AddSocketDataProvider(&data);
12956
12957 TestCompletionCallback callback;
12958
12959 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12960 EXPECT_EQ(ERR_IO_PENDING, rv);
12961 // Make sure the headers are sent before adding a chunk. This ensures that
12962 // they can't be merged with the body in a single send. Not currently
12963 // necessary since a chunked body is never merged with headers, but this makes
12964 // the test more future proof.
12965 base::RunLoop().RunUntilIdle();
12966
12967 upload_data_stream.AppendChunk("last chunk", 10, true);
12968
12969 rv = callback.WaitForResult();
12970 EXPECT_EQ(OK, rv);
12971
12972 const HttpResponseInfo* response = trans->GetResponseInfo();
12973 ASSERT_TRUE(response != NULL);
12974
12975 EXPECT_TRUE(response->headers.get() != NULL);
12976 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12977
12978 std::string response_data;
12979 rv = ReadTransaction(trans.get(), &response_data);
12980 EXPECT_EQ(OK, rv);
12981 EXPECT_EQ("hello world", response_data);
12982}
12983
12984TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
12985 ScopedVector<UploadElementReader> element_readers;
12986 element_readers.push_back(new UploadBytesElementReader("foo", 3));
12987 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12988
12989 HttpRequestInfo request;
12990 request.method = "POST";
12991 request.url = GURL("http://www.foo.com/");
12992 request.upload_data_stream = &upload_data_stream;
12993 request.load_flags = 0;
12994
12995 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12996 scoped_ptr<HttpTransaction> trans(
12997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12998
12999 MockWrite data_writes[] = {
13000 MockWrite("POST / HTTP/1.1\r\n"
13001 "Host: www.foo.com\r\n"
13002 "Connection: keep-alive\r\n"
13003 "Content-Length: 3\r\n\r\n"),
13004 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13005 };
13006
13007 MockRead data_reads[] = {
13008 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13009 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13010 MockRead("hello world"),
13011 MockRead(SYNCHRONOUS, OK),
13012 };
13013 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13014 arraysize(data_writes));
13015 session_deps_.socket_factory->AddSocketDataProvider(&data);
13016
13017 TestCompletionCallback callback;
13018
13019 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13020 EXPECT_EQ(ERR_IO_PENDING, rv);
13021
13022 rv = callback.WaitForResult();
13023 EXPECT_EQ(OK, rv);
13024
13025 const HttpResponseInfo* response = trans->GetResponseInfo();
13026 ASSERT_TRUE(response != NULL);
13027
13028 EXPECT_TRUE(response->headers.get() != NULL);
13029 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13030
13031 std::string response_data;
13032 rv = ReadTransaction(trans.get(), &response_data);
13033 EXPECT_EQ(OK, rv);
13034 EXPECT_EQ("hello world", response_data);
13035}
13036
13037TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13038 ScopedVector<UploadElementReader> element_readers;
13039 element_readers.push_back(new UploadBytesElementReader("foo", 3));
13040 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13041
13042 HttpRequestInfo request;
13043 request.method = "POST";
13044 request.url = GURL("http://www.foo.com/");
13045 request.upload_data_stream = &upload_data_stream;
13046 request.load_flags = 0;
13047
13048 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13049 scoped_ptr<HttpTransaction> trans(
13050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13051 // Send headers successfully, but get an error while sending the body.
13052 MockWrite data_writes[] = {
13053 MockWrite("POST / HTTP/1.1\r\n"
13054 "Host: www.foo.com\r\n"
13055 "Connection: keep-alive\r\n"
13056 "Content-Length: 3\r\n\r\n"),
13057 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13058 };
13059
13060 MockRead data_reads[] = {
13061 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13062 MockRead("hello world"),
13063 MockRead(SYNCHRONOUS, OK),
13064 };
13065 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13066 arraysize(data_writes));
13067 session_deps_.socket_factory->AddSocketDataProvider(&data);
13068
13069 TestCompletionCallback callback;
13070
13071 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13072 EXPECT_EQ(ERR_IO_PENDING, rv);
13073
13074 rv = callback.WaitForResult();
13075 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13076
13077 const HttpResponseInfo* response = trans->GetResponseInfo();
13078 EXPECT_TRUE(response == NULL);
13079}
13080
13081TEST_P(HttpNetworkTransactionTest,
13082 PostIgnoresNonErrorResponseAfterResetAnd100) {
13083 ScopedVector<UploadElementReader> element_readers;
13084 element_readers.push_back(new UploadBytesElementReader("foo", 3));
13085 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13086
13087 HttpRequestInfo request;
13088 request.method = "POST";
13089 request.url = GURL("http://www.foo.com/");
13090 request.upload_data_stream = &upload_data_stream;
13091 request.load_flags = 0;
13092
13093 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13094 scoped_ptr<HttpTransaction> trans(
13095 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13096 // Send headers successfully, but get an error while sending the body.
13097 MockWrite data_writes[] = {
13098 MockWrite("POST / HTTP/1.1\r\n"
13099 "Host: www.foo.com\r\n"
13100 "Connection: keep-alive\r\n"
13101 "Content-Length: 3\r\n\r\n"),
13102 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13103 };
13104
13105 MockRead data_reads[] = {
13106 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13107 MockRead("HTTP/1.0 302 Redirect\r\n"),
13108 MockRead("Location: http://somewhere-else.com/\r\n"),
13109 MockRead("Content-Length: 0\r\n\r\n"),
13110 MockRead(SYNCHRONOUS, OK),
13111 };
13112 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13113 arraysize(data_writes));
13114 session_deps_.socket_factory->AddSocketDataProvider(&data);
13115
13116 TestCompletionCallback callback;
13117
13118 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13119 EXPECT_EQ(ERR_IO_PENDING, rv);
13120
13121 rv = callback.WaitForResult();
13122 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13123
13124 const HttpResponseInfo* response = trans->GetResponseInfo();
13125 EXPECT_TRUE(response == NULL);
13126}
13127
13128TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13129 ScopedVector<UploadElementReader> element_readers;
13130 element_readers.push_back(new UploadBytesElementReader("foo", 3));
13131 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13132
13133 HttpRequestInfo request;
13134 request.method = "POST";
13135 request.url = GURL("http://www.foo.com/");
13136 request.upload_data_stream = &upload_data_stream;
13137 request.load_flags = 0;
13138
13139 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13140 scoped_ptr<HttpTransaction> trans(
13141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13142 // Send headers successfully, but get an error while sending the body.
13143 MockWrite data_writes[] = {
13144 MockWrite("POST / HTTP/1.1\r\n"
13145 "Host: www.foo.com\r\n"
13146 "Connection: keep-alive\r\n"
13147 "Content-Length: 3\r\n\r\n"),
13148 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13149 };
13150
13151 MockRead data_reads[] = {
13152 MockRead("HTTP 0.9 rocks!"),
13153 MockRead(SYNCHRONOUS, OK),
13154 };
13155 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13156 arraysize(data_writes));
13157 session_deps_.socket_factory->AddSocketDataProvider(&data);
13158
13159 TestCompletionCallback callback;
13160
13161 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13162 EXPECT_EQ(ERR_IO_PENDING, rv);
13163
13164 rv = callback.WaitForResult();
13165 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13166
13167 const HttpResponseInfo* response = trans->GetResponseInfo();
13168 EXPECT_TRUE(response == NULL);
13169}
13170
13171TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13172 ScopedVector<UploadElementReader> element_readers;
13173 element_readers.push_back(new UploadBytesElementReader("foo", 3));
13174 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13175
13176 HttpRequestInfo request;
13177 request.method = "POST";
13178 request.url = GURL("http://www.foo.com/");
13179 request.upload_data_stream = &upload_data_stream;
13180 request.load_flags = 0;
13181
13182 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13183 scoped_ptr<HttpTransaction> trans(
13184 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13185 // Send headers successfully, but get an error while sending the body.
13186 MockWrite data_writes[] = {
13187 MockWrite("POST / HTTP/1.1\r\n"
13188 "Host: www.foo.com\r\n"
13189 "Connection: keep-alive\r\n"
13190 "Content-Length: 3\r\n\r\n"),
13191 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13192 };
13193
13194 MockRead data_reads[] = {
13195 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13196 MockRead(SYNCHRONOUS, OK),
13197 };
13198 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13199 arraysize(data_writes));
13200 session_deps_.socket_factory->AddSocketDataProvider(&data);
13201
13202 TestCompletionCallback callback;
13203
13204 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13205 EXPECT_EQ(ERR_IO_PENDING, rv);
13206
13207 rv = callback.WaitForResult();
13208 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13209
13210 const HttpResponseInfo* response = trans->GetResponseInfo();
13211 EXPECT_TRUE(response == NULL);
13212}
13213
[email protected]89ceba9a2009-03-21 03:46:0613214} // namespace net